blob: 31c0a913338e014a569f945c39e5edbae50e594d [file] [log] [blame]
<!doctype html>
<title>crossOriginIsolated permission</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<body>
<script>
const {ORIGIN, HTTPS_REMOTE_ORIGIN} = get_host_info();
const FRAME_PATH =
new URL('resources/cross-origin-isolated-frame.html', location).pathname;
const WORKER_URL =
new URL('resources/cross-origin-isolated-worker.js', location).href;
const PIPE =
'?pipe=' +
'|header(cross-origin-embedder-policy,require-corp)' +
'|header(cross-origin-resource-policy,cross-origin)';
async function getCrossOriginIsolatedForFrame(t, origin, value) {
const parentFrame = document.createElement('iframe');
t.add_cleanup(() => parentFrame.remove());
let pipe = PIPE;
if (value !== undefined) {
pipe += `|header(permissions-policy,cross-origin-isolated=${value})`;
}
parentFrame.src = `${FRAME_PATH}${pipe}`;
document.body.append(parentFrame);
await new Promise((resolve) => {
parentFrame.addEventListener('load', resolve);
});
const frame = parentFrame.contentDocument.createElement('iframe');
frame.src = `${origin}${FRAME_PATH}${PIPE}`;
parentFrame.contentDocument.body.append(frame);
frame.addEventListener('error', t.unreached_func('frame.error'));
await new Promise((resolve) => {
frame.addEventListener('load', resolve);
});
const mc = new MessageChannel();
frame.contentWindow.postMessage({port: mc.port2}, '*', [mc.port2]);
return (await new Promise(r => mc.port1.onmessage = r)).data;
}
async function getCrossOriginIsolatedForDedicatedWorker(t, scheme, value) {
const frame = document.createElement('iframe');
t.add_cleanup(() => frame.remove());
let pipe = PIPE;
if (value !== undefined) {
pipe += `|header(permissions-policy,cross-origin-isolated=${value})`
}
frame.src = `${FRAME_PATH}${pipe}`;
document.body.append(frame);
frame.addEventListener('error', t.unreached_func('frame.error'));
await new Promise((resolve) => {
frame.addEventListener('load', resolve);
});
let workerURL;
if (scheme === 'https') {
workerURL = `${WORKER_URL}${PIPE}`;
} else if (scheme === 'data') {
const res = await fetch(WORKER_URL);
const text = await res.text();
workerURL = `data:application/javascript;base64,${btoa(text)}`;
} else if (scheme === 'blob') {
const res = await fetch(WORKER_URL);
const blob = await res.blob();
workerURL = URL.createObjectURL(blob);
} else {
assert_unreached('scheme should be one of "https", "data" and "blob".');
}
const worker = new frame.contentWindow.Worker(workerURL);
const mc = new MessageChannel();
worker.postMessage({port: mc.port2}, [mc.port2]);
return (await new Promise(r => mc.port1.onmessage = r)).data;
}
async function getCrossOriginIsolatedForSharedWorker(t, withCoopCoep) {
const workerURL = `${WORKER_URL}${withCoopCoep ? PIPE : ''}`;
const worker = new SharedWorker(workerURL);
worker.addEventListener('error', t.unreached_func('worker.error'));
const mc = new MessageChannel();
worker.port.postMessage({port: mc.port2}, [mc.port2]);
return (await new Promise(r => mc.port1.onmessage = r)).data;
}
async function getCrossOriginIsolatedForServiceWorker(t, withCoopCoep) {
// As we don't want the service worker to control any page, generate a
// one-time scope.
const SCOPE = new URL(`resources/${token()}.html`, location).pathname;
const workerURL = `${WORKER_URL}${withCoopCoep ? PIPE : ''}`;
const reg =
await service_worker_unregister_and_register(t, workerURL, SCOPE);
t.add_cleanup(() => reg.unregister());
const worker = reg.installing;
const mc = new MessageChannel();
worker.postMessage({port: mc.port2}, [mc.port2]);
return (await new Promise(r => mc.port1.onmessage = r)).data;
}
function generateFrameTest(origin, value, expectation) {
async function run(t) {
assert_equals(
await getCrossOriginIsolatedForFrame(t, origin, value), expectation);
}
// We use async_test, not promise_test here to run tests in parallel.
async_test((t) => {
run(t).then(() => t.done(), (e) => t.step(() => {throw e;}));
}, `frame: origin = ${origin}, value = ${value}`);
}
function generateDedicatedWorkerTest(scheme, value, expectation) {
async function run(t) {
assert_equals(
await getCrossOriginIsolatedForDedicatedWorker(t, scheme, value),
expectation);
}
// We use async_test, not promise_test here to run tests in parallel.
async_test((t) => {
run(t).then(() => t.done(), (e) => t.step(() => {throw e;}));
}, `dedicated worker: scheme = ${scheme}, value = ${value}`);
}
function generateSharedWorkerTest(withCoopCoep) {
async function run(t) {
assert_equals(
await getCrossOriginIsolatedForSharedWorker(t, withCoopCoep),
withCoopCoep);
}
// We use async_test, not promise_test here to run tests in parallel.
async_test((t) => {
run(t).then(() => t.done(), (e) => t.step(() => {throw e;}));
}, `shared worker: withCoopCoep = ${withCoopCoep}`);
}
function generateServiceWorkerTest(withCoopCoep) {
// Here we use promise_test as we want to use a cleanup callback that returns
// a promise.
promise_test(async (t) => {
assert_equals(
await getCrossOriginIsolatedForServiceWorker(t, withCoopCoep),
withCoopCoep);
}, `service worker: withCoopCoep = ${withCoopCoep}`);
}
generateFrameTest(ORIGIN, undefined, true);
generateFrameTest(ORIGIN, '*', true);
generateFrameTest(ORIGIN, 'self', true);
// We need the backslash to escape the close parenthesis in a wpt pipe.
generateFrameTest(ORIGIN, '(\\)', false);
generateFrameTest(HTTPS_REMOTE_ORIGIN, undefined, false);
generateFrameTest(HTTPS_REMOTE_ORIGIN, '*', false);
generateFrameTest(HTTPS_REMOTE_ORIGIN, 'self', false);
// We need the backslash to escape the close parenthesis in a wpt pipe.
generateFrameTest(HTTPS_REMOTE_ORIGIN, '(\\)', false);
generateDedicatedWorkerTest('https', undefined, true);
generateDedicatedWorkerTest('https', '*', true);
generateDedicatedWorkerTest('https', 'self', true);
// We need the backslash to escape the close parenthesis in a wpt pipe.
generateDedicatedWorkerTest('https', '(\\)', false);
generateDedicatedWorkerTest('data', undefined, false);
generateDedicatedWorkerTest('data', '*', false);
generateDedicatedWorkerTest('data', 'self', false);
// We need the backslash to escape the close parenthesis in a wpt pipe.
generateDedicatedWorkerTest('data', '(\\)', false);
generateDedicatedWorkerTest('blob', undefined, true);
generateDedicatedWorkerTest('blob', '*', true);
generateDedicatedWorkerTest('blob', 'self', true);
// We need the backslash to escape the close parenthesis in a wpt pipe.
generateDedicatedWorkerTest('blob', '(\\)', false);
generateSharedWorkerTest(false);
generateSharedWorkerTest(true);
generateServiceWorkerTest(false);
generateServiceWorkerTest(true);
</script>
</body>
</html>