зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
2597348372
Коммит
a91c462cd7
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче