browser_source_map-01.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Any copyright is dedicated to the Public Domain.
  2. http://creativecommons.org/publicdomain/zero/1.0/ */
  3. // Whitelisting this test.
  4. // As part of bug 1077403, the leaking uncaught rejections should be fixed.
  5. thisTestLeaksUncaughtRejectionsAndShouldBeFixed("[object Object]");
  6. thisTestLeaksUncaughtRejectionsAndShouldBeFixed(
  7. "TypeError: this.transport is null");
  8. /**
  9. * Tests the SourceMapService updates generated sources when source maps
  10. * are subsequently found. Also checks when no column is provided, and
  11. * when tagging an already source mapped location initially.
  12. */
  13. // Force the old debugger UI since it's directly used (see Bug 1301705)
  14. Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
  15. registerCleanupFunction(function* () {
  16. Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
  17. });
  18. const DEBUGGER_ROOT = "http://example.com/browser/devtools/client/debugger/test/mochitest/";
  19. // Empty page
  20. const PAGE_URL = `${DEBUGGER_ROOT}doc_empty-tab-01.html`;
  21. const JS_URL = `${URL_ROOT}code_binary_search.js`;
  22. const COFFEE_URL = `${URL_ROOT}code_binary_search.coffee`;
  23. const { SourceMapService } = require("devtools/client/framework/source-map-service");
  24. const { serialize } = require("devtools/client/framework/location-store");
  25. add_task(function* () {
  26. const toolbox = yield openNewTabAndToolbox(PAGE_URL, "jsdebugger");
  27. const service = new SourceMapService(toolbox.target);
  28. let aggregator = new Map();
  29. function onUpdate(e, oldLoc, newLoc) {
  30. if (oldLoc.line === 6) {
  31. checkLoc1(oldLoc, newLoc);
  32. } else if (oldLoc.line === 8) {
  33. checkLoc2(oldLoc, newLoc);
  34. } else {
  35. throw new Error(`Unexpected location update: ${JSON.stringify(oldLoc)}`);
  36. }
  37. aggregator.set(serialize(oldLoc), newLoc);
  38. }
  39. let loc1 = { url: JS_URL, line: 6 };
  40. let loc2 = { url: JS_URL, line: 8, column: 3 };
  41. service.subscribe(loc1, onUpdate);
  42. service.subscribe(loc2, onUpdate);
  43. // Inject JS script
  44. let sourceShown = waitForSourceShown(toolbox.getCurrentPanel(), "code_binary_search");
  45. yield createScript(JS_URL);
  46. yield sourceShown;
  47. yield waitUntil(() => aggregator.size === 2);
  48. aggregator = Array.from(aggregator.values());
  49. ok(aggregator.find(i => i.url === COFFEE_URL && i.line === 4), "found first updated location");
  50. ok(aggregator.find(i => i.url === COFFEE_URL && i.line === 6), "found second updated location");
  51. yield toolbox.destroy();
  52. gBrowser.removeCurrentTab();
  53. finish();
  54. });
  55. function checkLoc1(oldLoc, newLoc) {
  56. is(oldLoc.line, 6, "Correct line for JS:6");
  57. is(oldLoc.column, null, "Correct column for JS:6");
  58. is(oldLoc.url, JS_URL, "Correct url for JS:6");
  59. is(newLoc.line, 4, "Correct line for JS:6 -> COFFEE");
  60. is(newLoc.column, 2, "Correct column for JS:6 -> COFFEE -- handles falsy column entries");
  61. is(newLoc.url, COFFEE_URL, "Correct url for JS:6 -> COFFEE");
  62. }
  63. function checkLoc2(oldLoc, newLoc) {
  64. is(oldLoc.line, 8, "Correct line for JS:8:3");
  65. is(oldLoc.column, 3, "Correct column for JS:8:3");
  66. is(oldLoc.url, JS_URL, "Correct url for JS:8:3");
  67. is(newLoc.line, 6, "Correct line for JS:8:3 -> COFFEE");
  68. is(newLoc.column, 10, "Correct column for JS:8:3 -> COFFEE");
  69. is(newLoc.url, COFFEE_URL, "Correct url for JS:8:3 -> COFFEE");
  70. }
  71. function createScript(url) {
  72. info(`Creating script: ${url}`);
  73. let mm = getFrameScript();
  74. let command = `
  75. let script = document.createElement("script");
  76. script.setAttribute("src", "${url}");
  77. document.body.appendChild(script);
  78. null;
  79. `;
  80. return evalInDebuggee(mm, command);
  81. }
  82. function waitForSourceShown(debuggerPanel, url) {
  83. let { panelWin } = debuggerPanel;
  84. let deferred = defer();
  85. info(`Waiting for source ${url} to be shown in the debugger...`);
  86. panelWin.on(panelWin.EVENTS.SOURCE_SHOWN, function onSourceShown(_, source) {
  87. let sourceUrl = source.url || source.generatedUrl;
  88. if (sourceUrl.includes(url)) {
  89. panelWin.off(panelWin.EVENTS.SOURCE_SHOWN, onSourceShown);
  90. info(`Source shown for ${url}`);
  91. deferred.resolve(source);
  92. }
  93. });
  94. return deferred.promise;
  95. }