Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* import-globals-from storageAccessAPIHelpers.js */
PartitionedStorageHelper.runTest(
"ServiceWorkers - disable partitioning",
async (win3rdParty, win1stParty, allowed) => {
// Partitioned serviceWorkers are disabled in third-party context.
await win3rdParty.navigator.serviceWorker.register("empty.js").then(
_ => {
ok(allowed, "Success: ServiceWorker cannot be used!");
},
_ => {
ok(!allowed, "Failed: ServiceWorker cannot be used!");
}
);
await win1stParty.navigator.serviceWorker.register("empty.js").then(
_ => {
ok(true, "Success: ServiceWorker should be available!");
},
_ => {
ok(false, "Failed: ServiceWorker should be available!");
}
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", false],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - enable partitioning",
async (win3rdParty, win1stParty) => {
// Partitioned serviceWorkers are enabled in third-party context.
await win3rdParty.navigator.serviceWorker.register("empty.js").then(
_ => {
ok(
true,
"Success: ServiceWorker should be available in third parties."
);
},
_ => {
ok(
false,
"Failed: ServiceWorker should be available in third parties."
);
}
);
await win1stParty.navigator.serviceWorker.register("empty.js").then(
_ => {
ok(true, "Success: ServiceWorker should be available!");
},
_ => {
ok(false, "Failed: ServiceWorker should be available!");
}
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - MatchAll",
async (win3rdParty, win1stParty) => {
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(win1stParty, "matchAll.js");
}
let msgPromise = new Promise(resolve => {
win1stParty.navigator.serviceWorker.addEventListener("message", msg => {
resolve(msg.data);
});
});
win1stParty.sw.postMessage(win3rdParty.location.href);
let msg = await msgPromise;
// The service worker will always be partitioned. So, the first party window
// won't have control on the third-party window.
is(
false,
msg,
"We won't have the 3rd party window controlled regardless of StorageAccess."
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - Partition ScriptContext",
async (win3rdParty, win1stParty) => {
// Register service worker for the first-party window.
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(
win1stParty,
"serviceWorker.js"
);
}
// Register service worker for the third-party window.
if (!win3rdParty.sw) {
win3rdParty.sw = await registerServiceWorker(
win3rdParty,
"serviceWorker.js"
);
}
// Set a script value to first-party service worker.
let res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{
type: "SetScriptValue",
value: "1stParty",
}
);
ok(res.result, "OK", "Set script value to first-party service worker.");
// Set a script value to third-party service worker.
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{
type: "SetScriptValue",
value: "3rdParty",
}
);
ok(res.result, "OK", "Set script value to third-party service worker.");
// Get and check script value from the first-party service worker.
res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{ type: "GetScriptValue" }
);
is(
res.value,
"1stParty",
"The script value in first party window is correct"
);
// Get and check script value from the third-party service worker.
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{ type: "GetScriptValue" }
);
is(
res.value,
"3rdParty",
"The script value in third party window is correct"
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - Partition DOM Cache",
async (win3rdParty, win1stParty) => {
// Register service worker for the first-party window.
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(
win1stParty,
"serviceWorker.js"
);
}
// Register service worker for the third-party window.
if (!win3rdParty.sw) {
win3rdParty.sw = await registerServiceWorker(
win3rdParty,
"serviceWorker.js"
);
}
// Set DOM cache to first-party service worker.
let res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{
type: "SetCache",
value: "1stParty",
}
);
ok(res.result, "OK", "Set cache to first-party service worker.");
// Set DOM cache to third-party service worker.
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{
type: "SetCache",
value: "3rdParty",
}
);
ok(res.result, "OK", "Set cache to third-party service worker.");
// Check DOM cache from the first-party service worker.
res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{ type: "HasCache", value: "1stParty" }
);
ok(
res.value,
"The '1stParty' cache storage should exist for the first-party window."
);
res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{ type: "HasCache", value: "3rdParty" }
);
ok(
!res.value,
"The '3rdParty' cache storage should not exist for the first-party window."
);
// Check DOM cache from the third-party service worker.
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{ type: "HasCache", value: "1stParty" }
);
ok(
!res.value,
"The '1stParty' cache storage should not exist for the third-party window."
);
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{ type: "HasCache", value: "3rdParty" }
);
ok(
res.value,
"The '3rdParty' cache storage should exist for the third-party window."
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - Partition IndexedDB",
async (win3rdParty, win1stParty) => {
// Register service worker for the first-party window.
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(
win1stParty,
"serviceWorker.js"
);
}
// Register service worker for the third-party window.
if (!win3rdParty.sw) {
win3rdParty.sw = await registerServiceWorker(
win3rdParty,
"serviceWorker.js"
);
}
// Set indexedDB value to first-party service worker.
let res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{
type: "SetIndexedDB",
value: "1stParty",
}
);
ok(res.result, "OK", "Set cache to first-party service worker.");
// Set indexedDB value to third-party service worker.
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{
type: "SetIndexedDB",
value: "3rdParty",
}
);
ok(res.result, "OK", "Set cache to third-party service worker.");
// Get and check indexedDB value from the first-party service worker.
res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{ type: "GetIndexedDB" }
);
is(
res.value,
"1stParty",
"The indexedDB value in first party window is correct"
);
// Get and check indexedDB from the third-party service worker.
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{ type: "GetIndexedDB" }
);
is(
res.value,
"3rdParty",
"The indexedDB value in third party window is correct"
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - Partition Intercept",
async (win3rdParty, win1stParty) => {
// Register service worker for the first-party window.
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(
win1stParty,
"serviceWorker.js"
);
}
// Register service worker for the third-party window.
if (!win3rdParty.sw) {
win3rdParty.sw = await registerServiceWorker(
win3rdParty,
"serviceWorker.js"
);
}
// Fetch a resource in the first-party window.
await win1stParty.fetch("empty.js");
// Check that only the first-party service worker gets fetch event.
let res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{ type: "GetFetchURL" }
);
is(
res.value,
"The first-party service worker received fetch event."
);
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{ type: "GetFetchURL" }
);
is(
res.value,
"",
"The third-party service worker received no fetch event."
);
// Fetch a resource in the third-party window.
await win3rdParty.fetch("empty.js");
// Check if the fetch event only happens in third-party service worker.
res = await sendAndWaitWorkerMessage(
win1stParty.sw,
win1stParty.navigator.serviceWorker,
{ type: "GetFetchURL" }
);
is(
res.value,
"",
"The first-party service worker received no fetch event."
);
res = await sendAndWaitWorkerMessage(
win3rdParty.sw,
win3rdParty.navigator.serviceWorker,
{ type: "GetFetchURL" }
);
is(
res.value,
"The third-party service worker received fetch event."
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
// Bug1743236 - Verify the content process won't crash if we create a dedicated
// worker in a service worker controlled third-party page with Storage Access.
PartitionedStorageHelper.runTest(
"ServiceWorkers - Create Dedicated Worker",
async (win3rdParty, win1stParty, allowed) => {
// We only do this test when the storage access is granted.
if (!allowed) {
return;
}
// Register service worker for the first-party window.
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(
win1stParty,
"serviceWorker.js"
);
}
// Register service worker for the third-party window.
if (!win3rdParty.sw) {
win3rdParty.sw = await registerServiceWorker(
win3rdParty,
"serviceWorker.js"
);
}
// Create a dedicated worker in first-party window.
let firstPartyWorker = new win1stParty.Worker("dedicatedWorker.js");
// Post a message to the dedicated worker and wait until the message circles
// back.
await new Promise(resolve => {
firstPartyWorker.addEventListener("message", msg => {
if (msg.data == "1stParty") {
resolve();
}
});
firstPartyWorker.postMessage("1stParty");
});
// Create a dedicated worker in third-party window.
let thirdPartyWorker = new win3rdParty.Worker("dedicatedWorker.js");
// Post a message to the dedicated worker and wait until the message circles
// back.
await new Promise(resolve => {
thirdPartyWorker.addEventListener("message", msg => {
if (msg.data == "3rdParty") {
resolve();
}
});
thirdPartyWorker.postMessage("3rdParty");
});
firstPartyWorker.terminate();
thirdPartyWorker.terminate();
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
// Bug1768193 - Verify the parent process won't crash if we create a shared
// worker in a service worker controlled third-party page with Storage Access.
PartitionedStorageHelper.runTest(
"ServiceWorkers - Create Shared Worker",
async (win3rdParty, win1stParty, allowed) => {
// We only do this test when the storage access is granted.
if (!allowed) {
return;
}
// Register service worker for the first-party window.
if (!win1stParty.sw) {
win1stParty.sw = await registerServiceWorker(
win1stParty,
"serviceWorker.js"
);
}
// Register service worker for the third-party window.
if (!win3rdParty.sw) {
win3rdParty.sw = await registerServiceWorker(
win3rdParty,
"serviceWorker.js"
);
}
// Create a shared worker in third-party window.
let thirdPartyWorker = new win3rdParty.SharedWorker("sharedWorker.js");
// Post a message to the dedicated worker and wait until the message circles
// back.
await new Promise(resolve => {
thirdPartyWorker.port.onmessage = () => {
resolve();
};
thirdPartyWorker.onerror = _ => {
ok(false, "We should not be here");
resolve();
};
thirdPartyWorker.port.postMessage("count");
});
thirdPartyWorker.port.postMessage("close");
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
]
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - Private Browsing with partitioning disabled",
async (win3rdParty, win1stParty) => {
// Partitioned serviceWorkers are disabled in third-party context.
ok(
!win3rdParty.navigator.serviceWorker,
"ServiceWorker should not be available"
);
ok(
!win1stParty.navigator.serviceWorker,
"ServiceWorker should not be available"
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", false],
],
{
runInPrivateWindow: true,
}
);
PartitionedStorageHelper.runTest(
"ServiceWorkers - Private Browsing with partitioning enabled",
async (win3rdParty, win1stParty) => {
// Partitioned serviceWorkers are disabled in third-party context.
ok(
!win3rdParty.navigator.serviceWorker,
"ServiceWorker should not be available"
);
ok(
!win1stParty.navigator.serviceWorker,
"ServiceWorker should not be available"
);
},
async _ => {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
},
[
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.ipc.processCount", 1],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["privacy.partition.serviceWorkers", true],
],
{
runInPrivateWindow: true,
}
);