Bug 1441703 - Split DevTools performance test damp.js;r=ochameau

MozReview-Commit-ID: Jwfe7RLxEg2

--HG--
rename : testing/talos/talos/tests/devtools/addon/content/pages/custom/panels-in-background/panels-in-background.html => testing/talos/talos/tests/devtools/addon/content/pages/custom/panels-in-background/index.html
extra : rebase_source : cebfd6265d88a1d5ea5135d200d115f7e5c71c94
This commit is contained in:
Julian Descottes 2018-03-09 09:03:11 +01:00
Родитель 24e313e7c7
Коммит 43ae2eade9
34 изменённых файлов: 1562 добавлений и 1104 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,33 @@
"use strict";
module.exports = {
"plugins": [
"react"
],
"globals": {
"exports": true,
"isWorker": true,
"loader": true,
"module": true,
"reportError": true,
"require": true,
},
"rules": {
"no-unused-vars": ["error", {"args": "none", "vars": "all"}],
// These are the rules that have been configured so far to match the
// devtools coding style.
// Rules from the mozilla plugin
"mozilla/no-aArgs": "error",
"mozilla/no-cpows-in-tests": "error",
"mozilla/no-single-arg-cu-import": "error",
// See bug 1224289.
"mozilla/reject-importGlobalProperties": "error",
// devtools/shared/platform is special; see the README.md in that
// directory for details. We reject requires using explicit
// subdirectories of this directory.
"mozilla/reject-some-requires": ["error", "^devtools/shared/platform/(chome|content)/"],
"mozilla/var-only-at-top-level": "error",
"mozilla/use-chromeutils-import": ["error", {allowCu: true}]
}
};

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

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { closeToolboxAndLog, testSetup, testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
const { openDebuggerAndLog, reloadDebuggerAndLog } = require("chrome://damp/content/tests/debugger/debugger-helpers");
const EXPECTED = {
sources: 14,
file: "ga.js",
text: "Math;function ga(a,b){return a.name=b}"
};
module.exports = async function() {
await testSetup(COMPLICATED_URL);
let toolbox = await openDebuggerAndLog("complicated", EXPECTED);
await reloadDebuggerAndLog("complicated", toolbox, EXPECTED);
await closeToolboxAndLog("complicated.jsdebugger", toolbox);
await testTeardown();
};

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

@ -0,0 +1,91 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { closeToolboxAndLog, garbageCollect, runTest, testSetup,
testTeardown, PAGES_BASE_URL } = require("chrome://damp/content/tests/head");
const { createContext, openDebuggerAndLog, pauseDebugger, reloadDebuggerAndLog,
removeBreakpoints, resume, step } = require("chrome://damp/content/tests/debugger/debugger-helpers");
const EXPECTED = {
sources: 7,
file: "App.js",
text: "import React, { Component } from 'react';"
};
const EXPECTED_FUNCTION = "window.hitBreakpoint()";
module.exports = async function() {
const tab = await testSetup(PAGES_BASE_URL + "custom/debugger/index.html");
const toolbox = await openDebuggerAndLog("custom", EXPECTED);
await reloadDebuggerAndLog("custom", toolbox, EXPECTED);
// these tests are only run on custom.jsdebugger
await pauseDebuggerAndLog(tab, toolbox, EXPECTED_FUNCTION);
await stepDebuggerAndLog(tab, toolbox, EXPECTED_FUNCTION);
await closeToolboxAndLog("custom.jsdebugger", toolbox);
await testTeardown();
};
async function pauseDebuggerAndLog(tab, toolbox, testFunction) {
dump("Waiting for debugger panel\n");
const panel = await toolbox.getPanelWhenReady("jsdebugger");
dump("Creating context\n");
const dbg = await createContext(panel);
const pauseLocation = { line: 22, file: "App.js" };
dump("Pausing debugger\n");
let test = runTest("custom.jsdebugger.pause.DAMP");
await pauseDebugger(dbg, tab, testFunction, pauseLocation);
test.done();
await removeBreakpoints(dbg);
await resume(dbg);
await garbageCollect();
}
async function stepDebuggerAndLog(tab, toolbox, testFunction) {
const panel = await toolbox.getPanelWhenReady("jsdebugger");
const dbg = await createContext(panel);
const stepCount = 2;
/*
* Each Step test has a max step count of at least 200;
* see https://github.com/codehag/debugger-talos-example/blob/master/src/ and the specific test
* file for more information
*/
const stepTests = [
{
location: { line: 10194, file: "step-in-test.js" },
key: "stepIn"
},
{
location: { line: 16, file: "step-over-test.js" },
key: "stepOver"
},
{
location: { line: 998, file: "step-out-test.js" },
key: "stepOut"
}
];
for (const stepTest of stepTests) {
await pauseDebugger(dbg, tab, testFunction, stepTest.location);
const test = runTest(`custom.jsdebugger.${stepTest.key}.DAMP`);
for (let i = 0; i < stepCount; i++) {
await step(dbg, stepTest.key);
}
test.done();
await removeBreakpoints(dbg);
await resume(dbg);
await garbageCollect();
}
}

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

@ -0,0 +1,277 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, reloadPageAndLog } = require("chrome://damp/content/tests/head");
/*
* These methods are used for working with debugger state changes in order
* to make it easier to manipulate the ui and test different behavior. These
* methods roughly reflect those found in debugger/new/test/mochi/head.js with
* a few exceptions. The `dbg` object is not exactly the same, and the methods
* have been simplified. We may want to consider unifying them in the future
*/
const DEBUGGER_POLLING_INTERVAL = 50;
function waitForState(dbg, predicate, msg) {
return new Promise(resolve => {
if (msg) {
dump(`Waiting for state change: ${msg}\n`);
}
if (predicate(dbg.store.getState())) {
if (msg) {
dump(`Finished waiting for state change: ${msg}\n`);
}
return resolve();
}
const unsubscribe = dbg.store.subscribe(() => {
if (predicate(dbg.store.getState())) {
if (msg) {
dump(`Finished waiting for state change: ${msg}\n`);
}
unsubscribe();
resolve();
}
});
return false;
});
}
function waitForDispatch(dbg, type) {
return new Promise(resolve => {
dbg.store.dispatch({
type: "@@service/waitUntil",
predicate: action => {
if (action.type === type) {
return action.status
? action.status === "done" || action.status === "error"
: true;
}
return false;
},
run: (dispatch, getState, action) => {
resolve(action);
}
});
});
}
async function waitUntil(predicate, msg) {
if (msg) {
dump(`Waiting until: ${msg}\n`);
}
return new Promise(resolve => {
const timer = setInterval(() => {
if (predicate()) {
clearInterval(timer);
if (msg) {
dump(`Finished Waiting until: ${msg}\n`);
}
resolve();
}
}, DEBUGGER_POLLING_INTERVAL);
});
}
function findSource(dbg, url) {
const sources = dbg.selectors.getSources(dbg.getState());
return sources.find(s => (s.get("url") || "").includes(url));
}
function getCM(dbg) {
const el = dbg.win.document.querySelector(".CodeMirror");
return el.CodeMirror;
}
function waitForText(dbg, url, text) {
return waitUntil(() => {
// the welcome box is removed once text is displayed
const welcomebox = dbg.win.document.querySelector(".welcomebox");
if (welcomebox) {
return false;
}
const cm = getCM(dbg);
const editorText = cm.doc.getValue();
return editorText.includes(text);
}, "text is visible");
}
function waitForMetaData(dbg) {
return waitUntil(
() => {
const state = dbg.store.getState();
const source = dbg.selectors.getSelectedSource(state);
// wait for metadata -- this involves parsing the file to determine its type.
// if the object is empty, the data has not yet loaded
const metaData = dbg.selectors.getSourceMetaData(state, source.get("id"));
return !!Object.keys(metaData).length;
},
"has file metadata"
);
}
function waitForSources(dbg, expectedSources) {
const { selectors } = dbg;
function countSources(state) {
const sources = selectors.getSources(state);
return sources.size >= expectedSources;
}
return waitForState(dbg, countSources, "count sources");
}
async function waitForPaused(dbg) {
const onLoadedScope = waitForLoadedScopes(dbg);
const onStateChange = waitForState(
dbg,
state => {
return dbg.selectors.getSelectedScope(state) && dbg.selectors.isPaused(state);
},
);
return Promise.all([onLoadedScope, onStateChange]);
}
async function waitForResumed(dbg) {
return waitForState(
dbg,
state => !dbg.selectors.isPaused(state)
);
}
async function waitForElement(dbg, name) {
await waitUntil(() => dbg.win.document.querySelector(name));
return dbg.win.document.querySelector(name);
}
async function waitForLoadedScopes(dbg) {
const element = ".scopes-list .tree-node[aria-level=\"1\"]";
return waitForElement(dbg, element);
}
function createContext(panel) {
const { store, selectors, actions } = panel.getVarsForTests();
return {
actions,
selectors,
getState: store.getState,
win: panel.panelWin,
store
};
}
exports.createContext = createContext;
function selectSource(dbg, url) {
dump(`Selecting source: ${url}\n`);
const line = 1;
const source = findSource(dbg, url);
dbg.actions.selectLocation({ sourceId: source.get("id"), line });
return waitForState(
dbg,
state => {
const source = dbg.selectors.getSelectedSource(state);
const isLoaded = source && source.get("loadedState") === "loaded";
if (!isLoaded) {
return false;
}
// wait for symbols -- a flat map of all named variables in a file -- to be calculated.
// this is a slow process and becomes slower the larger the file is
return dbg.selectors.hasSymbols(state, source.toJS());
},
"selected source"
);
}
function evalInContent(dbg, tab, testFunction) {
dump(`Run function in content process: ${testFunction}\n`);
// Load a frame script using a data URI so we can run a script
// inside of the content process and trigger debugger functionality
// as needed
const messageManager = tab.linkedBrowser.messageManager;
return messageManager.loadFrameScript("data:,(" + encodeURIComponent(
`function () {
content.window.eval("${testFunction}");
}`
) + ")()", true);
}
async function openDebuggerAndLog(label, expected) {
const onLoad = async (toolbox, panel) => {
const dbg = await createContext(panel);
await waitForSources(dbg, expected.sources);
await selectSource(dbg, expected.file);
await waitForText(dbg, expected.file, expected.text);
await waitForMetaData(dbg);
};
const toolbox = await openToolboxAndLog(label + ".jsdebugger", "jsdebugger", onLoad);
return toolbox;
}
exports.openDebuggerAndLog = openDebuggerAndLog;
async function reloadDebuggerAndLog(label, toolbox, expected) {
const onReload = async () => {
const panel = await toolbox.getPanelWhenReady("jsdebugger");
const dbg = await createContext(panel);
await waitForDispatch(dbg, "NAVIGATE");
await waitForSources(dbg, expected.sources);
await waitForText(dbg, expected.file, expected.text);
await waitForMetaData(dbg);
};
await reloadPageAndLog(`${label}.jsdebugger`, toolbox, onReload);
}
exports.reloadDebuggerAndLog = reloadDebuggerAndLog;
async function addBreakpoint(dbg, line, url) {
dump(`add breakpoint\n`);
const source = findSource(dbg, url);
const location = {
sourceId: source.get("id"),
line,
column: 0
};
const onDispatched = waitForDispatch(dbg, "ADD_BREAKPOINT");
dbg.actions.addBreakpoint(location);
return onDispatched;
}
exports.addBreakpoint = addBreakpoint;
async function removeBreakpoints(dbg, line, url) {
dump(`remove all breakpoints\n`);
const breakpoints = dbg.selectors.getBreakpoints(dbg.getState());
const onBreakpointsCleared = waitForState(
dbg,
state => !dbg.selectors.getBreakpoints(state).length
);
await dbg.actions.removeBreakpoints(breakpoints);
return onBreakpointsCleared;
}
exports.removeBreakpoints = removeBreakpoints;
async function pauseDebugger(dbg, tab, testFunction, { line, file }) {
await addBreakpoint(dbg, line, file);
const onPaused = waitForPaused(dbg);
await evalInContent(dbg, tab, testFunction);
return onPaused;
}
exports.pauseDebugger = pauseDebugger;
async function resume(dbg) {
const onResumed = waitForResumed(dbg);
dbg.actions.resume();
return onResumed;
}
exports.resume = resume;
async function step(dbg, stepType) {
const resumed = waitForResumed(dbg);
dbg.actions[stepType]();
await resumed;
return waitForPaused(dbg);
}
exports.step = step;

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

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { closeToolboxAndLog, testSetup, testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
const { openDebuggerAndLog, reloadDebuggerAndLog } = require("chrome://damp/content/tests/debugger/debugger-helpers");
const EXPECTED = {
sources: 1,
file: "simple.html",
text: "This is a simple page"
};
module.exports = async function() {
await testSetup(SIMPLE_URL);
let toolbox = await openDebuggerAndLog("simple", EXPECTED);
await reloadDebuggerAndLog("simple", toolbox, EXPECTED);
await closeToolboxAndLog("simple.jsdebugger", toolbox);
await testTeardown();
};

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

@ -0,0 +1,157 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* This helper contains the public API that can be used by DAMP tests.
*/
// eslint-disable-next-line mozilla/no-define-cc-etc
const { Ci } = require("chrome");
const Services = require("Services");
const { gDevTools } = require("devtools/client/framework/devtools");
const { TargetFactory } = require("devtools/client/framework/target");
const webserver = Services.prefs.getCharPref("addon.test.damp.webserver");
const PAGES_BASE_URL = webserver + "/tests/devtools/addon/content/pages/";
exports.PAGES_BASE_URL = PAGES_BASE_URL;
exports.SIMPLE_URL = PAGES_BASE_URL + "simple.html";
exports.COMPLICATED_URL = webserver + "/tests/tp5n/bild.de/www.bild.de/index.html";
let damp = null;
/*
* This method should be called by js before starting the tests.
*/
exports.initialize = function(_damp) {
damp = _damp;
};
function garbageCollect() {
return damp.garbageCollect();
}
exports.garbageCollect = garbageCollect;
function runTest(label) {
return damp.runTest(label);
}
exports.runTest = runTest;
exports.testSetup = function(url) {
return damp.testSetup(url);
};
exports.testTeardown = function() {
return damp.testTeardown();
};
exports.logTestResult = function(name, value) {
damp._results.push(name, value);
};
function getBrowserWindow() {
return Services.wm.getMostRecentWindow("navigator:browser");
}
exports.getBrowserWindow = getBrowserWindow;
function getActiveTab() {
return getBrowserWindow().gBrowser.selectedTab;
}
exports.getActiveTab = getActiveTab;
exports.getToolbox = function() {
let tab = getActiveTab();
let target = TargetFactory.forTab(tab);
return gDevTools.getToolbox(target);
};
/**
* Wait for any pending paint.
* The tool may have touched the DOM elements at the very end of the current test.
* We should ensure waiting for the reflow related to these changes.
*/
async function waitForPendingPaints(toolbox) {
let panel = toolbox.getCurrentPanel();
// All panels have its own way of exposing their window object...
let window = panel.panelWin || panel._frameWindow || panel.panelWindow;
let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
window.performance.mark("pending paints.start");
while (utils.isMozAfterPaintPending) {
await new Promise(done => {
window.addEventListener("MozAfterPaint", function listener() {
window.performance.mark("pending paint");
done();
}, { once: true });
});
}
window.performance.measure("pending paints", "pending paints.start");
}
const openToolbox = async function(tool = "webconsole", onLoad) {
let tab = getActiveTab();
let target = TargetFactory.forTab(tab);
let onToolboxCreated = gDevTools.once("toolbox-created");
let showPromise = gDevTools.showToolbox(target, tool);
let toolbox = await onToolboxCreated;
if (typeof(onLoad) == "function") {
let panel = await toolbox.getPanelWhenReady(tool);
await onLoad(toolbox, panel);
}
await showPromise;
return toolbox;
};
exports.openToolbox = openToolbox;
exports.closeToolbox = async function() {
let tab = getActiveTab();
let target = TargetFactory.forTab(tab);
await target.client.waitForRequestsToSettle();
await gDevTools.closeToolbox(target);
};
exports.openToolboxAndLog = async function(name, tool, onLoad) {
let test = runTest(name + ".open.DAMP");
let toolbox = await openToolbox(tool, onLoad);
test.done();
test = runTest(name + ".open.settle.DAMP");
await waitForPendingPaints(toolbox);
test.done();
// Force freeing memory after toolbox open as it creates a lot of objects
// and for complex documents, it introduces a GC that runs during 'reload' test.
await garbageCollect();
return toolbox;
};
exports.closeToolboxAndLog = async function(name, toolbox) {
let { target } = toolbox;
dump("Close toolbox on '" + name + "'\n");
await target.client.waitForRequestsToSettle();
let test = runTest(name + ".close.DAMP");
await gDevTools.closeToolbox(target);
test.done();
};
exports.reloadPageAndLog = async function(name, toolbox, onReload) {
dump("Reload page on '" + name + "'\n");
let test = runTest(name + ".reload.DAMP");
await damp.reloadPage(onReload);
test.done();
dump("Wait for pending paints on '" + name + "'\n");
test = runTest(name + ".reload.settle.DAMP");
await waitForPendingPaints(toolbox);
test.done();
};
dump("Required HEAD successfully\n");

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

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolbox, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
// This simple test is only called once using the flag coldRun
module.exports = async function() {
await testSetup(SIMPLE_URL);
await openToolboxAndLog("cold.inspector", "inspector");
await closeToolbox();
await testTeardown();
};

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

@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { reloadInspectorAndLog } = require("chrome://damp/content/tests/inspector/inspector-helpers");
const { openToolboxAndLog, closeToolboxAndLog, testSetup,
testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(COMPLICATED_URL);
let toolbox = await openToolboxAndLog("complicated.inspector", "inspector");
await reloadInspectorAndLog("complicated", toolbox);
await closeToolboxAndLog("complicated.inspector", toolbox);
await testTeardown();
};

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

@ -0,0 +1,56 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { reloadInspectorAndLog } = require("chrome://damp/content/tests/inspector/inspector-helpers");
const { openToolboxAndLog, closeToolboxAndLog, runTest, testSetup,
testTeardown, PAGES_BASE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(PAGES_BASE_URL + "custom/inspector/index.html");
let toolbox = await openToolboxAndLog("custom.inspector", "inspector");
await reloadInspectorAndLog("custom", toolbox);
await selectNodeWithManyRulesAndLog(toolbox);
await closeToolboxAndLog("custom.inspector", toolbox);
await testTeardown();
};
/**
* Measure the time necessary to select a node and display the rule view when many rules
* match the element.
*/
async function selectNodeWithManyRulesAndLog(toolbox) {
let inspector = toolbox.getPanel("inspector");
// Local helper to select a node front and wait for the ruleview to be refreshed.
let selectNodeFront = (nodeFront) => {
let onRuleViewRefreshed = inspector.once("rule-view-refreshed");
inspector.selection.setNodeFront(nodeFront);
return onRuleViewRefreshed;
};
let initialNodeFront = inspector.selection.nodeFront;
// Retrieve the node front for the test node.
let root = await inspector.walker.getRootNode();
let referenceNodeFront = await inspector.walker.querySelector(root, ".no-css-rules");
let testNodeFront = await inspector.walker.querySelector(root, ".many-css-rules");
// Select test node and measure the time to display the rule view with many rules.
dump("Selecting .many-css-rules test node front\n");
let test = runTest("custom.inspector.manyrules.selectnode");
await selectNodeFront(testNodeFront);
test.done();
// Select reference node and measure the time to empty the rule view.
dump("Move the selection to a node with no rules\n");
test = runTest("custom.inspector.manyrules.deselectnode");
await selectNodeFront(referenceNodeFront);
test.done();
await selectNodeFront(initialNodeFront);
}

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

@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { reloadPageAndLog } = require("chrome://damp/content/tests/head");
exports.reloadInspectorAndLog = async function(label, toolbox) {
let onReload = async function() {
let inspector = toolbox.getPanel("inspector");
// First wait for markup view to be loaded against the new root node
await inspector.once("new-root");
// Then wait for inspector to be updated
await inspector.once("inspector-updated");
};
await reloadPageAndLog(label + ".inspector", toolbox, onReload);
};

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

@ -0,0 +1,52 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Services = require("Services");
const { openToolbox, closeToolbox, runTest, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
let tab = await testSetup(SIMPLE_URL);
let messageManager = tab.linkedBrowser.messageManager;
// Backup current sidebar tab preference
let sidebarTab = Services.prefs.getCharPref("devtools.inspector.activeSidebar");
// Set layoutview as the current inspector sidebar tab.
Services.prefs.setCharPref("devtools.inspector.activeSidebar", "layoutview");
// Setup test page. It is a simple page containing 5000 regular nodes and 10 grid
// containers.
await new Promise(resolve => {
messageManager.addMessageListener("setup-test-done", resolve);
const NODES = 5000;
const GRID_NODES = 10;
messageManager.loadFrameScript("data:,(" + encodeURIComponent(
`function () {
let div = content.document.createElement("div");
div.innerHTML =
new Array(${NODES}).join("<div></div>") +
new Array(${GRID_NODES}).join("<div style='display:grid'></div>");
content.document.body.appendChild(div);
sendSyncMessage("setup-test-done");
}`
) + ")()", false);
});
// Record the time needed to open the toolbox.
let test = runTest("inspector.layout.open");
await openToolbox("inspector");
test.done();
await closeToolbox();
// Restore sidebar tab preference.
Services.prefs.setCharPref("devtools.inspector.activeSidebar", sidebarTab);
await testTeardown();
};

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

@ -0,0 +1,63 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolbox, closeToolbox, runTest, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
/**
* Measure the time necessary to perform successive childList mutations in the content
* page and update the markup-view accordingly.
*/
module.exports = async function() {
let tab = await testSetup(SIMPLE_URL);
let messageManager = tab.linkedBrowser.messageManager;
let toolbox = await openToolbox("inspector");
let inspector = toolbox.getPanel("inspector");
// Test with n=LIMIT mutations, with t=DELAY ms between each one.
const LIMIT = 100;
const DELAY = 5;
messageManager.loadFrameScript("data:,(" + encodeURIComponent(
`function () {
const LIMIT = ${LIMIT};
addMessageListener("start-mutations-test", function () {
let addElement = function(index) {
if (index == LIMIT) {
// LIMIT was reached, stop adding elements.
return;
}
let div = content.document.createElement("div");
content.document.body.appendChild(div);
content.setTimeout(() => addElement(index + 1), ${DELAY});
};
addElement(0);
});
}`
) + ")()", false);
let test = runTest("inspector.mutations");
await new Promise(resolve => {
let childListMutationsCounter = 0;
inspector.on("markupmutation", (evt, mutations) => {
let childListMutations = mutations.filter(m => m.type === "childList");
childListMutationsCounter += childListMutations.length;
if (childListMutationsCounter === LIMIT) {
// Wait until we received exactly n=LIMIT mutations in the markup view.
resolve();
}
});
messageManager.sendAsyncMessage("start-mutations-test");
});
test.done();
await closeToolbox();
await testTeardown();
};

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

@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { reloadInspectorAndLog } = require("chrome://damp/content/tests/inspector/inspector-helpers");
const { openToolboxAndLog, closeToolboxAndLog, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(SIMPLE_URL);
let toolbox = await openToolboxAndLog("simple.inspector", "inspector");
await reloadInspectorAndLog("simple", toolbox);
await closeToolboxAndLog("simple.inspector", toolbox);
await testTeardown();
};

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

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
const { saveHeapSnapshot, readHeapSnapshot, takeCensus } = require("chrome://damp/content/tests/memory/memory-helpers");
module.exports = async function() {
await testSetup(COMPLICATED_URL);
const toolbox = await openToolboxAndLog("complicated.memory", "memory");
await reloadPageAndLog("complicated.memory", toolbox);
let heapSnapshotFilePath = await saveHeapSnapshot("complicated");
let snapshot = await readHeapSnapshot("complicated", heapSnapshotFilePath);
await takeCensus("complicated", snapshot);
await closeToolboxAndLog("complicated.memory", toolbox);
await testTeardown();
};

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

@ -0,0 +1,58 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { getToolbox, runTest } = require("chrome://damp/content/tests/head");
exports.saveHeapSnapshot = async function(label) {
let toolbox = getToolbox();
let panel = toolbox.getCurrentPanel();
let memoryFront = panel.panelWin.gFront;
let test = runTest(label + ".saveHeapSnapshot");
let heapSnapshotFilePath = await memoryFront.saveHeapSnapshot();
test.done();
return heapSnapshotFilePath;
};
exports.readHeapSnapshot = function(label, snapshotFilePath) {
const ChromeUtils = require("ChromeUtils");
let test = runTest(label + ".readHeapSnapshot");
let snapshot = ChromeUtils.readHeapSnapshot(snapshotFilePath);
test.done();
return Promise.resolve(snapshot);
};
exports.takeCensus = function(label, snapshot) {
let test = runTest("complicated.takeCensus");
snapshot.takeCensus({
breakdown: {
by: "coarseType",
objects: {
by: "objectClass",
then: { by: "count", bytes: true, count: true },
other: { by: "count", bytes: true, count: true }
},
strings: {
by: "internalType",
then: { by: "count", bytes: true, count: true }
},
scripts: {
by: "internalType",
then: { by: "count", bytes: true, count: true }
},
other: {
by: "internalType",
then: { by: "count", bytes: true, count: true }
}
}
});
test.done();
return Promise.resolve();
};

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

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
const { saveHeapSnapshot, readHeapSnapshot, takeCensus } = require("chrome://damp/content/tests/memory/memory-helpers");
module.exports = async function() {
await testSetup(SIMPLE_URL);
const toolbox = await openToolboxAndLog("simple.memory", "memory");
await reloadPageAndLog("simple.memory", toolbox);
let heapSnapshotFilePath = await saveHeapSnapshot("simple");
let snapshot = await readHeapSnapshot("simple", heapSnapshotFilePath);
await takeCensus("simple", snapshot);
await closeToolboxAndLog("simple.memory", toolbox);
await testTeardown();
};

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

@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
const { exportHar, waitForNetworkRequests } = require("chrome://damp/content/tests/netmonitor/netmonitor-helpers");
const EXPECTED_REQUESTS = 280;
module.exports = async function() {
await testSetup(COMPLICATED_URL);
const toolbox = await openToolboxAndLog("complicated.netmonitor", "netmonitor");
const requestsDone = waitForNetworkRequests("complicated.netmonitor", toolbox,
EXPECTED_REQUESTS);
await reloadPageAndLog("complicated.netmonitor", toolbox);
await requestsDone;
await exportHar("complicated.netmonitor", toolbox);
await closeToolboxAndLog("complicated.netmonitor", toolbox);
await testTeardown();
};

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

@ -0,0 +1,73 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { EVENTS } = require("devtools/client/netmonitor/src/constants");
const { getToolbox, runTest } = require("chrome://damp/content/tests/head");
/**
* Start monitoring all incoming update events about network requests and wait until
* a complete info about all requests is received. (We wait for the timings info
* explicitly, because that's always the last piece of information that is received.)
*
* This method is designed to wait for network requests that are issued during a page
* load, when retrieving page resources (scripts, styles, images). It has certain
* assumptions that can make it unsuitable for other types of network communication:
* - it waits for at least one network request to start and finish before returning
* - it waits only for request that were issued after it was called. Requests that are
* already in mid-flight will be ignored.
* - the request start and end times are overlapping. If a new request starts a moment
* after the previous one was finished, the wait will be ended in the "interim"
* period.
* @returns a promise that resolves when the wait is done.
*/
function waitForAllRequestsFinished(expectedRequests) {
let toolbox = getToolbox();
let window = toolbox.getCurrentPanel().panelWin;
return new Promise(resolve => {
// Explicitly waiting for specific number of requests arrived
let payloadReady = 0;
let timingsUpdated = 0;
function onPayloadReady(_, id) {
payloadReady++;
maybeResolve();
}
function onTimingsUpdated(_, id) {
timingsUpdated++;
maybeResolve();
}
function maybeResolve() {
// Have all the requests finished yet?
if (payloadReady >= expectedRequests && timingsUpdated >= expectedRequests) {
// All requests are done - unsubscribe from events and resolve!
window.off(EVENTS.PAYLOAD_READY, onPayloadReady);
window.off(EVENTS.RECEIVED_EVENT_TIMINGS, onTimingsUpdated);
resolve();
}
}
window.on(EVENTS.PAYLOAD_READY, onPayloadReady);
window.on(EVENTS.RECEIVED_EVENT_TIMINGS, onTimingsUpdated);
});
}
exports.waitForNetworkRequests = async function(label, toolbox, expectedRequests) {
let test = runTest(label + ".requestsFinished.DAMP");
await waitForAllRequestsFinished(expectedRequests);
test.done();
};
exports.exportHar = async function(label, toolbox) {
let test = runTest(label + ".exportHar");
// Export HAR from the Network panel.
await toolbox.getHARFromNetMonitor();
test.done();
};

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

@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
const { exportHar, waitForNetworkRequests } = require("chrome://damp/content/tests/netmonitor/netmonitor-helpers");
const EXPECTED_REQUESTS = 1;
module.exports = async function() {
await testSetup(SIMPLE_URL);
const toolbox = await openToolboxAndLog("simple.netmonitor", "netmonitor");
const requestsDone = waitForNetworkRequests("simple.netmonitor", toolbox,
EXPECTED_REQUESTS);
await reloadPageAndLog("simple.netmonitor", toolbox);
await requestsDone;
await exportHar("simple.netmonitor", toolbox);
await closeToolboxAndLog("simple.netmonitor", toolbox);
await testTeardown();
};

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

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(COMPLICATED_URL);
const toolbox = await openToolboxAndLog("complicated.performance", "performance");
await reloadPageAndLog("complicated.performance", toolbox);
await closeToolboxAndLog("complicated.performance", toolbox);
await testTeardown();
};

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

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(SIMPLE_URL);
const toolbox = await openToolboxAndLog("simple.performance", "performance");
await reloadPageAndLog("simple.performance", toolbox);
await closeToolboxAndLog("simple.performance", toolbox);
await testTeardown();
};

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

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(COMPLICATED_URL);
const toolbox = await openToolboxAndLog("complicated.styleeditor", "styleeditor");
await reloadPageAndLog("complicated.styleeditor", toolbox);
await closeToolboxAndLog("complicated.styleeditor", toolbox);
await testTeardown();
};

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

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, reloadPageAndLog, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(SIMPLE_URL);
const toolbox = await openToolboxAndLog("simple.styleeditor", "styleeditor");
await reloadPageAndLog("simple.styleeditor", toolbox);
await closeToolboxAndLog("simple.styleeditor", toolbox);
await testTeardown();
};

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

