Bug 1154874 - Add a debugger-specific DAMP test for Talos [New Frontend] r=ochameau

MozReview-Commit-ID: HbVgCVPPlYw

--HG--
extra : rebase_source : 7c92a910aeae76e133fe8862b559d60c2cfbd737
This commit is contained in:
yulia 2018-02-28 11:11:21 +01:00
parent 14627be8a8
commit 5966e7cd7b
7 changed files with 190 additions and 30 deletions

View file

@ -378,6 +378,7 @@ testing/talos/talos/scripts/jszip.min.js
testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js
testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js
testing/talos/talos/tests/canvasmark/** testing/talos/talos/tests/canvasmark/**
testing/talos/talos/tests/devtools/addon/content/pages/**
testing/talos/talos/tests/dromaeo/** testing/talos/talos/tests/dromaeo/**
testing/talos/talos/tests/v8_7/** testing/talos/talos/tests/v8_7/**
testing/talos/talos/tests/kraken/** testing/talos/talos/tests/kraken/**

View file

@ -57,15 +57,21 @@ const DEBUGGER_POLLING_INTERVAL = 50;
const debuggerHelper = { const debuggerHelper = {
waitForState(dbg, predicate, msg) { waitForState(dbg, predicate, msg) {
return new Promise(resolve => { return new Promise(resolve => {
dump(`Waiting for state change: ${msg}\n`); if (msg) {
dump(`Waiting for state change: ${msg}\n`);
}
if (predicate(dbg.store.getState())) { if (predicate(dbg.store.getState())) {
dump(`Finished waiting for state change: ${msg}\n`); if (msg) {
dump(`Finished waiting for state change: ${msg}\n`);
}
return resolve(); return resolve();
} }
const unsubscribe = dbg.store.subscribe(() => { const unsubscribe = dbg.store.subscribe(() => {
if (predicate(dbg.store.getState())) { if (predicate(dbg.store.getState())) {
dump(`Finished waiting for state change: ${msg}\n`); if (msg) {
dump(`Finished waiting for state change: ${msg}\n`);
}
unsubscribe(); unsubscribe();
resolve(); resolve();
} }
@ -94,12 +100,16 @@ const debuggerHelper = {
}, },
async waitUntil(predicate, msg) { async waitUntil(predicate, msg) {
dump(`Waiting until: ${msg}\n`); if (msg) {
dump(`Waiting until: ${msg}\n`);
}
return new Promise(resolve => { return new Promise(resolve => {
const timer = setInterval(() => { const timer = setInterval(() => {
if (predicate()) { if (predicate()) {
clearInterval(timer); clearInterval(timer);
dump(`Finished Waiting until: ${msg}\n`); if (msg) {
dump(`Finished Waiting until: ${msg}\n`);
}
resolve(); resolve();
} }
}, DEBUGGER_POLLING_INTERVAL); }, DEBUGGER_POLLING_INTERVAL);
@ -184,6 +194,92 @@ const debuggerHelper = {
}, },
"selected source" "selected source"
); );
},
async addBreakpoint(dbg, line, url) {
dump(`add breakpoint\n`);
const source = this.findSource(dbg, url);
const location = {
sourceId: source.get("id"),
line,
column: 0
};
const onDispatched = debuggerHelper.waitForDispatch(dbg, "ADD_BREAKPOINT");
dbg.actions.addBreakpoint(location);
return onDispatched;
},
async removeBreakpoints(dbg, line, url) {
dump(`remove all breakpoints\n`);
const breakpoints = dbg.selectors.getBreakpoints(dbg.getState());
const onBreakpointsCleared = this.waitForState(
dbg,
state => !dbg.selectors.getBreakpoints(state).length
);
await dbg.actions.removeBreakpoints(breakpoints);
return onBreakpointsCleared;
},
async pauseDebugger(dbg, tab, testFunction, { line, file }) {
await this.addBreakpoint(dbg, line, file);
const onPaused = this.waitForPaused(dbg);
await this.evalInContent(dbg, tab, testFunction);
return onPaused;
},
async waitForPaused(dbg) {
const onLoadedScope = this.waitForLoadedScopes(dbg);
const onStateChange = this.waitForState(
dbg,
state => {
return dbg.selectors.getSelectedScope(state) && dbg.selectors.isPaused(state);
},
);
return Promise.all([onLoadedScope, onStateChange]);
},
async resume(dbg) {
const onResumed = this.waitForResumed(dbg);
dbg.actions.resume();
return onResumed;
},
async waitForResumed(dbg) {
return this.waitForState(
dbg,
state => !dbg.selectors.isPaused(state)
);
},
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 waitForElement(dbg, name) {
await this.waitUntil(() => dbg.win.document.querySelector(name));
return dbg.win.document.querySelector(name);
},
async waitForLoadedScopes(dbg) {
const element = ".scopes-list .tree-node[aria-level=\"1\"]";
return this.waitForElement(dbg, element);
},
async step(dbg, stepType) {
const resumed = this.waitForResumed(dbg);
dbg.actions[stepType]();
await resumed;
return this.waitForPaused(dbg);
} }
}; };
@ -814,7 +910,7 @@ async _consoleOpenWithCachedMessagesTest() {
await selectNodeFront(initialNodeFront); await selectNodeFront(initialNodeFront);
}, },
async openDebuggerAndLog(label, expectedSources, selectedFile, expectedText) { async openDebuggerAndLog(label, { expectedSources, selectedFile, expectedText }) {
const onLoad = async (toolbox, panel) => { const onLoad = async (toolbox, panel) => {
const dbg = await debuggerHelper.createContext(panel); const dbg = await debuggerHelper.createContext(panel);
await debuggerHelper.waitForSources(dbg, expectedSources); await debuggerHelper.waitForSources(dbg, expectedSources);
@ -826,7 +922,61 @@ async _consoleOpenWithCachedMessagesTest() {
return toolbox; return toolbox;
}, },
async reloadDebuggerAndLog(label, toolbox, expectedSources, selectedFile, expectedText) { async pauseDebuggerAndLog(tab, toolbox, { testFunction }) {
const panel = await toolbox.getPanelWhenReady("jsdebugger");
const dbg = await debuggerHelper.createContext(panel);
const pauseLocation = { line: 22, file: "App.js" };
dump("Pausing debugger\n");
let test = this.runTest("custom.jsdebugger.pause.DAMP");
await debuggerHelper.pauseDebugger(dbg, tab, testFunction, pauseLocation);
test.done();
await debuggerHelper.removeBreakpoints(dbg);
await debuggerHelper.resume(dbg);
await garbageCollect();
},
async stepDebuggerAndLog(tab, toolbox, { testFunction }) {
const panel = await toolbox.getPanelWhenReady("jsdebugger");
const dbg = await debuggerHelper.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 debuggerHelper.pauseDebugger(dbg, tab, testFunction, stepTest.location);
const test = this.runTest(`custom.jsdebugger.${stepTest.key}.DAMP`);
for (let i = 0; i < stepCount; i++) {
await debuggerHelper.step(dbg, stepTest.key);
}
test.done();
await debuggerHelper.removeBreakpoints(dbg);
await debuggerHelper.resume(dbg);
await garbageCollect();
}
},
async reloadDebuggerAndLog(label, toolbox, { expectedSources, selectedFile, expectedText }) {
const onReload = async () => { const onReload = async () => {
const panel = await toolbox.getPanelWhenReady("jsdebugger"); const panel = await toolbox.getPanelWhenReady("jsdebugger");
const dbg = await debuggerHelper.createContext(panel); const dbg = await debuggerHelper.createContext(panel);
@ -840,13 +990,22 @@ async _consoleOpenWithCachedMessagesTest() {
async customDebugger() { async customDebugger() {
const label = "custom"; const label = "custom";
const expectedSources = 7;
let url = CUSTOM_URL.replace(/\$TOOL/, "debugger"); let url = CUSTOM_URL.replace(/\$TOOL/, "debugger");
await this.testSetup(url);
const selectedFile = "App.js"; const tab = await this.testSetup(url);
const expectedText = "import React, { Component } from 'react';"; const debuggerTestData = {
const toolbox = await this.openDebuggerAndLog(label, expectedSources, selectedFile, expectedText); expectedSources: 7,
await this.reloadDebuggerAndLog(label, toolbox, expectedSources, selectedFile, expectedText); testFunction: "window.hitBreakpoint()",
selectedFile: "App.js",
expectedText: "import React, { Component } from 'react';"
};
const toolbox = await this.openDebuggerAndLog(label, debuggerTestData);
await this.reloadDebuggerAndLog(label, toolbox, debuggerTestData);
// these tests are only run on custom.jsdebugger
await this.pauseDebuggerAndLog(tab, toolbox, debuggerTestData);
await this.stepDebuggerAndLog(tab, toolbox, debuggerTestData);
await this.closeToolboxAndLog("custom.jsdebugger", toolbox); await this.closeToolboxAndLog("custom.jsdebugger", toolbox);
await this.testTeardown(); await this.testTeardown();
}, },
@ -883,9 +1042,7 @@ async _consoleOpenWithCachedMessagesTest() {
_getToolLoadingTests(url, label, { _getToolLoadingTests(url, label, {
expectedMessages, expectedMessages,
expectedRequests, expectedRequests,
expectedSources, debuggerTestData
selectedFile,
expectedText,
}) { }) {
let tests = { let tests = {
async inspector() { async inspector() {
@ -906,8 +1063,8 @@ async _consoleOpenWithCachedMessagesTest() {
async debugger() { async debugger() {
await this.testSetup(url); await this.testSetup(url);
let toolbox = await this.openDebuggerAndLog(label, expectedSources, selectedFile, expectedText); let toolbox = await this.openDebuggerAndLog(label, debuggerTestData);
await this.reloadDebuggerAndLog(label, toolbox, expectedSources, selectedFile, expectedText); await this.reloadDebuggerAndLog(label, toolbox, debuggerTestData);
await this.closeToolboxAndLog(label + ".jsdebugger", toolbox); await this.closeToolboxAndLog(label + ".jsdebugger", toolbox);
await this.testTeardown(); await this.testTeardown();
}, },
@ -1137,18 +1294,22 @@ async _consoleOpenWithCachedMessagesTest() {
Object.assign(tests, this._getToolLoadingTests(SIMPLE_URL, "simple", { Object.assign(tests, this._getToolLoadingTests(SIMPLE_URL, "simple", {
expectedMessages: 1, expectedMessages: 1,
expectedRequests: 1, expectedRequests: 1,
expectedSources: 1, debuggerTestData: {
selectedFile: "simple.html", expectedSources: 1,
expectedText: "This is a simple page" selectedFile: "simple.html",
expectedText: "This is a simple page"
}
})); }));
// Run all tests against "complicated" document // Run all tests against "complicated" document
Object.assign(tests, this._getToolLoadingTests(COMPLICATED_URL, "complicated", { Object.assign(tests, this._getToolLoadingTests(COMPLICATED_URL, "complicated", {
expectedMessages: 7, expectedMessages: 7,
expectedRequests: 280, expectedRequests: 280,
expectedSources: 14, debuggerTestData: {
selectedFile: "ga.js", expectedSources: 14,
expectedText: "Math;function ga(a,b){return a.name=b}" selectedFile: "ga.js",
expectedText: "Math;function ga(a,b){return a.name=b}"
}
})); }));
// Run all tests against a document specific to each tool // Run all tests against a document specific to each tool
@ -1189,7 +1350,6 @@ async _consoleOpenWithCachedMessagesTest() {
if (!config.subtests[i] || !tests[config.subtests[i]]) { if (!config.subtests[i] || !tests[config.subtests[i]]) {
continue; continue;
} }
sequenceArray.push(tests[config.subtests[i]]); sequenceArray.push(tests[config.subtests[i]]);
} }
} }

View file

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="./manifest.json"><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="./static/js/main.447c224f.js"></script></body></html> <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="./manifest.json"><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="./static/js/main.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long