browser_webconsole_jsterm.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
  2. /* Any copyright is dedicated to the Public Domain.
  3. * http://creativecommons.org/publicdomain/zero/1.0/ */
  4. "use strict";
  5. const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
  6. "test/test-console.html";
  7. var jsterm;
  8. add_task(function* () {
  9. yield loadTab(TEST_URI);
  10. let hud = yield openConsole();
  11. jsterm = hud.jsterm;
  12. yield testJSTerm(hud);
  13. jsterm = null;
  14. });
  15. function checkResult(msg, desc) {
  16. let def = promise.defer();
  17. waitForMessages({
  18. webconsole: jsterm.hud.owner,
  19. messages: [{
  20. name: desc,
  21. category: CATEGORY_OUTPUT,
  22. }],
  23. }).then(([result]) => {
  24. let node = [...result.matched][0].querySelector(".message-body");
  25. if (typeof msg == "string") {
  26. is(node.textContent.trim(), msg,
  27. "correct message shown for " + desc);
  28. } else if (typeof msg == "function") {
  29. ok(msg(node), "correct message shown for " + desc);
  30. }
  31. def.resolve();
  32. });
  33. return def.promise;
  34. }
  35. function* testJSTerm(hud) {
  36. const HELP_URL = "https://developer.mozilla.org/docs/Tools/" +
  37. "Web_Console/Helpers";
  38. jsterm.clearOutput();
  39. yield jsterm.execute("$('#header').getAttribute('id')");
  40. yield checkResult('"header"', "$() worked");
  41. jsterm.clearOutput();
  42. yield jsterm.execute("$$('h1').length");
  43. yield checkResult("1", "$$() worked");
  44. jsterm.clearOutput();
  45. yield jsterm.execute("$x('.//*', document.body)[0] == $$('h1')[0]");
  46. yield checkResult("true", "$x() worked");
  47. // no jsterm.clearOutput() here as we clear the output using the clear() fn.
  48. yield jsterm.execute("clear()");
  49. yield waitForSuccess({
  50. name: "clear() worked",
  51. validator: function () {
  52. return jsterm.outputNode.childNodes.length == 0;
  53. }
  54. });
  55. jsterm.clearOutput();
  56. yield jsterm.execute("keys({b:1})[0] == 'b'");
  57. yield checkResult("true", "keys() worked", 1);
  58. jsterm.clearOutput();
  59. yield jsterm.execute("values({b:1})[0] == 1");
  60. yield checkResult("true", "values() worked", 1);
  61. jsterm.clearOutput();
  62. let openedLinks = 0;
  63. let oldOpenLink = hud.openLink;
  64. hud.openLink = (url) => {
  65. if (url == HELP_URL) {
  66. openedLinks++;
  67. }
  68. };
  69. yield jsterm.execute("help()");
  70. yield jsterm.execute("help");
  71. yield jsterm.execute("?");
  72. let output = jsterm.outputNode.querySelector(".message[category='output']");
  73. ok(!output, "no output for help() calls");
  74. is(openedLinks, 3, "correct number of pages opened by the help calls");
  75. hud.openLink = oldOpenLink;
  76. jsterm.clearOutput();
  77. yield jsterm.execute("pprint({b:2, a:1})");
  78. yield checkResult("\" b: 2\n a: 1\"", "pprint()");
  79. // check instanceof correctness, bug 599940
  80. jsterm.clearOutput();
  81. yield jsterm.execute("[] instanceof Array");
  82. yield checkResult("true", "[] instanceof Array == true");
  83. jsterm.clearOutput();
  84. yield jsterm.execute("({}) instanceof Object");
  85. yield checkResult("true", "({}) instanceof Object == true");
  86. // check for occurrences of Object XRayWrapper, bug 604430
  87. jsterm.clearOutput();
  88. yield jsterm.execute("document");
  89. yield checkResult(function (node) {
  90. return node.textContent.search(/\[object xraywrapper/i) == -1;
  91. }, "document - no XrayWrapper");
  92. // check that pprint(window) and keys(window) don't throw, bug 608358
  93. jsterm.clearOutput();
  94. yield jsterm.execute("pprint(window)");
  95. yield checkResult(null, "pprint(window)");
  96. jsterm.clearOutput();
  97. yield jsterm.execute("keys(window)");
  98. yield checkResult(null, "keys(window)");
  99. // bug 614561
  100. jsterm.clearOutput();
  101. yield jsterm.execute("pprint('hi')");
  102. yield checkResult("\" 0: \"h\"\n 1: \"i\"\"", "pprint('hi')");
  103. // check that pprint(function) shows function source, bug 618344
  104. jsterm.clearOutput();
  105. yield jsterm.execute("pprint(function() { var someCanaryValue = 42; })");
  106. yield checkResult(function (node) {
  107. return node.textContent.indexOf("someCanaryValue") > -1;
  108. }, "pprint(function) shows source");
  109. // check that an evaluated null produces "null", bug 650780
  110. jsterm.clearOutput();
  111. yield jsterm.execute("null");
  112. yield checkResult("null", "null is null");
  113. jsterm.clearOutput();
  114. yield jsterm.execute("undefined");
  115. yield checkResult("undefined", "undefined is printed");
  116. // check that thrown strings produce error messages,
  117. // and the message text matches that of a stringified error object
  118. // bug 1099071
  119. jsterm.clearOutput();
  120. yield jsterm.execute("throw '';");
  121. yield checkResult((node) => {
  122. return node.closest(".message").getAttribute("severity") === "error" &&
  123. node.textContent === new Error("").toString();
  124. }, "thrown empty string generates error message");
  125. jsterm.clearOutput();
  126. yield jsterm.execute("throw 'tomatoes';");
  127. yield checkResult((node) => {
  128. return node.closest(".message").getAttribute("severity") === "error" &&
  129. node.textContent === new Error("tomatoes").toString();
  130. }, "thrown non-empty string generates error message");
  131. jsterm.clearOutput();
  132. yield jsterm.execute("throw { foo: 'bar' };");
  133. yield checkResult((node) => {
  134. return node.closest(".message").getAttribute("severity") === "error" &&
  135. node.textContent === Object.prototype.toString();
  136. }, "thrown object generates error message");
  137. // check that errors with entires in errordocs.js display links
  138. // alongside their messages.
  139. const ErrorDocs = require("devtools/server/actors/errordocs");
  140. const ErrorDocStatements = {
  141. "JSMSG_BAD_RADIX": "(42).toString(0);",
  142. "JSMSG_BAD_ARRAY_LENGTH": "([]).length = -1",
  143. "JSMSG_NEGATIVE_REPETITION_COUNT": "'abc'.repeat(-1);",
  144. "JSMSG_PRECISION_RANGE": "77.1234.toExponential(-1);",
  145. };
  146. for (let errorMessageName of Object.keys(ErrorDocStatements)) {
  147. let title = ErrorDocs.GetURL({ errorMessageName }).split("?")[0];
  148. jsterm.clearOutput();
  149. yield jsterm.execute(ErrorDocStatements[errorMessageName]);
  150. yield checkResult((node) => {
  151. return node.parentNode.getElementsByTagName("a")[0].title == title;
  152. }, `error links to ${title}`);
  153. }
  154. // Ensure that dom errors, with error numbers outside of the range
  155. // of valid js.msg errors, don't cause crashes (bug 1270721).
  156. yield jsterm.execute("new Request('',{redirect:'foo'})");
  157. }