@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { EVENTS } = require("devtools/client/netmonitor/src/constants");
const { openToolbox, closeToolbox, reloadPageAndLog, testSetup,
testTeardown, PAGES_BASE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
await testSetup(PAGES_BASE_URL + "custom/panels-in-background/index.html");
// Make sure the Console and Network panels are initialized
let toolbox = await openToolbox("webconsole");
let monitor = await toolbox.selectTool("netmonitor");
// Select the options panel to make both the Console and Network
// panel be in background.
// Options panel should not do anything on page reload.
await toolbox.selectTool("options");
// Reload the page and wait for all HTTP requests
// to finish (1 doc + 600 XHRs).
let payloadReady = waitForPayload(601, monitor.panelWin);
await reloadPageAndLog("panelsInBackground", toolbox);
await payloadReady;
await closeToolbox();
await testTeardown();
};
function waitForPayload(count, panelWin) {
return new Promise(resolve => {
let payloadReady = 0;
function onPayloadReady(_, id) {
payloadReady++;
maybeResolve();
}
function maybeResolve() {
if (payloadReady >= count) {
panelWin.off(EVENTS.PAYLOAD_READY, onPayloadReady);
resolve();
}
}
panelWin.on(EVENTS.PAYLOAD_READY, onPayloadReady);
});
}

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

