Commit 0633976e authored by Razvan Maries's avatar Razvan Maries
Browse files

Backed out 2 changesets (bug 1598259) for dt perma fails. CLOSED TREE

Backed out changeset 38140fd01a52 (bug 1598259)
Backed out changeset 70b22c90ea2e (bug 1598259)
parent b75f3406
......@@ -17,6 +17,8 @@ function _getSupportsFile(path) {
async function enableExtensionDebugging() {
// Disable security prompt
await pushPref("devtools.debugger.prompt-connection", false);
// Enable Browser toolbox test script execution via env variable
await pushPref("devtools.browser-toolbox.allow-unsafe-script", true);
}
/* exported enableExtensionDebugging */
......
......@@ -6,6 +6,7 @@
BROWSER_CHROME_MANIFESTS += [
'test/allocations/browser_allocations_target.ini',
'test/browser-rtl.ini',
'test/browser-telemetry-startup.ini',
'test/browser.ini',
'test/metrics/browser_metrics_debugger.ini',
......
[DEFAULT]
tags = devtools
subsuite = devtools
prefs =
# This test suite is dedicated to tests that need to run with the browser in RTL mode.
# This mode cannot be dynamically changed between tests reusing the browser instance and
# window.
intl.uidirection=1
support-files =
head.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_browser_toolbox_rtl.js]
......@@ -42,6 +42,7 @@ support-files =
serviceworker.js
sjs_code_reload.sjs
sjs_code_bundle_reload_map.sjs
test_browser_toolbox_debugger.js
test_chrome_page.html
!/devtools/client/debugger/test/mochitest/head.js
!/devtools/client/debugger/test/mochitest/helpers.js
......@@ -63,7 +64,6 @@ skip-if = coverage # Bug 1387827
skip-if = os == 'win' || debug || (bits == 64 && !debug && (os == 'mac' || os == 'linux')) # Bug 1282269, 1448084, Bug 1270731
[browser_browser_toolbox_fission_inspector.js]
skip-if = coverage # Bug 1387827
[browser_browser_toolbox_rtl.js]
[browser_devtools_api_destroy.js]
[browser_dynamic_tool_enabling.js]
[browser_front_parentFront.js]
......
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from helpers.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js",
this
);
// There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import(
......@@ -18,14 +12,84 @@ PromiseTestUtils.whitelistRejectionsGlobally(/File closed/);
requestLongerTimeout(4);
add_task(async function() {
const ToolboxTask = await initBrowserToolboxTask();
await ToolboxTask.importFunctions({});
await setupPreferencesForBrowserToolbox();
// Wait for a notification sent by a script evaluated in the webconsole
// of the browser toolbox.
const onCustomMessage = new Promise(done => {
Services.obs.addObserver(function listener(target, aTop, data) {
Services.obs.removeObserver(listener, "browser-toolbox-console-works");
done(data === "true");
}, "browser-toolbox-console-works");
});
const hasCloseButton = await ToolboxTask.spawn(null, async () => {
/* global gToolbox */
return !!gToolbox.doc.getElementById("toolbox-close");
// Be careful, this JS function is going to be executed in the addon toolbox,
// which lives in another process. So do not try to use any scope variable!
const env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
/* global toolbox */
const testScript = function() {
toolbox
.selectTool("webconsole")
.then(console => {
// This is for checking Browser Toolbox doesn't have a close button.
const hasCloseButton = !!toolbox.doc.getElementById("toolbox-close");
const { wrapper } = console.hud.ui;
const js = `Services.obs.notifyObservers(null, 'browser-toolbox-console-works', ${hasCloseButton} )`;
const onResult = new Promise(resolve => {
const onNewMessages = messages => {
for (const message of messages) {
if (message.node.classList.contains("result")) {
console.hud.ui.off("new-messages", onNewMessages);
resolve();
}
}
};
console.hud.ui.on("new-messages", onNewMessages);
});
wrapper.dispatchEvaluateExpression(js);
return onResult;
})
.then(() => toolbox.destroy());
};
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "new " + testScript);
registerCleanupFunction(() => {
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "");
});
const { BrowserToolboxProcess } = ChromeUtils.import(
"resource://devtools/client/framework/ToolboxProcess.jsm"
);
is(
BrowserToolboxProcess.getBrowserToolboxSessionState(),
false,
"No session state initially"
);
let closePromise;
await new Promise(onRun => {
closePromise = new Promise(onClose => {
info("Opening the browser toolbox\n");
BrowserToolboxProcess.init(onClose, onRun);
});
});
ok(true, "Browser toolbox started\n");
is(
BrowserToolboxProcess.getBrowserToolboxSessionState(),
true,
"Has session state"
);
const hasCloseButton = await onCustomMessage;
ok(true, "Received the custom message");
ok(!hasCloseButton, "Browser toolbox doesn't have a close button");
await ToolboxTask.destroy();
await closePromise;
ok(true, "Browser toolbox process just closed");
is(
BrowserToolboxProcess.getBrowserToolboxSessionState(),
false,
"No session state after closing"
);
});
......@@ -2,12 +2,9 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
// This test asserts that the new debugger works from the browser toolbox process
/* import-globals-from helpers.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js",
this
);
// 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.
// There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues.
......@@ -26,8 +23,11 @@ const debuggerHeadURL =
const helpersURL = CHROME_URL_ROOT + "../../debugger/test/mochitest/helpers.js";
const helpersContextURL =
CHROME_URL_ROOT + "../../debugger/test/mochitest/helpers/context.js";
const testScriptURL = CHROME_URL_ROOT + "test_browser_toolbox_debugger.js";
add_task(async function runTest() {
await setupPreferencesForBrowserToolbox();
const s = Cu.Sandbox("http://mozilla.org");
// Use a unique id for the fake script name in order to be able to run
......@@ -57,25 +57,17 @@ add_task(async function runTest() {
// Execute the function every second in order to trigger the breakpoint
const interval = setInterval(s.plop, 1000);
let { content: debuggerHead } = await fetch(debuggerHeadURL);
// Also include the debugger helpers which are separated from debugger's head to be
// reused in other modules.
const { content: debuggerHelpers } = await fetch(helpersURL);
const { content: debuggerContextHelpers } = await fetch(helpersContextURL);
debuggerHead = debuggerHead + debuggerContextHelpers + debuggerHelpers;
// 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[^\)]*\);/g,
""
// Be careful, this JS function is going to be executed in the browser toolbox,
// which lives in another process. So do not try to use any scope variable!
const env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
const ToolboxTask = await initBrowserToolboxTask();
await ToolboxTask.importScript(debuggerHead);
await ToolboxTask.importFunctions({
info: msg => dump(msg + "\n"),
is: (a, b, description) => {
// First inject a very minimal head, with simplest assertion methods
// and very common globals
/* eslint-disable no-unused-vars */
const 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) {
......@@ -89,8 +81,8 @@ add_task(async function runTest() {
msg = "SUCCESS: " + msg;
dump(msg + "\n");
}
},
ok: (a, description) => {
};
const ok = (a, description) => {
let msg = "'" + JSON.stringify(a) + "' is true";
if (description) {
msg += " - " + description;
......@@ -103,67 +95,92 @@ add_task(async function runTest() {
msg = "SUCCESS: " + msg;
dump(msg + "\n");
}
},
waitUntil,
});
};
const registerCleanupFunction = () => {};
await ToolboxTask.spawn(`"${testUrl}"`, async _testUrl => {
/* global createDebuggerContext, waitForSources,
waitForPaused, addBreakpoint, assertPausedLocation, stepIn,
findSource, removeBreakpoint, resume, selectSource */
const { require } = ChromeUtils.import(
"resource://devtools/shared/Loader.jsm"
);
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
Services.prefs.clearUserPref("devtools.debugger.tabs");
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location");
info("Waiting for debugger load");
/* global gToolbox */
await gToolbox.selectTool("jsdebugger");
const dbg = createDebuggerContext(gToolbox);
const window = dbg.win;
const document = window.document;
// Copied from shared-head.js:
// test_browser_toolbox_debugger.js uses waitForPaused, which relies on waitUntil
// which is normally provided by shared-head.js
const { setTimeout } = ChromeUtils.import(
"resource://gre/modules/Timer.jsm"
);
function waitUntil(predicate, interval = 10) {
if (predicate()) {
return Promise.resolve(true);
}
return new Promise(resolve => {
// TODO: fixme.
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
setTimeout(function() {
waitUntil(predicate, interval).then(() => resolve(true));
}, interval);
});
}
}
.toSource()
.replace(/^\(function\(\) \{|\}\)$/g, "");
/* eslint-enable no-unused-vars */
// Stringify testHead's function and remove `(function {` prefix and `})` suffix
// to ensure inner symbols gets exposed to next pieces of code
// Then inject new debugger head file
let { content: debuggerHead } = await fetch(debuggerHeadURL);
await waitForSources(dbg, _testUrl);
// Also include the debugger helpers which are separated from debugger's head to be
// reused in other modules.
const { content: debuggerHelpers } = await fetch(helpersURL);
const { content: debuggerContextHelpers } = await fetch(helpersContextURL);
debuggerHead = debuggerHead + debuggerContextHelpers + debuggerHelpers;
info("Loaded, selecting the test script to debug");
// First expand the domain
const domain = [...document.querySelectorAll(".tree-node")].find(node => {
return node.querySelector(".label").textContent.trim() == "mozilla.org";
});
const arrow = domain.querySelector(".arrow");
arrow.click();
// 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[^\)]*\);/g,
""
);
const fileName = _testUrl.match(/browser-toolbox-test.*\.js/)[0];
// Finally, fetch the debugger test script that is going to be execute in the browser
// toolbox process
const testScript = (await fetch(testScriptURL)).content;
const source =
'try { let testUrl = "' +
testUrl +
'";' +
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", "");
});
let script = [...document.querySelectorAll(".tree-node")].find(node => {
return node.textContent.includes(fileName);
const { BrowserToolboxProcess } = ChromeUtils.import(
"resource://devtools/client/framework/ToolboxProcess.jsm"
);
// Use two promises, one for each BrowserToolboxProcess.init callback
// arguments, to ensure that we wait for toolbox run and close events.
let closePromise;
await new Promise(onRun => {
closePromise = new Promise(onClose => {
info("Opening the browser toolbox\n");
BrowserToolboxProcess.init(onClose, onRun);
});
script = script.querySelector(".node");
script.click();
const onPaused = waitForPaused(dbg);
await selectSource(dbg, fileName);
await addBreakpoint(dbg, fileName, 2);
await onPaused;
assertPausedLocation(dbg, fileName, 2);
await stepIn(dbg);
assertPausedLocation(dbg, fileName, 3);
// Remove the breakpoint before resuming in order to prevent hitting the breakpoint
// again during test closing.
const source = findSource(dbg, fileName);
await removeBreakpoint(dbg, source.id, 2);
await resume(dbg);
});
ok(true, "Browser toolbox started\n");
clearInterval(interval);
await closePromise;
ok(true, "Browser toolbox process just closed");
await ToolboxTask.destroy();
clearInterval(interval);
});
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from helpers.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js",
this
);
// There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import(
......@@ -21,10 +15,7 @@ requestLongerTimeout(4);
// - computed view is correct when selecting an element in a remote frame
add_task(async function() {
const ToolboxTask = await initBrowserToolboxTask({
enableBrowserToolboxFission: true,
});
await ToolboxTask.importFunctions({});
await setupPreferencesForBrowserToolbox();
const tab = await addTab(
`data:text/html,<div id="my-div" style="color: red">Foo</div>`
......@@ -33,47 +24,103 @@ add_task(async function() {
// Set a custom attribute on the tab's browser, in order to easily select it in the markup view
tab.linkedBrowser.setAttribute("test-tab", "true");
const color = await ToolboxTask.spawn(null, async () => {
/* global gToolbox */
const inspector = await gToolbox.selectTool("inspector");
const onSidebarSelect = inspector.sidebar.once("select");
inspector.sidebar.select("computedview");
await onSidebarSelect;
async function select(walker, selector) {
const nodeFront = await walker.querySelector(walker.rootNode, selector);
const updated = inspector.once("inspector-updated");
inspector.selection.setNodeFront(nodeFront);
await updated;
return nodeFront;
}
const browser = await select(
inspector.walker,
'browser[remote="true"][test-tab]'
// Be careful, this JS function is going to be executed in the browser toolbox,
// which lives in another process. So do not try to use any scope variable!
const env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
/* global toolbox */
const testScript = function() {
// Force the fission pref in order to be able to pierce through the remote browser element
// Set the pref from the toolbox process as previous test may already have created
// the browser toolbox profile folder. Then setting the pref in Firefox process
// won't be taken into account for the browser toolbox.
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
const browserTarget = await browser.connectToRemoteFrame();
const walker = (await browserTarget.getFront("inspector")).walker;
await select(walker, "#my-div");
Services.prefs.setBoolPref("devtools.browsertoolbox.fission", true);
const view = inspector.getPanel("computedview").computedView;
function getProperty(name) {
const propertyViews = view.propertyViews;
for (const propView of propertyViews) {
if (propView.name == name) {
return propView;
toolbox
.selectTool("inspector")
.then(async inspector => {
const onSidebarSelect = inspector.sidebar.once("select");
inspector.sidebar.select("computedview");
await onSidebarSelect;
async function select(walker, selector) {
const nodeFront = await walker.querySelector(
walker.rootNode,
selector
);
const updated = inspector.once("inspector-updated");
inspector.selection.setNodeFront(nodeFront);
await updated;
return nodeFront;
}
const browser = await select(
inspector.walker,
'browser[remote="true"][test-tab]'
);
const browserTarget = await browser.connectToRemoteFrame();
const walker = (await browserTarget.getFront("inspector")).walker;
await select(walker, "#my-div");
const view = inspector.getPanel("computedview").computedView;
function getProperty(name) {
const propertyViews = view.propertyViews;
for (const propView of propertyViews) {
if (propView.name == name) {
return propView;
}
}
return null;
}
const prop = getProperty("color");
const color = prop.valueNode.textContent;
if (color != "rgb(255, 0, 0)") {
throw new Error(
"The color property of the <div> within a tab isn't red, got: " +
color
);
}
}
return null;
}
const prop = getProperty("color");
return prop.valueNode.textContent;
Services.prefs.setBoolPref("devtools.browsertoolbox.fission", false);
})
.then(() => toolbox.destroy());
};
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "new " + testScript);
registerCleanupFunction(() => {
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "");
});
const { BrowserToolboxProcess } = ChromeUtils.import(
"resource://devtools/client/framework/ToolboxProcess.jsm"
);
is(
BrowserToolboxProcess.getBrowserToolboxSessionState(),
false,
"No session state initially"
);
let closePromise;
await new Promise(onRun => {
closePromise = new Promise(onClose => {
info("Opening the browser toolbox\n");
BrowserToolboxProcess.init(onClose, onRun);
});
});
ok(true, "Browser toolbox started\n");
is(
color,
"rgb(255, 0, 0)",
"The color property of the <div> within a tab isn't red"
BrowserToolboxProcess.getBrowserToolboxSessionState(),
true,
"Has session state"
);
await ToolboxTask.destroy();
await closePromise;
ok(true, "Browser toolbox process just closed");
is(
BrowserToolboxProcess.getBrowserToolboxSessionState(),
false,
"No session state after closing"
);
});
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from helpers.js */
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/helpers.js",
this
);
// There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import(
......@@ -19,17 +13,82 @@ requestLongerTimeout(4);
// Test that DevTools panels are rendered in "rtl" (right-to-left) in the Browser Toolbox.
add_task(async function() {
await pushPref("intl.uidirection", 1);
await setupPreferencesForBrowserToolbox();
// Wait for a notification sent by a script evaluated in the webconsole
// of the browser toolbox.
const onCustomMessage = new Promise(resolve => {
Services.obs.addObserver(function listener(target, aTop, data) {
Services.obs.removeObserver(listener, "browser-toolbox-inspector-dir");
resolve(data);
}, "browser-toolbox-inspector-dir");
});
const env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
env.set(
"MOZ_TOOLBOX_TEST_SCRIPT",
"new function() {(" + testScript + ")();}"
);
registerCleanupFunction(() => env.set("MOZ_TOOLBOX_TEST_SCRIPT", ""));
const ToolboxTask = await initBrowserToolboxTask();
await ToolboxTask.importFunctions({});
const { BrowserToolboxProcess } = ChromeUtils.import(
"resource://devtools/client/framework/ToolboxProcess.jsm"
);
const dir = await ToolboxTask.spawn(null, async () => {
/* global gToolbox */
const inspector = await gToolbox.selectTool("inspector");
return inspector.panelDoc.dir;
let closePromise;