Bug 1346902 - Update browser toolbox integration test for new debugger. r=jlast

MozReview-Commit-ID: 8k8bIqSBKGf

--HG--
extra : rebase_source : cde5ef6e3a5de845e5236037ef9a408af73d8ca1
This commit is contained in:
J. Ryan Stinnett 2017-04-25 22:12:30 +02:00
Родитель 2597348372
Коммит a91c462cd7
5 изменённых файлов: 122 добавлений и 68 удалений

Просмотреть файл

@ -175,7 +175,8 @@ function waitForSources(dbg, ...sources) {
sources.map(url => {
function sourceExists(state) {
return getSources(state).some(s => {
return s.get("url").includes(url);
let u = s.get("url");
return u && u.includes(url);
});
}
@ -212,8 +213,9 @@ function assertPausedLocation(dbg, source, line) {
is(location.get("line"), line);
// Check the debug line
let cm = dbg.win.document.querySelector(".CodeMirror").CodeMirror;
ok(
dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
"Line is highlighted as paused"
);
}
@ -356,7 +358,10 @@ function findSource(dbg, url) {
}
const sources = dbg.selectors.getSources(dbg.getState());
const source = sources.find(s => s.get("url").includes(url));
const source = sources.find(s => {
let u = s.get("url");
return u && u.includes(url);
});
if (!source) {
throw new Error("Unable to find source: " + url);

Просмотреть файл

@ -23,6 +23,7 @@ support-files =
browser_toolbox_options_enable_serviceworkers_testing_frame_script.js
browser_toolbox_options_enable_serviceworkers_testing.html
serviceworker.js
test_browser_toolbox_debugger.js
[browser_browser_toolbox.js]
[browser_browser_toolbox_debugger.js]

Просмотреть файл

@ -2,10 +2,19 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// This test asserts that the new debugger works from the browser toolbox process
// Its pass a big piece of Javascript string to the browser toolbox process via
// MOZ_TOOLBOX_TEST_SCRIPT env variable. It does that as test resources fetched from
// chrome://mochitests/ package isn't available from browser toolbox process.
// On debug test runner, it takes about 50s to run the test.
requestLongerTimeout(4);
const { setInterval, clearInterval } = require("sdk/timers");
const { fetch } = require("devtools/shared/DevToolsUtils");
const debuggerHeadURL = CHROME_URL_ROOT + "../../debugger/new/test/mochitest/head.js";
const testScriptURL = CHROME_URL_ROOT + "test_browser_toolbox_debugger.js";
add_task(function* runTest() {
yield new Promise(done => {
@ -41,73 +50,64 @@ add_task(function* runTest() {
// which lives in another process. So do not try to use any scope variable!
let env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
let testScript = function () {
const { Task } = Components.utils.import("resource://gre/modules/Task.jsm", {});
dump("Opening the browser toolbox and debugger panel\n");
let window, document;
let testUrl = "http://mozilla.org/browser-toolbox-test.js";
Task.spawn(function* () {
dump("Waiting for debugger load\n");
let panel = yield toolbox.selectTool("jsdebugger");
let window = panel.panelWin;
let document = window.document;
yield window.once(window.EVENTS.SOURCE_SHOWN);
dump("Loaded, selecting the test script to debug\n");
let item = document.querySelector(`.dbg-source-item[tooltiptext="${testUrl}"]`);
let onSourceShown = window.once(window.EVENTS.SOURCE_SHOWN);
item.click();
yield onSourceShown;
dump("Selected, setting a breakpoint\n");
let { Sources, editor } = window.DebuggerView;
let onBreak = window.once(window.EVENTS.FETCHED_SCOPES);
editor.emit("gutterClick", 1);
yield onBreak;
dump("Paused, asserting breakpoint position\n");
let url = Sources.selectedItem.attachment.source.url;
if (url != testUrl) {
throw new Error("Breaking on unexpected script: " + url);
// First inject a very minimal head, with simplest assertion methods
// and very common globals
let testHead = (function () {
const info = msg => dump(msg + "\n");
const is = (a, b, description) => {
let msg = "'" + JSON.stringify(a) + "' is equal to '" + JSON.stringify(b) + "'";
if (description) {
msg += " - " + description;
}
let cursor = editor.getCursor();
if (cursor.line != 1) {
throw new Error("Breaking on unexpected line: " + cursor.line);
if (a !== b) {
msg = "FAILURE: " + msg;
dump(msg + "\n");
throw new Error(msg);
} else {
msg = "SUCCESS: " + msg;
dump(msg + "\n");
}
dump("Now, stepping over\n");
let stepOver = window.document.querySelector("#step-over");
let onFetchedScopes = window.once(window.EVENTS.FETCHED_SCOPES);
stepOver.click();
yield onFetchedScopes;
dump("Stepped, asserting step position\n");
url = Sources.selectedItem.attachment.source.url;
if (url != testUrl) {
throw new Error("Stepping on unexpected script: " + url);
};
const ok = (a, description) => {
let msg = "'" + JSON.stringify(a) + "' is true";
if (description) {
msg += " - " + description;
}
cursor = editor.getCursor();
if (cursor.line != 2) {
throw new Error("Stepping on unexpected line: " + cursor.line);
if (!a) {
msg = "FAILURE: " + msg;
dump(msg + "\n");
throw new Error(msg);
} else {
msg = "SUCCESS: " + msg;
dump(msg + "\n");
}
};
const registerCleanupFunction = () => {};
dump("Resume script execution\n");
let resume = window.document.querySelector("#resume");
let onResume = toolbox.target.once("thread-resumed");
resume.click();
yield onResume;
const Cu = Components.utils;
const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
}).toSource().replace(/^\(function \(\) \{|\}\)$/g, "");
// Stringify testHead's function and remove `(function {` prefix and `})` suffix
// to ensure inner symbols gets exposed to next pieces of code
dump("Close the browser toolbox\n");
toolbox.destroy();
// Then inject new debugger head file
let { content } = yield fetch(debuggerHeadURL);
let debuggerHead = content;
// We remove its import of shared-head, which isn't available in browser toolbox process
// And isn't needed thanks to testHead's symbols
debuggerHead = debuggerHead.replace(/Services.scriptloader.loadSubScript[^\)]*\);/, "");
}).catch(error => {
dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n");
dump("stack:\n" + error.stack + "\n");
});
};
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "new " + testScript);
// Finally, fetch the debugger test script that is going to be execute in the browser
// toolbox process
let testScript = (yield fetch(testScriptURL)).content;
let source =
"try {" + testHead + debuggerHead + testScript + "} catch (e) {" +
" dump('Exception: '+ e + ' at ' + e.fileName + ':' + " +
" e.lineNumber + '\\nStack: ' + e.stack + '\\n');" +
"}";
env.set("MOZ_TOOLBOX_TEST_SCRIPT", source);
registerCleanupFunction(() => {
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "");
});

Просмотреть файл

@ -0,0 +1,48 @@
/* global toolbox */
info(`START: ${new Error().lineNumber}`);
let testUrl = "http://mozilla.org/browser-toolbox-test.js";
Task.spawn(function* () {
Services.prefs.clearUserPref("devtools.debugger.tabs")
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
info("Waiting for debugger load");
yield toolbox.selectTool("jsdebugger");
let dbg = createDebuggerContext(toolbox);
let window = dbg.win;
let document = window.document;
yield waitForSources(dbg, testUrl);
// yield waitForSourceCount(dbg, 6);
info("Loaded, selecting the test script to debug");
// First expand the domain
let domain = [...document.querySelectorAll(".tree-node")].find(node => {
return node.textContent == "mozilla.org";
});
let arrow = domain.querySelector(".arrow");
arrow.click();
let script = [...document.querySelectorAll(".tree-node")].find(node => {
return node.textContent.includes("browser-toolbox-test.js");
});
script = script.querySelector(".node");
script.click();
let onPaused = waitForPaused(dbg);
yield addBreakpoint(dbg, "browser-toolbox-test.js", 2);
yield onPaused;
assertPausedLocation(dbg, "browser-toolbox-test.js", 2);
yield stepIn(dbg);
assertPausedLocation(dbg, "browser-toolbox-test.js", 3);
yield resume(dbg);
info("Close the browser toolbox");
toolbox.destroy();
});

Просмотреть файл

@ -157,16 +157,16 @@ function bindToolboxHandlers() {
}
function setupThreadListeners(panel) {
updateBadgeText(panel._controller.activeThread.state == "paused");
updateBadgeText(panel._selectors().getPause(panel._getState()));
let onPaused = updateBadgeText.bind(null, true);
let onResumed = updateBadgeText.bind(null, false);
panel.target.on("thread-paused", onPaused);
panel.target.on("thread-resumed", onResumed);
gToolbox.target.on("thread-paused", onPaused);
gToolbox.target.on("thread-resumed", onResumed);
panel.once("destroyed", () => {
panel.off("thread-paused", onPaused);
panel.off("thread-resumed", onResumed);
gToolbox.target.off("thread-paused", onPaused);
gToolbox.target.off("thread-resumed", onResumed);
});
}