@ -0,0 +1,52 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolbox, closeToolbox, getBrowserWindow, runTest, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
let TOTAL_MESSAGES = 10;
let tab = await testSetup(SIMPLE_URL);
let messageManager = tab.linkedBrowser.messageManager;
let toolbox = await openToolbox("webconsole");
let webconsole = toolbox.getPanel("webconsole");
// Resolve once the last message has been received.
let allMessagesReceived = new Promise(resolve => {
function receiveMessages(messages) {
for (let m of messages) {
if (m.node.textContent.includes("damp " + TOTAL_MESSAGES)) {
webconsole.hud.ui.off("new-messages", receiveMessages);
// Wait for the console to redraw
getBrowserWindow().requestAnimationFrame(resolve);
}
}
}
webconsole.hud.ui.on("new-messages", receiveMessages);
});
// Load a frame script using a data URI so we can do logs
// from the page. So this is running in content.
messageManager.loadFrameScript("data:,(" + encodeURIComponent(
`function () {
addMessageListener("do-logs", function () {
for (var i = 0; i < ${TOTAL_MESSAGES}; i++) {
content.console.log('damp', i+1, content);
}
});
}`
) + ")()", true);
// Kick off the logging
messageManager.sendAsyncMessage("do-logs");
let test = runTest("console.bulklog");
await allMessagesReceived;
test.done();
await closeToolbox();
await testTeardown();
};

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

@ -0,0 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, testSetup,
testTeardown, COMPLICATED_URL } = require("chrome://damp/content/tests/head");
const { reloadConsoleAndLog } = require("chrome://damp/content/tests/webconsole/webconsole-helpers");
const EXPECTED_MESSAGES = 7;
module.exports = async function() {
await testSetup(COMPLICATED_URL);
let toolbox = await openToolboxAndLog("complicated.webconsole", "webconsole");
await reloadConsoleAndLog("complicated", toolbox, EXPECTED_MESSAGES);
await closeToolboxAndLog("complicated.webconsole", toolbox);
await testTeardown();
};

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

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, testSetup,
testTeardown, PAGES_BASE_URL } = require("chrome://damp/content/tests/head");
const { reloadConsoleAndLog } = require("chrome://damp/content/tests/webconsole/webconsole-helpers");
module.exports = async function() {
// These numbers controls the number of console api calls we do in the test
let sync = 250, stream = 250, async = 250;
let params = `?sync=${sync}&stream=${stream}&async=${async}`;
let url = PAGES_BASE_URL + "custom/console/index.html" + params;
await testSetup(url);
let toolbox = await openToolboxAndLog("custom.webconsole", "webconsole");
await reloadConsoleAndLog("custom", toolbox, sync + stream + async);
await closeToolboxAndLog("custom.webconsole", toolbox);
await testTeardown();
};

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

@ -0,0 +1,68 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolbox, closeToolboxAndLog, getBrowserWindow, runTest, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
module.exports = async function() {
let tab = await testSetup(SIMPLE_URL);
let messageManager = tab.linkedBrowser.messageManager;
let toolbox = await openToolbox("webconsole");
let webconsole = toolbox.getPanel("webconsole");
// Resolve once the first message is received.
let onMessageReceived = new Promise(resolve => {
function receiveMessages(messages) {
for (let m of messages) {
resolve(m);
}
}
webconsole.hud.ui.once("new-messages", receiveMessages);
});
// Load a frame script using a data URI so we can do logs
// from the page.
messageManager.loadFrameScript("data:,(" + encodeURIComponent(
`function () {
addMessageListener("do-dir", function () {
content.console.dir(Array.from({length:1000}).reduce((res, _, i)=> {
res["item_" + i] = i;
return res;
}, {}));
});
}`
) + ")()", true);
// Kick off the logging
messageManager.sendAsyncMessage("do-dir");
let test = runTest("console.objectexpand");
await onMessageReceived;
const tree = webconsole.hud.ui.outputNode.querySelector(".dir.message .tree");
// The tree can be collapsed since the properties are fetched asynchronously.
if (tree.querySelectorAll(".node").length === 1) {
// If this is the case, we wait for the properties to be fetched and displayed.
await new Promise(resolve => {
const observer = new (getBrowserWindow().MutationObserver)(mutations => {
resolve(mutations);
observer.disconnect();
});
observer.observe(tree, {
childList: true
});
});
}
test.done();
await closeToolboxAndLog("console.objectexpanded", toolbox);
await testTeardown();
};

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

