Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tests scripting.executeScript() with allFrames:true or frameId option, edge cases</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";
let gRequestThrottlerExt = null;
async function throttleAllIframeLoads() {
is(gRequestThrottlerExt, null, "throttleAllIframeLoads - one at a time");
gRequestThrottlerExt = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["webRequest", "webRequestBlocking"],
host_permissions: ["*://*/*"],
},
background() {
let neverResolvingPromise = new Promise(() => {});
browser.webRequest.onBeforeRequest.addListener(
details => {
browser.test.log(`(Indefinitely) delaying load of ${details.url}`);
return neverResolvingPromise;
},
{ urls: ["*://*/*"], types: ["sub_frame"] },
["blocking"]
);
},
});
await gRequestThrottlerExt.startup();
}
async function stopThrottlingAllIframeLoads() {
await gRequestThrottlerExt.unload();
gRequestThrottlerExt = null;
}
async function openTabAndAwaitLoad(url) {
info(`openTabAndAwaitLoad: ${url}`);
// We cannot use AppTestDelegate.openNewForegroundTab in this test because it
// resolves only when all subresources have been loaded, but we are
// intentionally delaying iframe loads in this test.
let win = window.open(url);
const browsingContextId = SpecialPowers.wrap(win).browsingContext.id;
await SimpleTest.promiseWaitForCondition(
() =>
SpecialPowers.spawnChrome(
[browsingContextId],
bcId => BrowsingContext.get(bcId).children.length
),
"Parent process should detect frame in " + url
);
return win;
}
async function do_test_executeScript_with_slow_frame({
injectImmediately = false,
targetSlowFrame = false, // if false, then allFrames:true is used.
}) {
await throttleAllIframeLoads();
let url = new URL("file_with_same_origin_frame.html", document.baseURI).href;
let win = await openTabAndAwaitLoad(url);
let extension = ExtensionTestUtils.loadExtension({
manifest: {
description: JSON.stringify({ injectImmediately, targetSlowFrame, url }),
permissions: ["scripting", "tabs"],
host_permissions: ["*://*/*"],
},
async background() {
let { injectImmediately, targetSlowFrame, url } = JSON.parse(
browser.runtime.getManifest().description
);
let tabs = await browser.tabs.query({ url: url.replace(/:\d+\//, "/") });
browser.test.assertEq(1, tabs.length, "Found tab of current test");
const target = { tabId: tabs[0].id, allFrames: !targetSlowFrame };
if (targetSlowFrame) {
let [ { result: frameId }] = await browser.scripting.executeScript({
target: { tabId: tabs[0].id },
func: () => browser.runtime.getFrameId(frames[0]),
injectImmediately: true,
});
target.frameIds = [frameId];
}
browser.test.log(`executeScript target is ${JSON.stringify(target)}`);
let results = await browser.scripting.executeScript({
target,
injectImmediately,
func: () => document.URL,
});
// The top document is file_with_same_origin_frame.html and the only
// child frame is the pending load of file_sample.html.
if (!targetSlowFrame) {
// with allFrames:true, the first result is from the top document.
browser.test.assertEq(results[0]?.result, url, "Got right tab");
}
let { error, result } = results[targetSlowFrame ? 0 : 1] || {};
browser.test.assertEq(error?.message, undefined, "No error");
browser.test.assertEq(result, "about:blank", "Got result");
browser.test.notifyPass();
},
});
await extension.startup();
await extension.awaitFinish();
await extension.unload();
win.close();
await stopThrottlingAllIframeLoads();
}
// Tests scripting.executeScript with allFrames:true and injectImmediately:true
// while one of the frames is still loading (and at initial about:blank).
add_task(async function test_executeScript_allFrames_injectImmediately_true() {
await do_test_executeScript_with_slow_frame({ injectImmediately: true });
});
// Tests scripting.executeScript with allFrames:true while one of the frames is
// still loading (and at initial about:blank).
add_task(async function test_executeScript_allFrames_injectImmediately_false() {
await do_test_executeScript_with_slow_frame({ injectImmediately: false });
});
// Tests scripting.executeScript with frameId of a frame that is still loading
// (and at initial about:blank).
add_task(async function test_executeScript_frameId_slow_frame() {
// Note: this tests with injectImmediately:false. We do not separately test
// with injectImmediately:true because if there were to be any failure with
// its implementation, then it should have been caught by
// test_executeScript_allFrames_injectImmediately_true.
await do_test_executeScript_with_slow_frame({ targetSlowFrame: true });
});
</script>
</body>
</html>