153 lines
5.4 KiB
HTML
153 lines
5.4 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Test for SpecialPowers sandboxes</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
</head>
|
|
<body>
|
|
|
|
<iframe id="iframe"></iframe>
|
|
|
|
<script>
|
|
/**
|
|
* 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.
|
|
*/
|
|
|
|
/* globals SpecialPowers, Assert */
|
|
|
|
async function interceptDiagnostics(func) {
|
|
let originalRecord = SimpleTest.record;
|
|
try {
|
|
let diags = [];
|
|
|
|
SimpleTest.record = (condition, name, diag, stack) => {
|
|
diags.push({condition, name, diag, stack});
|
|
};
|
|
|
|
await func();
|
|
|
|
return diags;
|
|
} finally {
|
|
SimpleTest.record = originalRecord;
|
|
}
|
|
}
|
|
|
|
add_task(async function() {
|
|
const frameSrc = "https://example.com/tests/testing/mochitest/tests/Harness_sanity/file_spawn.html";
|
|
const subframeSrc = "https://example.org/tests/testing/mochitest/tests/Harness_sanity/file_spawn.html";
|
|
|
|
let frame = document.getElementById("iframe");
|
|
frame.src = frameSrc;
|
|
|
|
await new Promise(resolve => {
|
|
frame.addEventListener("load", resolve, {once: true});
|
|
});
|
|
|
|
let expected = [
|
|
[false, "Thing - 1 == 2", "got 1, expected 2 (operator ==)"],
|
|
[true, "Hmm - 1 == 1", undefined],
|
|
[true, "Yay. - true == true", undefined],
|
|
[false, "Boo!. - false == true", "got false, expected true (operator ==)"],
|
|
[false, "Missing expected exception Rej_bad", "got null, expected /./ (operator undefined)"],
|
|
[true, "Rej_ok", undefined],
|
|
];
|
|
|
|
// 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(frame, [], async () => {
|
|
Assert.equal(1, 2, "Thing");
|
|
Assert.equal(1, 1, "Hmm");
|
|
Assert.ok(true, "Yay.");
|
|
Assert.ok(false, "Boo!.");
|
|
await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
|
|
await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
|
|
});
|
|
},
|
|
"SpecialPowers.spawn-subframe": () => {
|
|
return SpecialPowers.spawn(frame, [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, [], async () => {
|
|
Assert.equal(1, 2, "Thing");
|
|
Assert.equal(1, 1, "Hmm");
|
|
Assert.ok(true, "Yay.");
|
|
Assert.ok(false, "Boo!.");
|
|
await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
|
|
await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
|
|
});
|
|
});
|
|
},
|
|
"SpecialPowers.spawnChrome": () => {
|
|
return SpecialPowers.spawnChrome([], async () => {
|
|
Assert.equal(1, 2, "Thing");
|
|
Assert.equal(1, 1, "Hmm");
|
|
Assert.ok(true, "Yay.");
|
|
Assert.ok(false, "Boo!.");
|
|
await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
|
|
await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
|
|
});
|
|
},
|
|
"SpecialPowers.loadChromeScript": async () => {
|
|
let script = SpecialPowers.loadChromeScript(() => {
|
|
/* eslint-env mozilla/chrome-script */
|
|
const resultPromise = (async () => {
|
|
Assert.equal(1, 2, "Thing");
|
|
Assert.equal(1, 1, "Hmm");
|
|
Assert.ok(true, "Yay.");
|
|
Assert.ok(false, "Boo!.");
|
|
await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
|
|
await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
|
|
})();
|
|
this.addMessageListener("ping", () => resultPromise);
|
|
});
|
|
|
|
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.condition, diag.name, diag.diag]);
|
|
|
|
isDeeply(results, expected, "Got expected assertions");
|
|
for (let { name: diagName, stack } of diags) {
|
|
ok(stack, `Got stack for: ${diagName}`);
|
|
// Unlike test_SpecialPowersSandbox.js, expectedFilenamePart does not end
|
|
// with ":" (separator between file name and line number). This is because
|
|
// xorigin tests run this test file with a query param ("currentTestURL"),
|
|
// and the name therefore looks like "test_SpecialPowersSandbox.html?...:"
|
|
// instead of "test_SpecialPowersSandbox.html:"
|
|
let expectedFilenamePart = "/test_SpecialPowersSandbox.html";
|
|
if (name === "SpecialPowers.loadChromeScript") {
|
|
// Unfortunately, the original file name is not included;
|
|
// the function name or a dummy value is used instead.
|
|
expectedFilenamePart = "loadChromeScript anonymous function>";
|
|
}
|
|
if (!stack.includes(expectedFilenamePart)) {
|
|
ok(false, `Stack does not contain ${expectedFilenamePart}: ${stack}`);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|