зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
24e313e7c7
Коммит
43ae2eade9
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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);
|
||||||
|
};
|
Загрузка…
Ссылка в новой задаче