Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
/**
* Bug 1973042 - Tests that ensure that worker fetches for tracker domains are
* properly blocked by tracking protection.
*/
"use strict";
const TEST_TRACKER_DOMAIN = "https://tracking.example.com/";
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["privacy.trackingprotection.enabled", true]],
});
await UrlClassifierTestUtils.addTestTrackers();
registerCleanupFunction(_ => {
UrlClassifierTestUtils.cleanupTestTrackers();
});
});
add_task(async function test_workerFetch() {
// Open a tab.
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
TEST_TOP_PAGE_HTTPS
);
// Create a dedicated worker on the page and instruct it to fetch.
await SpecialPowers.spawn(
tab.linkedBrowser,
[
TEST_TRACKER_DOMAIN + TEST_PATH + "corsAllowed.html",
TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "corsAllowed.html",
],
async (trackingUrl, nonTrackingUrl) => {
let worker = new content.Worker("workerFetch.js");
// Send a fetch request to a tracking domain.
let result = await new content.Promise(resolve => {
worker.addEventListener("message", function handler(e) {
if (e.data.type === "FetchResult") {
if (e.data.success) {
resolve(true);
} else {
resolve(false);
}
worker.removeEventListener("message", handler);
}
});
// Send the fetch request to the worker
worker.postMessage({ type: "Fetch", url: trackingUrl });
});
// The fetch should be blocked by tracking protection
ok(
!result,
"Dedicated worker fetch to a tracker domain should be blocked by tracking protection"
);
// Send a fetch request to a non-tracking domain.
result = await new content.Promise(resolve => {
worker.addEventListener("message", function handler(e) {
if (e.data.type === "FetchResult") {
if (e.data.success) {
resolve(true);
} else {
resolve(false);
}
worker.removeEventListener("message", handler);
}
});
worker.postMessage({ type: "Fetch", url: nonTrackingUrl });
});
// The fetch should succeed
ok(
result,
"Dedicated worker fetch to non-tracking domain should succeed"
);
// Terminate the worker
worker.terminate();
}
);
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_sharedWorkerFetch() {
// Open a tab.
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
TEST_TOP_PAGE_HTTPS
);
// Create a shared worker on the page and instruct it to fetch
await SpecialPowers.spawn(
tab.linkedBrowser,
[
TEST_TRACKER_DOMAIN + TEST_PATH + "corsAllowed.html",
TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "corsAllowed.html",
],
async (trackingUrl, nonTrackingUrl) => {
let worker = new content.SharedWorker("sharedWorkerFetch.js");
// Create a promise that will resolve when we get the response
let result = await new content.Promise(resolve => {
worker.port.addEventListener("message", function handler(e) {
if (e.data.type === "FetchResult") {
if (e.data.success) {
resolve(true);
} else {
resolve(false);
}
worker.port.removeEventListener("message", handler);
}
});
// Start the port connection
worker.port.start();
// Send the fetch request to the worker
worker.port.postMessage({ type: "Fetch", url: trackingUrl });
});
// The fetch should be blocked by tracking protection
ok(
!result,
"Shared worker fetch to a tracker domain should be blocked by tracking protection"
);
// Send a fetch request to a non-tracking domain.
result = await new content.Promise(resolve => {
worker.port.addEventListener("message", function handler(e) {
if (e.data.type === "FetchResult") {
if (e.data.success) {
resolve(true);
} else {
resolve(false);
}
worker.port.removeEventListener("message", handler);
}
});
// Send the fetch request to the worker
worker.port.postMessage({ type: "Fetch", url: nonTrackingUrl });
});
// The fetch should succeed
ok(result, "Shared worker fetch to non-tracking domain should succeed");
// Terminate the worker
worker.port.close();
}
);
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_serviceWorkerFetch() {
// Open a tab.
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
TEST_TOP_PAGE_HTTPS
);
// Register a service worker on the page and instruct it to fetch from a
// tracker domain.
await SpecialPowers.spawn(
tab.linkedBrowser,
[
TEST_TRACKER_DOMAIN + TEST_PATH + "corsAllowed.html",
TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "corsAllowed.html",
],
async (trackingUrl, nonTrackingUrl) => {
let reg = await content.navigator.serviceWorker.register(
"serviceWorkerFetch.js"
);
if (reg.installing.state !== "activated") {
await new content.Promise(resolve => {
let w = reg.installing;
w.addEventListener("statechange", function onStateChange() {
if (w.state === "activated") {
w.removeEventListener("statechange", onStateChange);
resolve();
}
});
});
}
// Create a promise that will resolve when we get the response
let result = await new content.Promise(resolve => {
content.navigator.serviceWorker.addEventListener(
"message",
function handler(e) {
if (e.data.type === "FetchResult") {
if (e.data.success) {
resolve(true);
} else {
resolve(false);
}
content.navigator.serviceWorker.removeEventListener(
"message",
handler
);
}
}
);
reg.active.postMessage({ type: "Fetch", url: trackingUrl });
});
ok(
!result,
"Service worker fetch to a tracker domain should be blocked by tracking protection"
);
result = await new content.Promise(resolve => {
content.navigator.serviceWorker.addEventListener(
"message",
function handler(e) {
if (e.data.type === "FetchResult") {
if (e.data.success) {
resolve(true);
} else {
resolve(false);
}
content.navigator.serviceWorker.removeEventListener(
"message",
handler
);
}
}
);
reg.active.postMessage({ type: "Fetch", url: nonTrackingUrl });
});
ok(
result,
"Service worker fetch to a non-tracking domain should succeed."
);
await reg.unregister();
}
);
BrowserTestUtils.removeTab(tab);
});