webdriver_logger.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const fs = require("fs");
  4. const path = require("path");
  5. const webdriver_commands_1 = require("./webdriver_commands");
  6. // Generate a random 8 character ID to avoid collisions.
  7. function getLogId() {
  8. return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36).slice(0, 8);
  9. }
  10. // Super proprietary left pad implementation. Do not copy plzkthx.
  11. function leftPad(field) {
  12. const fieldWidth = 6;
  13. let padding = fieldWidth - field.length;
  14. if (padding > 0) {
  15. return ' '.repeat(padding) + field;
  16. }
  17. return field;
  18. }
  19. const FINDERS = [
  20. webdriver_commands_1.CommandName.FindElement, webdriver_commands_1.CommandName.FindElementFromElement, webdriver_commands_1.CommandName.FindElements,
  21. webdriver_commands_1.CommandName.FindElementsFromElement
  22. ];
  23. const READERS = [
  24. webdriver_commands_1.CommandName.GetElementTagName, webdriver_commands_1.CommandName.GetElementText, webdriver_commands_1.CommandName.GetElementAttribute,
  25. webdriver_commands_1.CommandName.GetElementProperty, webdriver_commands_1.CommandName.GetElementCSSValue, webdriver_commands_1.CommandName.GetElementRect
  26. ];
  27. const PAD = ' ';
  28. /**
  29. * Logs WebDriver commands, transforming the command into a user-friendly description.
  30. */
  31. class WebDriverLogger {
  32. constructor() {
  33. this.logName = `webdriver_log_${getLogId()}.txt`;
  34. }
  35. /**
  36. * Start logging to the specified directory. Will create a file named
  37. * 'webdriver_log_<process id>.txt'
  38. *
  39. * @param logDir The directory to create log files in.
  40. */
  41. setLogDir(logDir) {
  42. this.logStream = fs.createWriteStream(path.join(logDir, this.logName), { flags: 'a' });
  43. }
  44. /**
  45. * Logs a webdriver command to the log file.
  46. *
  47. * @param command The command to log.
  48. */
  49. logWebDriverCommand(command) {
  50. if (!this.logStream) {
  51. return;
  52. }
  53. let logLine;
  54. logLine = `${this.timestamp()} `;
  55. let started = Date.now();
  56. command.on('response', () => {
  57. let done = Date.now();
  58. let elapsed = leftPad((done - started) + '');
  59. logLine += `| ${elapsed}ms `;
  60. if (command.getParam('sessionId')) {
  61. let session = command.getParam('sessionId').slice(0, 6);
  62. logLine += `| ${session} `;
  63. }
  64. else if (command.commandName == webdriver_commands_1.CommandName.NewSession) {
  65. // Only for new session commands, the sessionId is in the response.
  66. let session = command.responseData['sessionId'].slice(0, 6);
  67. logLine += `| ${session} `;
  68. }
  69. if (command.commandName == webdriver_commands_1.CommandName.UNKNOWN) {
  70. logLine += `| ${command.url}`;
  71. }
  72. else {
  73. logLine += `| ${webdriver_commands_1.CommandName[command.commandName]}`;
  74. }
  75. if (command.commandName == webdriver_commands_1.CommandName.Go) {
  76. logLine += ' ' + command.data['url'];
  77. }
  78. else if (command.getParam('elementId')) {
  79. logLine += ` (${command.getParam('elementId')})`;
  80. }
  81. logLine += '\n';
  82. this.logStream.write(logLine);
  83. this.renderData(command);
  84. this.renderResponse(command);
  85. });
  86. }
  87. /**
  88. * Log an arbitrary event to the log file.
  89. *
  90. * @param msg The message to log.
  91. * @param sessionId The session id associated with the event.
  92. * @param elapsedMs How long the event took, in ms.
  93. */
  94. logEvent(msg, sessionId, elapsedMs) {
  95. let elapsed = leftPad(elapsedMs.toString());
  96. let logLine = `${this.timestamp()} | ${elapsed}ms | ${sessionId.slice(0, 6)} | ${msg}\n`;
  97. this.logStream.write(logLine);
  98. }
  99. renderData(command) {
  100. let dataLine = '';
  101. if (command.commandName === webdriver_commands_1.CommandName.NewSession) {
  102. dataLine = JSON.stringify(command.data['desiredCapabilities']);
  103. }
  104. else if (command.commandName === webdriver_commands_1.CommandName.ElementSendKeys) {
  105. let value = command.data['value'].join('');
  106. dataLine = `Send: ${value}`;
  107. }
  108. else if (FINDERS.indexOf(command.commandName) !== -1) {
  109. const using = command.data['using'];
  110. const value = command.data['value'];
  111. dataLine = `Using ${using} '${value}'`;
  112. }
  113. if (dataLine) {
  114. this.logStream.write(PAD + dataLine + '\n');
  115. }
  116. }
  117. renderResponse(command) {
  118. let respLine = '';
  119. const data = command.responseData;
  120. if (data['status'] > 0) {
  121. respLine = `ERROR ${data['status']}: ${data['value']['message']}`;
  122. }
  123. else if (FINDERS.indexOf(command.commandName) !== -1) {
  124. let els = command.responseData['value'];
  125. if (!Array.isArray(els)) {
  126. els = [els];
  127. }
  128. els = els.map((e) => e['ELEMENT']);
  129. respLine = 'Elements: ' + els;
  130. }
  131. else if (READERS.indexOf(command.commandName) !== -1) {
  132. respLine = command.responseData['value'];
  133. if (typeof respLine == 'object') {
  134. respLine = JSON.stringify(respLine);
  135. }
  136. }
  137. if (respLine) {
  138. this.logStream.write(PAD + respLine + '\n');
  139. }
  140. }
  141. timestamp() {
  142. let d = new Date();
  143. let hours = d.getHours() < 10 ? '0' + d.getHours() : d.getHours();
  144. let minutes = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes();
  145. let seconds = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds();
  146. let millis = d.getMilliseconds().toString();
  147. millis = '000'.slice(0, 3 - millis.length) + millis;
  148. return `${hours}:${minutes}:${seconds}.${millis}`;
  149. }
  150. }
  151. exports.WebDriverLogger = WebDriverLogger;
  152. //# sourceMappingURL=webdriver_logger.js.map