summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html')
-rw-r--r--toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html213
1 files changed, 213 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html
new file mode 100644
index 0000000000..76a13be1af
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html
@@ -0,0 +1,213 @@
+<!DOCTYPE HTML>
+
+<html>
+<head>
+<meta charset="utf-8">
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script type="text/javascript" src="head_webrequest.js"></script>
+ <script type="text/javascript" src="head.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+<script>
+"use strict";
+
+let extensionData = {
+ manifest: {
+ permissions: ["webRequest", "webRequestBlocking", "<all_urls>", "tabs"],
+ },
+ background() {
+ browser.webRequest.onBeforeRequest.addListener(details => {
+ if (details.url.endsWith("/favicon.ico")) {
+ // We don't care about favicon.ico in this test. It is hard to control
+ // whether the request happens.
+ browser.test.log(`Ignoring favicon request: ${details.url}`);
+ return;
+ }
+ browser.test.sendMessage("onBeforeRequest", details);
+ }, {urls: ["<all_urls>"]}, ["blocking"]);
+
+ let tab;
+ browser.tabs.onCreated.addListener(newTab => {
+ browser.test.sendMessage("tab-created");
+ tab = newTab;
+ });
+
+ browser.test.onMessage.addListener(msg => {
+ if (msg === "close-tab") {
+ browser.tabs.remove(tab.id);
+ browser.test.sendMessage("tab-closed");
+ }
+ });
+ },
+};
+
+let expected = {
+ "file_simple_xhr.html": {
+ type: "main_frame",
+ toplevel: true,
+ },
+ "file_image_good.png": {
+ type: "image",
+ toplevel: true,
+ origin: "file_simple_xhr.html",
+ },
+ "example.txt": {
+ type: "xmlhttprequest",
+ toplevel: true,
+ origin: "file_simple_xhr.html",
+ },
+ // sub frames will have the origin and first ancestor is the
+ // parent document
+ "file_simple_xhr_frame.html": {
+ type: "sub_frame",
+ toplevelParent: true,
+ origin: "file_simple_xhr.html",
+ parent: "file_simple_xhr.html",
+ },
+ // a resource in a sub frame will have origin of the subframe,
+ // but the ancestor chain starts with the parent document
+ "xhr_resource": {
+ type: "xmlhttprequest",
+ origin: "file_simple_xhr_frame.html",
+ parent: "file_simple_xhr.html",
+ },
+ "file_image_bad.png": {
+ type: "image",
+ depth: 2,
+ origin: "file_simple_xhr_frame.html",
+ parent: "file_simple_xhr.html",
+ },
+ "file_simple_xhr_frame2.html": {
+ type: "sub_frame",
+ depth: 2,
+ origin: "file_simple_xhr_frame.html",
+ parent: "file_simple_xhr_frame.html",
+ },
+ "file_image_redirect.png": {
+ type: "image",
+ depth: 2,
+ origin: "file_simple_xhr_frame2.html",
+ parent: "file_simple_xhr_frame.html",
+ },
+ "xhr_resource_2": {
+ type: "xmlhttprequest",
+ depth: 2,
+ origin: "file_simple_xhr_frame2.html",
+ parent: "file_simple_xhr_frame.html",
+ },
+ // This is loaded in a sandbox iframe. originUrl is not available for that,
+ // and requests within a sandboxed iframe will additionally have an empty
+ // url on their immediate parent/ancestor.
+ "file_simple_sandboxed_frame.html": {
+ type: "sub_frame",
+ depth: 3,
+ parent: "file_simple_xhr_frame2.html",
+ },
+ "xhr_sandboxed": {
+ type: "xmlhttprequest",
+ sandboxed: true,
+ depth: 3,
+ parent: "",
+ },
+ "file_image_great.png": {
+ type: "image",
+ sandboxed: true,
+ depth: 3,
+ parent: "",
+ },
+ "file_simple_sandboxed_subframe.html": {
+ type: "sub_frame",
+ depth: 4,
+ parent: "",
+ },
+};
+
+function checkDetails(details) {
+ let url = new URL(details.url);
+ let filename = url.pathname.split("/").pop();
+ ok(filename in expected, `Should be expecting a request for ${filename}`);
+ let expect = expected[filename];
+ is(expect.type, details.type, `${details.type} type matches`);
+ if (details.parentFrameId == -1) {
+ is(details.frameAncestors.length, 0, "no ancestors for main_frame requests");
+ } else if (details.parentFrameId == 0) {
+ is(details.frameAncestors.length, 1, "one ancestors for sub_frame requests");
+ } else {
+ ok(details.frameAncestors.length > 1, "have multiple ancestors for deep subframe requests");
+ is(details.frameAncestors.length, expect.depth, "have multiple ancestors for deep subframe requests");
+ }
+ if (details.parentFrameId > -1) {
+ ok(!expect.origin || details.originUrl.includes(expect.origin), "origin url is correct");
+ is(details.frameAncestors[0].frameId, details.parentFrameId, "first ancestor matches request.parentFrameId");
+ ok(details.frameAncestors[0].url.includes(expect.parent), "ancestor parent page correct");
+ is(details.frameAncestors[details.frameAncestors.length - 1].frameId, 0, "last ancestor is always zero");
+ // All our tests should be somewhere within the frame that we set topframe in the query string. That
+ // frame will always be the last ancestor.
+ ok(details.frameAncestors[details.frameAncestors.length - 1].url.includes("topframe=true"), "last ancestor is always topframe");
+ }
+ if (expect.toplevel) {
+ is(details.frameId, 0, "expect load at top level");
+ is(details.parentFrameId, -1, "expect top level frame to have no parent");
+ } else if (details.type == "sub_frame") {
+ ok(details.frameId > 0, "expect sub_frame to load into a new frame");
+ if (expect.toplevelParent) {
+ is(details.parentFrameId, 0, "expect sub_frame to have top level parent");
+ is(details.frameAncestors.length, 1, "one ancestor for top sub_frame request");
+ } else {
+ ok(details.parentFrameId > 0, "expect sub_frame to have parent");
+ ok(details.frameAncestors.length > 1, "sub_frame has ancestors");
+ }
+ expect.subframeId = details.frameId;
+ expect.parentId = details.parentFrameId;
+ } else if (expect.sandboxed) {
+ is(details.documentUrl, undefined, "null principal documentUrl for sandboxed request");
+ } else {
+ // get the parent frame.
+ let purl = new URL(details.documentUrl);
+ let pfilename = purl.pathname.split("/").pop();
+ let parent = expected[pfilename];
+ is(details.frameId, parent.subframeId, "expect load in subframe");
+ is(details.parentFrameId, parent.parentId, "expect subframe parent");
+ }
+ return filename;
+}
+
+add_task(async function test_webRequest_main_frame() {
+ // Clear the image cache, since it gets in the way otherwise.
+ let imgTools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService(SpecialPowers.Ci.imgITools);
+ let cache = imgTools.getImgCacheForDocument(document);
+ cache.clearCache(false);
+ await SpecialPowers.spawnChrome([], async () => {
+ Services.cache2.clear();
+ });
+
+ let extension = ExtensionTestUtils.loadExtension(extensionData);
+ await extension.startup();
+
+ let a = addLink(`file_simple_xhr.html?topframe=true&nocache=${Math.random()}`);
+ a.click();
+
+ let remaining = new Set(Object.keys(expected));
+ let totalExpectedCount = remaining.size;
+ for (let i = 0; i < totalExpectedCount; i++) {
+ info(`Waiting for request ${i + 1} out of ${totalExpectedCount}`);
+ info(`Expecting one of: ${Array.from(remaining)}`);
+ let details = await extension.awaitMessage("onBeforeRequest");
+ info(`Checking details for request ${i}: ${JSON.stringify(details)}`);
+ let filename = checkDetails(details);
+ ok(remaining.delete(filename), `Got only one request for ${filename}`);
+ }
+
+ await extension.awaitMessage("tab-created");
+ extension.sendMessage("close-tab");
+ await extension.awaitMessage("tab-closed");
+
+ await extension.unload();
+});
+</script>
+</head>
+<body>
+<div id="test">Sample text</div>
+
+</body>
+</html>