1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>DNR with tabIds condition</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" type="text/css" href="/tests/SimpleTest/test.css">
</head>
<body>
<script>
"use strict";
// While most DNR tests are xpcshell tests, this one is a mochitest because it
// is not possible to create a tab and get a tabId in a xpcshell test.
// toolkit/components/extensions/test/xpcshell/test_ext_dnr_tabIds.js does
// exist, as an isolated xpcshell is needed to verify that the internals are
// working as expected. A mochitest is not a good fit for that because it has
// built-in add-ons that may affect the observed behavior.
add_setup(async () => {
await SpecialPowers.pushPrefEnv({
set: [
["extensions.manifestV3.enabled", true],
["extensions.dnr.enabled", true],
],
});
});
add_task(async function match_by_tabIds() {
let extension = ExtensionTestUtils.loadExtension({
async background() {
async function createTabAndPort() {
let portPromise = new Promise(resolve => {
browser.runtime.onConnect.addListener(function listener(port) {
browser.runtime.onConnect.removeListener(listener);
browser.test.assertEq("port_from_tab", port.name, "Got port");
resolve(port);
});
});
const tab = await browser.tabs.create({ url: "tab.html" });
const port = await portPromise;
browser.test.assertEq(tab.id, port.sender.tab.id, "Got port from tab");
browser.test.assertTrue(tab.id > 0, `tabId must be valid: ${tab.id}`);
tab.port = port;
return tab;
}
async function getFinalUrlForFetchInTab(tabWithPort, url) {
const port = tabWithPort.port; // from createTabAndPort.
return new Promise(resolve => {
port.onMessage.addListener(function listener(responseUrl) {
port.onMessage.removeListener(listener);
resolve(responseUrl);
});
port.postMessage(url);
});
}
let tab1 = await createTabAndPort();
let tab2 = await createTabAndPort();
const URL_PREFIX = "https://example.com/tests/toolkit/components/extensions/test/mochitest/file_sample.txt";
function makeRedirect(id, condition, url) {
return {
id,
// The test sends a request to example.net and expects a redirect to
// URL_PREFIX (example.com).
condition: { requestDomains: ["example.net"], ...condition },
action: { type: "redirect", redirect: { url }},
};
}
await browser.declarativeNetRequest.updateSessionRules({
addRules: [
makeRedirect(1, { tabIds: [-1] }, `${URL_PREFIX}?tabId/-1`),
makeRedirect(2, { tabIds: [tab1.id] }, `${URL_PREFIX}?tabId/tab1`),
makeRedirect(
3,
{ excludedTabIds: [-1, tab1.id] },
`${URL_PREFIX}?tabId/not-1,not-tab1`
),
],
});
browser.test.assertEq(
`${URL_PREFIX}?tabId/-1`,
(await fetch("https://example.net/?pre-redirect-bg")).url,
"Request from background should match tabIds: [-1]"
);
browser.test.assertEq(
`${URL_PREFIX}?tabId/tab1`,
await getFinalUrlForFetchInTab(tab1, "https://example.net/?pre-tab1"),
"Request from tab1 should match tabIds: [tab1]"
);
browser.test.assertEq(
`${URL_PREFIX}?tabId/not-1,not-tab1`,
await getFinalUrlForFetchInTab(tab2, "https://example.net/?pre-tab2"),
"Request from tab2 should match excludedTabIds: [-1, tab1]"
);
await browser.tabs.remove(tab1.id);
await browser.tabs.remove(tab2.id);
browser.test.sendMessage("done");
},
temporarilyInstalled: true, // Needed for granted_host_permissions
manifest: {
manifest_version: 3,
host_permissions: ["*://example.com/*", "*://example.net/*"],
permissions: ["declarativeNetRequest"],
granted_host_permissions: true,
},
files: {
"tab.html": `<!DOCTYPE html><script src="tab.js"><\/script>`,
"tab.js": () => {
let port = browser.runtime.connect({ name: "port_from_tab" });
port.onMessage.addListener(async url => {
try {
let res = await fetch(url);
port.postMessage(res.url);
} catch (e) {
port.postMessage(e.message);
}
});
},
},
});
await extension.startup();
await extension.awaitMessage("done");
await extension.unload();
});
</script>
</body>
</html>
|