зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1648545: Part 3 - Support Assert in SpecialPowers.spawn for xpcshell tests. r=ahal
Differential Revision: https://phabricator.services.mozilla.com/D119450
This commit is contained in:
Родитель
1abe5de918
Коммит
05d13811b2
|
@ -88,7 +88,7 @@ async function ensureDataCleanup() {
|
|||
// resulting install invocation. The installation's call to importScripts when evaluated
|
||||
// will load the script directly out of the Cache API.
|
||||
function testSWUpdate(contentPage) {
|
||||
return contentPage.spawn([], async () => {
|
||||
return contentPage.legacySpawn([], async () => {
|
||||
const oldReg = await this.content.navigator.serviceWorker.ready;
|
||||
const reg = await oldReg.update();
|
||||
const sw = reg.installing || reg.waiting || reg.active;
|
||||
|
@ -178,7 +178,7 @@ add_task(async function test_extension_invalid_sw_scripts_redirect_ignored() {
|
|||
// Register the worker while the test extension isn't loaded and cannot
|
||||
// intercept and redirect the importedScripts requests.
|
||||
info("Register service worker from a content webpage");
|
||||
let workerMessage = await contentPage.spawn([], async () => {
|
||||
let workerMessage = await contentPage.legacySpawn([], async () => {
|
||||
const reg = await this.content.navigator.serviceWorker.register("/sw.js");
|
||||
return new Promise(resolve => {
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
|
@ -281,7 +281,7 @@ add_task(async function test_filter_sw_script() {
|
|||
"http://localhost/page.html"
|
||||
);
|
||||
|
||||
let workerMessage = await contentPage.spawn([], async () => {
|
||||
let workerMessage = await contentPage.legacySpawn([], async () => {
|
||||
const reg = await this.content.navigator.serviceWorker.register("/sw.js");
|
||||
return new Promise(resolve => {
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
|
@ -349,7 +349,7 @@ add_task(async function test_extension_redirect_sw_imported_script() {
|
|||
|
||||
// Register the worker while the test extension isn't loaded and cannot
|
||||
// intercept and redirect the importedScripts requests.
|
||||
let workerMessage = await contentPage.spawn([], async () => {
|
||||
let workerMessage = await contentPage.legacySpawn([], async () => {
|
||||
const reg = await this.content.navigator.serviceWorker.register("/sw.js");
|
||||
return new Promise(resolve => {
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
extends: ["plugin:mozilla/xpcshell-test"],
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: "*.html",
|
||||
env: { browser: true },
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,139 @@
|
|||
"use strict";
|
||||
|
||||
/* eslint-disable @microsoft/sdl/no-insecure-url */
|
||||
|
||||
const { XPCShellContentUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/XPCShellContentUtils.jsm"
|
||||
);
|
||||
|
||||
XPCShellContentUtils.init(this);
|
||||
|
||||
const HTML = String.raw`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<span id="span">Hello there.</span>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const server = XPCShellContentUtils.createHttpServer({
|
||||
hosts: ["example.com", "example.org"],
|
||||
});
|
||||
|
||||
server.registerPathHandler("/", (request, response) => {
|
||||
response.setHeader("Content-Type", "text/html");
|
||||
response.write(HTML);
|
||||
});
|
||||
/**
|
||||
* Tests that the shared sandbox functionality for cross-process script
|
||||
* execution works as expected. In particular, ensures that Assert methods
|
||||
* report the correct diagnostics in the caller scope.
|
||||
*/
|
||||
|
||||
let scope = this;
|
||||
|
||||
async function interceptDiagnostics(func) {
|
||||
let originalRecord = scope.do_report_result;
|
||||
try {
|
||||
let diags = [];
|
||||
|
||||
scope.do_report_result = (passed, msg, stack) => {
|
||||
diags.push({ passed, msg, stack });
|
||||
};
|
||||
|
||||
await func();
|
||||
|
||||
return diags;
|
||||
} finally {
|
||||
scope.do_report_result = originalRecord;
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function () {
|
||||
const frameSrc = "http://example.com/";
|
||||
const subframeSrc = "http://example.org/";
|
||||
|
||||
let page = await XPCShellContentUtils.loadContentPage(frameSrc, {
|
||||
remote: true,
|
||||
remoteSubframes: true,
|
||||
});
|
||||
|
||||
let { SpecialPowers, browsingContext } = page;
|
||||
|
||||
let expected = [
|
||||
[false, "Thing - 1 == 2"],
|
||||
[true, "Hmm - 1 == 1"],
|
||||
[true, "Yay. - true == true"],
|
||||
[false, "Boo!. - false == true"],
|
||||
];
|
||||
|
||||
// Test that a representative variety of assertions work as expected, and
|
||||
// trigger the expected calls to the harness's reporting function.
|
||||
//
|
||||
// Note: Assert.sys.mjs has its own tests, and defers all of its reporting to a
|
||||
// single reporting function, so we don't need to test it comprehensively. We
|
||||
// just need to make sure that the general functionality works as expected.
|
||||
let tests = {
|
||||
"SpecialPowers.spawn": () => {
|
||||
return SpecialPowers.spawn(browsingContext, [], async () => {
|
||||
Assert.equal(1, 2, "Thing");
|
||||
Assert.equal(1, 1, "Hmm");
|
||||
Assert.ok(true, "Yay.");
|
||||
Assert.ok(false, "Boo!.");
|
||||
});
|
||||
},
|
||||
"SpecialPowers.spawn-subframe": () => {
|
||||
return SpecialPowers.spawn(browsingContext, [subframeSrc], async src => {
|
||||
let subFrame = this.content.document.createElement("iframe");
|
||||
subFrame.src = src;
|
||||
this.content.document.body.appendChild(subFrame);
|
||||
|
||||
await new Promise(resolve => {
|
||||
subFrame.addEventListener("load", resolve, { once: true });
|
||||
});
|
||||
|
||||
await SpecialPowers.spawn(subFrame, [], () => {
|
||||
Assert.equal(1, 2, "Thing");
|
||||
Assert.equal(1, 1, "Hmm");
|
||||
Assert.ok(true, "Yay.");
|
||||
Assert.ok(false, "Boo!.");
|
||||
});
|
||||
});
|
||||
},
|
||||
"SpecialPowers.spawnChrome": () => {
|
||||
return SpecialPowers.spawnChrome([], async () => {
|
||||
Assert.equal(1, 2, "Thing");
|
||||
Assert.equal(1, 1, "Hmm");
|
||||
Assert.ok(true, "Yay.");
|
||||
Assert.ok(false, "Boo!.");
|
||||
});
|
||||
},
|
||||
"SpecialPowers.loadChromeScript": async () => {
|
||||
let script = SpecialPowers.loadChromeScript(() => {
|
||||
/* eslint-env mozilla/chrome-script */
|
||||
this.addMessageListener("ping", () => "pong");
|
||||
|
||||
Assert.equal(1, 2, "Thing");
|
||||
Assert.equal(1, 1, "Hmm");
|
||||
Assert.ok(true, "Yay.");
|
||||
Assert.ok(false, "Boo!.");
|
||||
});
|
||||
|
||||
await script.sendQuery("ping");
|
||||
script.destroy();
|
||||
},
|
||||
};
|
||||
|
||||
for (let [name, func] of Object.entries(tests)) {
|
||||
info(`Starting task: ${name}`);
|
||||
|
||||
let diags = await interceptDiagnostics(func);
|
||||
|
||||
let results = diags.map(diag => [diag.passed, diag.msg]);
|
||||
|
||||
deepEqual(results, expected, "Got expected assertions");
|
||||
}
|
||||
});
|
|
@ -0,0 +1,68 @@
|
|||
"use strict";
|
||||
|
||||
const { XPCShellContentUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/XPCShellContentUtils.jsm"
|
||||
);
|
||||
|
||||
XPCShellContentUtils.init(this);
|
||||
|
||||
const HTML = String.raw`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<span id="span">Hello there.</span>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const server = XPCShellContentUtils.createHttpServer({
|
||||
hosts: ["example.com"],
|
||||
});
|
||||
|
||||
server.registerPathHandler("/", (request, response) => {
|
||||
response.setHeader("Content-Type", "text/html");
|
||||
response.write(HTML);
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
let page = await XPCShellContentUtils.loadContentPage("http://example.com/", {
|
||||
remote: true,
|
||||
remoteSubframes: true,
|
||||
});
|
||||
|
||||
let { SpecialPowers, browsingContext } = page;
|
||||
|
||||
let result = await SpecialPowers.spawn(
|
||||
browsingContext,
|
||||
["#span"],
|
||||
selector => {
|
||||
let elem = content.document.querySelector(selector);
|
||||
return elem.textContent;
|
||||
}
|
||||
);
|
||||
|
||||
equal(result, "Hello there.", "Got correct element text from frame");
|
||||
|
||||
let line = Components.stack.lineNumber + 1;
|
||||
let callback = () => {
|
||||
let e = new Error("Hello.");
|
||||
return { filename: e.fileName, lineNumber: e.lineNumber };
|
||||
};
|
||||
|
||||
let loc = await SpecialPowers.spawn(browsingContext, [], callback);
|
||||
equal(
|
||||
loc.filename,
|
||||
Components.stack.filename,
|
||||
"Error should have correct script filename"
|
||||
);
|
||||
equal(
|
||||
loc.lineNumber,
|
||||
line + 2,
|
||||
"Error should have correct script line number"
|
||||
);
|
||||
|
||||
await page.close();
|
||||
});
|
|
@ -0,0 +1,2 @@
|
|||
[test_SpecialPowersSandbox.js]
|
||||
[test_SpecialPowersSpawn.js]
|
|
@ -11,4 +11,5 @@ TESTING_JS_MODULES += [
|
|||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ["Harness_sanity/mochitest.ini"]
|
||||
XPCSHELL_TESTS_MANIFESTS += ["Harness_sanity/xpcshell.ini"]
|
||||
BROWSER_CHROME_MANIFESTS += ["browser/browser.ini"]
|
||||
|
|
|
@ -177,6 +177,10 @@ class ContentPage {
|
|||
|
||||
let chromeDoc = await promiseDocumentLoaded(chromeShell.document);
|
||||
|
||||
let { SpecialPowers } = chromeDoc.ownerGlobal;
|
||||
SpecialPowers.xpcshellScope = XPCShellContentUtils.currentScope;
|
||||
SpecialPowers.setAsDefaultAssertHandler();
|
||||
|
||||
let browser = chromeDoc.createXULElement("browser");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute("disableglobalhistory", "true");
|
||||
|
|
|
@ -311,7 +311,7 @@ export class SpecialPowersChild extends JSWindowActorChild {
|
|||
case "Assert":
|
||||
{
|
||||
if ("info" in message.data) {
|
||||
this.SimpleTest.info(message.data.info);
|
||||
(this.xpcshellScope || this.SimpleTest).info(message.data.info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -322,6 +322,8 @@ export class SpecialPowersChild extends JSWindowActorChild {
|
|||
if (SimpleTest) {
|
||||
let expected = expectFail ? "fail" : "pass";
|
||||
SimpleTest.record(passed, name, diag, stack, expected);
|
||||
} else if (this.xpcshellScope) {
|
||||
this.xpcshellScope.do_report_result(passed, name, stack);
|
||||
} else {
|
||||
// Well, this is unexpected.
|
||||
dump(name + "\n");
|
||||
|
@ -1585,7 +1587,9 @@ export class SpecialPowersChild extends JSWindowActorChild {
|
|||
args,
|
||||
task: String(task),
|
||||
caller: Cu.getFunctionSourceLocation(task),
|
||||
hasHarness: typeof this.SimpleTest === "object",
|
||||
hasHarness:
|
||||
typeof this.SimpleTest === "object" ||
|
||||
typeof this.xpcshellScope === "object",
|
||||
imports: this._spawnTaskImports,
|
||||
});
|
||||
}
|
||||
|
@ -1667,6 +1671,13 @@ export class SpecialPowersChild extends JSWindowActorChild {
|
|||
this._SimpleTest = val;
|
||||
}
|
||||
|
||||
get xpcshellScope() {
|
||||
return this._xpcshellScope;
|
||||
}
|
||||
set xpcshellScope(val) {
|
||||
this._xpcshellScope = val;
|
||||
}
|
||||
|
||||
async evictAllContentViewers() {
|
||||
if (Services.appinfo.sessionHistoryInParent) {
|
||||
await this.sendQuery("EvictAllContentViewers");
|
||||
|
|
|
@ -179,7 +179,7 @@ add_task(async function test_blob_url() {
|
|||
"http://example.org/empty"
|
||||
);
|
||||
|
||||
let blobUrl = await contentPage.spawn(null, async () => {
|
||||
let blobUrl = await contentPage.spawn([], async () => {
|
||||
// Create a third-party iframe and create a blob url in there.
|
||||
let f = this.content.document.createElement("iframe");
|
||||
f.src = "http://foo.com/iframe";
|
||||
|
|
|
@ -177,7 +177,7 @@ add_task(async function page_content_process() {
|
|||
"privilegedabout"
|
||||
);
|
||||
|
||||
await contentPage.spawn(PAGE_ICON_TEST_URLS, async URLS => {
|
||||
await contentPage.spawn([PAGE_ICON_TEST_URLS], async URLS => {
|
||||
// We expect each of these URLs to produce an error event when
|
||||
// we attempt to load them in this process type.
|
||||
/* global content */
|
||||
|
@ -218,7 +218,7 @@ add_task(async function page_privileged_about_content_process() {
|
|||
"privilegedabout"
|
||||
);
|
||||
|
||||
await contentPage.spawn(PAGE_ICON_TEST_URLS, async URLS => {
|
||||
await contentPage.spawn([PAGE_ICON_TEST_URLS], async URLS => {
|
||||
// We expect each of these URLs to load correctly in this process
|
||||
// type.
|
||||
for (let url of URLS) {
|
||||
|
@ -226,7 +226,7 @@ add_task(async function page_privileged_about_content_process() {
|
|||
img.src = url;
|
||||
let imgPromise = new Promise((resolve, reject) => {
|
||||
img.addEventListener("error", e => {
|
||||
Assert.ok(false, "Did not expect an error.");
|
||||
Assert.ok(false, "Did not expect an error. ");
|
||||
reject();
|
||||
});
|
||||
img.addEventListener("load", e => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче