Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tabs executeScript Test</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";
add_task(async function testExecuteScript() {
await SpecialPowers.pushPrefEnv({
set: [["dom.security.https_first", false]],
});
const URL = BASE + "file_iframe_document.html";
const win = window.open(URL);
await new Promise(resolve => win.addEventListener("load", resolve, {once: true}));
async function background() {
try {
const [tab] = await browser.tabs.query({active: true, currentWindow: true});
const frames = await browser.webNavigation.getAllFrames({tabId: tab.id});
browser.test.log(`FRAMES: ${frames[1].frameId} ${JSON.stringify(frames)}\n`);
await Promise.all([
browser.tabs.executeScript({
code: "42",
}).then(result => {
browser.test.assertEq(1, result.length, "Expected one callback result");
browser.test.assertEq(42, result[0], "Expected callback result");
}),
browser.tabs.executeScript({
file: "script.js",
code: "42",
}).then(() => {
browser.test.fail("Expected not to be able to execute a script with both file and code");
}, error => {
browser.test.assertTrue(/a 'code' or a 'file' property, but not both/.test(error.message),
"Got expected error");
}),
browser.tabs.executeScript({
file: "script.js",
}).then(result => {
browser.test.assertEq(1, result.length, "Expected one callback result");
browser.test.assertEq(undefined, result[0], "Expected callback result");
}),
browser.tabs.executeScript({
file: "script2.js",
}).then(result => {
browser.test.assertEq(1, result.length, "Expected one callback result");
browser.test.assertEq(27, result[0], "Expected callback result");
}),
browser.tabs.executeScript({
code: "location.href;",
allFrames: true,
}).then(result => {
browser.test.assertTrue(Array.isArray(result), "Result is an array");
browser.test.assertEq(2, result.length, "Result has correct length");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
}),
browser.tabs.executeScript({
code: "location.href;",
allFrames: true,
matchAboutBlank: true,
}).then(result => {
browser.test.assertTrue(Array.isArray(result), "Result is an array");
browser.test.assertEq(3, result.length, "Result has correct length");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
browser.test.assertEq("about:blank", result[2], "Thirds result is correct");
}),
browser.tabs.executeScript({
code: "location.href;",
runAt: "document_end",
}).then(result => {
browser.test.assertEq(1, result.length, "Expected callback result");
browser.test.assertEq("string", typeof result[0], "Result is a string");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "Result is correct");
}),
browser.tabs.executeScript({
code: "window",
}).then(() => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
browser.test.assertEq("<anonymous code>", error.fileName, "Got expected fileName");
browser.test.assertEq("Script '<anonymous code>' result is non-structured-clonable data",
error.message, "Got expected error");
}),
browser.tabs.executeScript({
code: "Promise.resolve(window)",
}).then(() => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
browser.test.assertEq("<anonymous code>", error.fileName, "Got expected fileName");
browser.test.assertEq("Script '<anonymous code>' result is non-structured-clonable data",
error.message, "Got expected error");
}),
browser.tabs.executeScript({
file: "script3.js",
}).then(() => {
browser.test.fail("Expected error when returning non-structured-clonable object");
}, error => {
const expected = /Script '.*script3.js' result is non-structured-clonable data/;
browser.test.assertTrue(expected.test(error.message), "Got expected error");
browser.test.assertTrue(error.fileName.endsWith("script3.js"), "Got expected fileName");
}),
browser.tabs.executeScript({
frameId: Number.MAX_SAFE_INTEGER,
code: "42",
}).then(() => {
browser.test.fail("Expected error when specifying invalid frame ID");
}, error => {
browser.test.assertEq(
`Invalid frame IDs: [${Number.MAX_SAFE_INTEGER}].`,
error.message,
"Got expected error"
);
}),
browser.tabs.create({url: "http://example.net/", active: false}).then(async tab => {
await browser.tabs.executeScript(tab.id, {
code: "42",
}).then(() => {
browser.test.fail("Expected error when trying to execute on invalid domain");
}, error => {
browser.test.assertEq(`Missing host permission for the tab`,
error.message, "Got expected error");
});
await browser.tabs.remove(tab.id);
}),
browser.tabs.executeScript({
code: "Promise.resolve(42)",
}).then(result => {
browser.test.assertEq(42, result[0], "Got expected promise resolution value as result");
}),
browser.tabs.executeScript({
code: "location.href;",
runAt: "document_end",
allFrames: true,
}).then(result => {
browser.test.assertTrue(Array.isArray(result), "Result is an array");
browser.test.assertEq(2, result.length, "Result has correct length");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
}),
browser.tabs.executeScript({
code: "location.href;",
frameId: frames[0].frameId,
}).then(result => {
browser.test.assertEq(1, result.length, "Expected one result");
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), `Result for frameId[0] is correct: ${result[0]}`);
}),
browser.tabs.executeScript({
code: "location.href;",
frameId: frames[1].frameId,
}).then(result => {
browser.test.assertEq(1, result.length, "Expected one result");
browser.test.assertEq("http://mochi.test:8888/", result[0], "Result for frameId[1] is correct");
}),
browser.tabs.create({url: "http://example.com/"}).then(async tab => {
const result = await browser.tabs.executeScript(tab.id, {code: "location.href"});
browser.test.assertEq("http://example.com/", result[0], "Script executed correctly in new tab");
await browser.tabs.remove(tab.id);
}),
// This currently does not work on Android.
/*
browser.tabs.create({url: "about:blank"}).then(async tab => {
const result = await browser.tabs.executeScript(tab.id, {code: "location.href", matchAboutBlank: true});
browser.test.assertEq("about:blank", result[0], "Script executed correctly in new tab");
await browser.tabs.remove(tab.id);
}),
*/
new Promise(resolve => {
browser.runtime.onMessage.addListener(message => {
browser.test.assertEq("script ran", message, "Expected runtime message");
resolve();
});
}),
]);
browser.test.notifyPass("executeScript");
} catch (e) {
browser.test.fail(`Error: ${e} :: ${e.stack}`);
browser.test.notifyFail("executeScript");
}
}
const extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["http://mochi.test/", "http://example.com/", "webNavigation"],
},
background,
files: {
"script.js": function() {
browser.runtime.sendMessage("script ran");
},
"script2.js": "27",
"script3.js": "window",
},
});
await extension.startup();
await extension.awaitFinish("executeScript");
await extension.unload();
win.close();
});
</script>
</body>
</html>