debuggerCommons.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. var baseDebugger;
  2. try {
  3. baseDebugger = require('_debugger');
  4. } catch (e) {
  5. if (e.code == 'MODULE_NOT_FOUND') {
  6. console.log('***********************************************************');
  7. console.log('* WARNING: _debugger module not available on Node.js 8 *');
  8. console.log('* and higher. *');
  9. console.log('* *');
  10. console.log('* Use \'debugger\' keyword instead: *');
  11. console.log('* https://goo.gl/MvWqFh *');
  12. console.log('***********************************************************');
  13. }
  14. throw e;
  15. }
  16. var path = require('path');
  17. /**
  18. * Create a debugger client and attach to a running protractor process.
  19. * @param {number} pid Pid of the process to attach the debugger to.
  20. * @param {number=} opt_port Port to set up the debugger connection over.
  21. * @return {!baseDebugger.Client} The connected debugger client.
  22. */
  23. exports.attachDebugger = function(pid, opt_port) {
  24. var client = new baseDebugger.Client();
  25. var port = opt_port || process.debugPort;
  26. // Call this private function instead of sending SIGUSR1 because Windows.
  27. process._debugProcess(pid);
  28. // Connect to debugger on port with retry 200ms apart.
  29. var connectWithRetry = function(attempts) {
  30. client.connect(port, 'localhost')
  31. .on('error', function(e) {
  32. if (attempts === 1) {
  33. throw e;
  34. } else {
  35. setTimeout(function() {
  36. connectWithRetry(attempts - 1);
  37. }, 200);
  38. }
  39. });
  40. };
  41. connectWithRetry(10);
  42. return client;
  43. };
  44. /**
  45. * Set a breakpoint for evaluating REPL statements.
  46. * This sets a breakpoint in Protractor's breakpointhook.js, so that we'll
  47. * break after executing a command from the REPL.
  48. */
  49. exports.setEvaluateBreakpoint = function(client, cb) {
  50. client.setBreakpoint({
  51. type: 'scriptRegExp',
  52. target: prepareDebuggerPath('built', 'breakpointhook.js'),
  53. line: 2
  54. }, function(err, response) {
  55. if (err) {
  56. throw new Error(err);
  57. }
  58. cb(response.breakpoint);
  59. });
  60. };
  61. /**
  62. * Set a breakpoint for moving forward by one webdriver command.
  63. * This sets a breakpoint in selenium-webdriver/lib/http.js, and is
  64. * extremely sensitive to the selenium version. It works for
  65. * selenium-webdriver 3.0.1
  66. * This breaks on the following line in http.js:
  67. * let request = buildRequest(this.customCommands_, this.w3c, command);
  68. * And will need to break at a similar point in future selenium-webdriver
  69. * versions.
  70. */
  71. exports.setWebDriverCommandBreakpoint = function(client, cb) {
  72. client.setBreakpoint({
  73. type: 'scriptRegExp',
  74. target: prepareDebuggerPath('lib', 'http.js'),
  75. line: 433
  76. }, function(err, response) {
  77. if (err) {
  78. throw new Error(err);
  79. }
  80. cb(response.breakpoint);
  81. });
  82. };
  83. /**
  84. * Create a cross-platform friendly path for setting scriptRegExp breakpoints.
  85. */
  86. function prepareDebuggerPath(...parts) {
  87. return path.join(...parts)
  88. .replace('\\', '\\\\')
  89. .replace('.', '\\.');
  90. }
  91. /**
  92. * Trim excess symbols from the repl command so that it is consistent with
  93. * the user input.
  94. * @param {string} cmd Cmd provided by the repl server.
  95. * @return {string} The trimmed cmd.
  96. */
  97. exports.trimReplCmd = function(cmd) {
  98. // Given user input 'foobar', some versions of node provide '(foobar\n)',
  99. // while other versions of node provide 'foobar\n'.
  100. if (cmd.length >= 2 && cmd[0] === '(' && cmd[cmd.length - 1] === ')') {
  101. cmd = cmd.substring(1, cmd.length - 1);
  102. }
  103. return cmd.slice(0, cmd.length - 1);
  104. };