commandRepl.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. var REPL_INITIAL_SUGGESTIONS = [
  2. 'element(by.id(\'\'))',
  3. 'element(by.css(\'\'))',
  4. 'element(by.name(\'\'))',
  5. 'element(by.binding(\'\'))',
  6. 'element(by.xpath(\'\'))',
  7. 'element(by.tagName(\'\'))',
  8. 'element(by.className(\'\'))'
  9. ];
  10. /**
  11. * Repl to interactively run commands in the context of the test.
  12. *
  13. * @param {Client} node debugger client.
  14. * @constructor
  15. */
  16. var CommandRepl = function(client) {
  17. this.client = client;
  18. this.prompt = '> ';
  19. };
  20. /**
  21. * Eval function for processing a single step in repl.
  22. * Call callback with the result when complete.
  23. *
  24. * @public
  25. * @param {string} expression
  26. * @param {function} callback
  27. */
  28. CommandRepl.prototype.stepEval = function(expression, callback) {
  29. expression = expression.replace(/"/g, '\\\"');
  30. var expr = 'browser.debugHelper.dbgCodeExecutor.execute("' + expression + '")';
  31. this.evaluate_(expr, callback);
  32. };
  33. /**
  34. * Autocomplete user entries.
  35. * Call callback with the suggestions.
  36. *
  37. * @public
  38. * @param {string} line Initial user entry
  39. * @param {function} callback
  40. */
  41. CommandRepl.prototype.complete = function(line, callback) {
  42. if (line === '') {
  43. callback(null, [REPL_INITIAL_SUGGESTIONS, '']);
  44. } else {
  45. // TODO(juliemr): This is freezing the program!
  46. line = line.replace(/"/g, '\\\"');
  47. var expr = 'browser.debugHelper.dbgCodeExecutor.complete("' + line + '")';
  48. this.evaluate_(expr, function(err, res) {
  49. // Result is a JSON representation of the autocomplete response.
  50. var result = res === undefined ? undefined : JSON.parse(res);
  51. callback(err, result);
  52. });
  53. }
  54. };
  55. /**
  56. * Helper function to evaluate an expression remotely, and callback with
  57. * the result. The expression can be a promise, in which case, the method
  58. * will wait for the result and callback with the resolved value.
  59. *
  60. * @private
  61. * @param {string} expression Expression to evaluate
  62. * @param {function} callback
  63. */
  64. CommandRepl.prototype.evaluate_ = function(expression, callback) {
  65. var self = this;
  66. var onbreak_ = function() {
  67. self.client.req({
  68. command: 'evaluate',
  69. arguments: {
  70. frame: 0,
  71. maxStringLength: 1000,
  72. expression: 'browser.debugHelper.dbgCodeExecutor.resultReady()'
  73. }
  74. }, function(err, res) {
  75. if (err) {
  76. throw new Error('Error while checking if debugger expression result was ready.' +
  77. 'Expression: ' + expression + ' Error: ' + err);
  78. }
  79. // If code finished executing, get result.
  80. if (res.value) {
  81. self.client.req({
  82. command: 'evaluate',
  83. arguments: {
  84. frame: 0,
  85. maxStringLength: -1,
  86. expression: 'browser.debugHelper.dbgCodeExecutor.getResult()'
  87. }
  88. }, function(err, res) {
  89. try {
  90. callback(err, res.value);
  91. } catch (e) {
  92. callback(e, undefined);
  93. }
  94. self.client.removeListener('break', onbreak_);
  95. });
  96. } else {
  97. // If we need more loops for the code to finish executing, continue
  98. // until the next execute step.
  99. self.client.reqContinue(function() {
  100. // Intentionally blank.
  101. });
  102. }
  103. });
  104. };
  105. this.client.on('break', onbreak_);
  106. this.client.req({
  107. command: 'evaluate',
  108. arguments: {
  109. frame: 0,
  110. maxStringLength: 1000,
  111. expression: expression
  112. }
  113. }, function() {
  114. self.client.reqContinue(function() {
  115. // Intentionally blank.
  116. });
  117. });
  118. };
  119. module.exports = CommandRepl;