@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolbox, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
const TOTAL_MESSAGES = 100;
module.exports = async function() {
let tab = await testSetup(SIMPLE_URL);
// Load a frame script using a data URI so we can do logs
// from the page. So this is running in content.
tab.linkedBrowser.messageManager.loadFrameScript("data:,(" + encodeURIComponent(`
function () {
for (var i = 0; i < ${TOTAL_MESSAGES}; i++) {
content.console.log('damp', i+1, content);
}
}`
) + ")()", true);
await openToolboxAndLog("console.openwithcache", "webconsole");
await closeToolbox();
await testTeardown();
};

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

@ -0,0 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolboxAndLog, closeToolboxAndLog, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
const { reloadConsoleAndLog } = require("chrome://damp/content/tests/webconsole/webconsole-helpers");
const EXPECTED_MESSAGES = 1;
module.exports = async function() {
await testSetup(SIMPLE_URL);
let toolbox = await openToolboxAndLog("simple.webconsole", "webconsole");
await reloadConsoleAndLog("simple", toolbox, EXPECTED_MESSAGES);
await closeToolboxAndLog("simple.webconsole", toolbox);
await testTeardown();
};

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

@ -0,0 +1,55 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { openToolbox, closeToolbox, logTestResult, testSetup,
testTeardown, SIMPLE_URL } = require("chrome://damp/content/tests/head");
// Log a stream of console messages, 1 per rAF. Then record the average
// time per rAF. The idea is that the console being slow can slow down
// content (i.e. Bug 1237368).
module.exports = async function() {
let TOTAL_MESSAGES = 100;
let tab = await testSetup(SIMPLE_URL);
let messageManager = tab.linkedBrowser.messageManager;
await openToolbox("webconsole");
// Load a frame script using a data URI so we can do logs
// from the page. So this is running in content.
messageManager.loadFrameScript("data:,(" + encodeURIComponent(
`function () {
let count = 0;
let startTime = content.performance.now();
function log() {
if (++count < ${TOTAL_MESSAGES}) {
content.document.querySelector("h1").textContent += count + "\\n";
content.console.log('damp', count,
content,
content.document,
content.document.body,
content.document.documentElement,
new Array(100).join(" DAMP? DAMP! "));
content.requestAnimationFrame(log);
} else {
let avgTime = (content.performance.now() - startTime) / ${TOTAL_MESSAGES};
sendSyncMessage("done", Math.round(avgTime));
}
}
log();
}`
) + ")()", true);
let avgTime = await new Promise(resolve => {
messageManager.addMessageListener("done", (e) => {
resolve(e.data);
});
});
logTestResult("console.streamlog", avgTime);
await closeToolbox();
await testTeardown();
};

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

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { reloadPageAndLog } = require("chrome://damp/content/tests/head");
exports.reloadConsoleAndLog = async function(label, toolbox, expectedMessages) {
let onReload = async function() {
let webconsole = toolbox.getPanel("webconsole");
await new Promise(done => {
let messages = 0;
let receiveMessages = () => {
if (++messages == expectedMessages) {
webconsole.hud.ui.off("new-messages", receiveMessages);
done();
}
};
webconsole.hud.ui.on("new-messages", receiveMessages);
});
};
await reloadPageAndLog(label + ".webconsole", toolbox, onReload);
};