mirror of
https://github.com/servo/servo.git
synced 2025-08-10 16:05:43 +01:00
Update web-platform-tests to revision b'b728032f59a396243864b0f8584e7211e3632005'
This commit is contained in:
parent
ace9b32b1c
commit
df68c4e5d1
15632 changed files with 514865 additions and 155000 deletions
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Accept: request header in webbundle requests</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
promise_test(async () => {
|
||||
await addWebBundleElementAndWaitForLoad(
|
||||
"../resources/check-accept-header-and-return-bundle.py",
|
||||
/*resources=*/ []
|
||||
);
|
||||
}, "Accept: header in a request for a bundle should contain application/webbundle MIME type.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,127 @@
|
|||
<!DOCTYPE html>
|
||||
<title>COEP for WebBundle subresource loading</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://html.spec.whatwg.org/multipage/origin.html#coep"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`corp.wbn` includes three subresources:
|
||||
a. `no-corp.js`, which doesn't include a Cross-Origin-Resource-Policy response header.
|
||||
b. `corp-same-origin.js`, which includes a Cross-Origin-Resource-Policy: same-origin response header.
|
||||
c. `corp-cross-origin.js`, which includes a Cross-Origin-Resource-Policy: cross-origin response header.
|
||||
-->
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn",
|
||||
"resources": [
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/no-corp.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-same-origin.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-cross-origin.js",
|
||||
"uuid-in-package:5eafff38-e0a0-4661-bde0-434255aa9d93",
|
||||
"uuid-in-package:7e13b47a-8b91-4a0e-997c-993a5e2f3a34",
|
||||
"uuid-in-package:86d5b696-8867-4454-8b07-51239a0817f7"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
async function expectCOEPReport(func) {
|
||||
const reportsPromise = new Promise((resolve) => {
|
||||
const observer = new ReportingObserver((reports) => {
|
||||
observer.disconnect();
|
||||
resolve(reports.map((r) => r.toJSON()));
|
||||
});
|
||||
observer.observe();
|
||||
});
|
||||
|
||||
await func();
|
||||
|
||||
const reports = await reportsPromise;
|
||||
assert_equals(reports.length, 1);
|
||||
assert_equals(reports[0].type, "coep");
|
||||
assert_equals(reports[0].url, location.href);
|
||||
return reports[0];
|
||||
}
|
||||
|
||||
const prefix =
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/";
|
||||
const no_corp_url = "uuid-in-package:5eafff38-e0a0-4661-bde0-434255aa9d93";
|
||||
const corp_same_origin_url =
|
||||
"uuid-in-package:7e13b47a-8b91-4a0e-997c-993a5e2f3a34";
|
||||
const corp_cross_origin_url =
|
||||
"uuid-in-package:86d5b696-8867-4454-8b07-51239a0817f7";
|
||||
|
||||
promise_test(async () => {
|
||||
const report = await expectCOEPReport(async () => {
|
||||
await addScriptAndWaitForError(prefix + "no-corp.js");
|
||||
});
|
||||
assert_equals(report.body.blockedURL, prefix + "no-corp.js");
|
||||
assert_equals(report.body.type, "corp");
|
||||
assert_equals(report.body.disposition, "enforce");
|
||||
assert_equals(report.body.destination, "script");
|
||||
}, "Cross-origin subresource without Cross-Origin-Resource-Policy: header should be blocked and generate a report.");
|
||||
|
||||
promise_test(async () => {
|
||||
await addScriptAndWaitForError(prefix + "corp-same-origin.js");
|
||||
}, "Cross-origin subresource with Cross-Origin-Resource-Policy: same-origin should be blocked.");
|
||||
|
||||
promise_test(async () => {
|
||||
await addScriptAndWaitForExecution(prefix + "corp-cross-origin.js");
|
||||
}, "Cross-origin subresource with Cross-Origin-Resource-Policy: cross-origin should be loaded.");
|
||||
|
||||
promise_test(async () => {
|
||||
const report = await expectCOEPReport(async () => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = no_corp_url;
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
|
||||
assert_equals(report.body.blockedURL, no_corp_url);
|
||||
assert_equals(report.body.type, "corp");
|
||||
assert_equals(report.body.disposition, "enforce");
|
||||
assert_equals(report.body.destination, "iframe");
|
||||
}, "uuid-in-package iframe without Cross-Origin-Resource-Policy: header should be blocked and generate a report.");
|
||||
|
||||
promise_test(async () => {
|
||||
const report = await expectCOEPReport(async () => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = corp_same_origin_url;
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
|
||||
assert_equals(report.body.blockedURL, corp_same_origin_url);
|
||||
assert_equals(report.body.type, "corp");
|
||||
assert_equals(report.body.disposition, "enforce");
|
||||
assert_equals(report.body.destination, "iframe");
|
||||
}, "uuid-in-package iframe with Cross-Origin-Resource-Policy: same-origin should be blocked and generate a report.");
|
||||
|
||||
promise_test(async () => {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = corp_cross_origin_url;
|
||||
await addElementAndWaitForLoad(iframe);
|
||||
assert_equals(
|
||||
await evalInIframe(iframe, "location.href"),
|
||||
corp_cross_origin_url
|
||||
);
|
||||
}, "uuid-in-package iframe with Cross-Origin-Resource-Policy: cross-origin should not be blocked.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,73 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CORP for WebBundle subresource loading</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#cors-and-corp-for-subresource-requests"
|
||||
/>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`corp.wbn` includes three subresources:
|
||||
a. `no-corp.js`, which doesn't include a Cross-Origin-Resource-Policy response header.
|
||||
b. `corp-same-origin.js`, which includes a Cross-Origin-Resource-Policy: same-origin response header.
|
||||
c. `corp-cross-origin.js`, which includes a Cross-Origin-Resource-Policy: cross-origin response header.
|
||||
-->
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn",
|
||||
"resources": [
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/no-corp.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-same-origin.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-cross-origin.js",
|
||||
"uuid-in-package:5eafff38-e0a0-4661-bde0-434255aa9d93",
|
||||
"uuid-in-package:7e13b47a-8b91-4a0e-997c-993a5e2f3a34",
|
||||
"uuid-in-package:86d5b696-8867-4454-8b07-51239a0817f7"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
const prefix =
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/";
|
||||
await addScriptAndWaitForExecution(prefix + "no-corp.js");
|
||||
await addScriptAndWaitForError(prefix + "corp-same-origin.js");
|
||||
await addScriptAndWaitForExecution(prefix + "corp-cross-origin.js");
|
||||
}, "Subresource loading from WebBundles should respect Cross-Origin-Resource-Policy header.");
|
||||
|
||||
promise_test(async () => {
|
||||
const no_corp_url = "uuid-in-package:5eafff38-e0a0-4661-bde0-434255aa9d93";
|
||||
const corp_same_origin_url =
|
||||
"uuid-in-package:7e13b47a-8b91-4a0e-997c-993a5e2f3a34";
|
||||
const corp_cross_origin_url =
|
||||
"uuid-in-package:86d5b696-8867-4454-8b07-51239a0817f7";
|
||||
await iframeLocationTest(no_corp_url);
|
||||
await iframeLocationTest(corp_same_origin_url);
|
||||
await iframeLocationTest(corp_cross_origin_url);
|
||||
}, "uuid-in-package iframes should not be blocked regardless of the Cross-Origin-Resource-Policy header, if Cross-Origin-Embedder-Policy is not set.");
|
||||
|
||||
async function iframeLocationTest(url) {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = url;
|
||||
await addElementAndWaitForLoad(iframe);
|
||||
assert_equals(await evalInIframe(iframe, "location.href"), url);
|
||||
}
|
||||
</script>
|
||||
</body>
|
|
@ -1,7 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
Credentials in WebBundle subresource loading
|
||||
</title>
|
||||
<title>Credentials in WebBundle subresource loading</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#requests-mode-and-credentials-mode"
|
||||
|
@ -18,7 +16,6 @@
|
|||
// returns a valid format webbundle. Then, a subresource fetch should be successful.
|
||||
// Otherwise, a subresource fetch should be rejected.
|
||||
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = "script";
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
@ -36,10 +33,12 @@
|
|||
);
|
||||
|
||||
const same_origin_bundle = "../resources/check-cookie-and-return-bundle.py";
|
||||
const cross_origin_bundle = "https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/check-cookie-and-return-bundle.py?bundle=cross-origin";
|
||||
const cross_origin_bundle =
|
||||
"https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/check-cookie-and-return-bundle.py?bundle=cross-origin";
|
||||
|
||||
const same_origin_bundle_subresource = "../resources/wbn/root.js";
|
||||
const cross_origin_bundle_subresource = "https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/simple-cross-origin.txt";
|
||||
const cross_origin_bundle_subresource =
|
||||
"https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/simple-cross-origin.txt";
|
||||
|
||||
async function assertSubresourceCanBeFetched() {
|
||||
const response = await fetch(same_origin_bundle_subresource);
|
||||
|
@ -58,7 +57,11 @@
|
|||
if (credentials) {
|
||||
options.credentials = credentials;
|
||||
}
|
||||
return createWebBundleElement(same_origin_bundle, [same_origin_bundle_subresource], options);
|
||||
return createWebBundleElement(
|
||||
same_origin_bundle,
|
||||
[same_origin_bundle_subresource],
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
function createScriptWebBundleCrossOrigin(credentials) {
|
||||
|
@ -66,7 +69,11 @@
|
|||
if (credentials) {
|
||||
options.credentials = credentials;
|
||||
}
|
||||
return createWebBundleElement(cross_origin_bundle, [cross_origin_bundle_subresource], options);
|
||||
return createWebBundleElement(
|
||||
cross_origin_bundle,
|
||||
[cross_origin_bundle_subresource],
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
promise_test(async (t) => {
|
||||
|
@ -90,7 +97,11 @@
|
|||
document.body.append(script);
|
||||
t.add_cleanup(() => script.remove());
|
||||
|
||||
return promise_rejects_js(t, TypeError, fetch(same_origin_bundle_subresource))
|
||||
return promise_rejects_js(
|
||||
t,
|
||||
TypeError,
|
||||
fetch(same_origin_bundle_subresource)
|
||||
);
|
||||
}, "'omit' should not send a credential to a same origin bundle");
|
||||
|
||||
promise_test(async (t) => {
|
||||
|
@ -116,7 +127,11 @@
|
|||
document.body.append(script);
|
||||
t.add_cleanup(() => script.remove());
|
||||
|
||||
return promise_rejects_js(t, TypeError, fetch(cross_origin_bundle_subresource))
|
||||
return promise_rejects_js(
|
||||
t,
|
||||
TypeError,
|
||||
fetch(cross_origin_bundle_subresource)
|
||||
);
|
||||
}, "'omit' should not send a credential to a cross origin bundle");
|
||||
|
||||
promise_test(async (t) => {
|
||||
|
@ -126,7 +141,11 @@
|
|||
document.body.append(script);
|
||||
t.add_cleanup(() => script.remove());
|
||||
|
||||
return promise_rejects_js(t, TypeError, fetch(cross_origin_bundle_subresource))
|
||||
return promise_rejects_js(
|
||||
t,
|
||||
TypeError,
|
||||
fetch(cross_origin_bundle_subresource)
|
||||
);
|
||||
}, "'same-origin' should not send a credential to a cross origin bundle");
|
||||
|
||||
promise_test(async (t) => {
|
||||
|
@ -139,13 +158,16 @@
|
|||
await assertCrossOriginSubresourceCanBeFetched();
|
||||
}, "'include' should send a credential to a cross origin bundle");
|
||||
|
||||
|
||||
promise_test(async (t) => {
|
||||
const script = createScriptWebBundleCrossOrigin("invalid");
|
||||
document.body.append(script);
|
||||
t.add_cleanup(() => script.remove());
|
||||
|
||||
return promise_rejects_js(t, TypeError, fetch(cross_origin_bundle_subresource))
|
||||
return promise_rejects_js(
|
||||
t,
|
||||
TypeError,
|
||||
fetch(cross_origin_bundle_subresource)
|
||||
);
|
||||
}, "An invalid value should not send a credential to a cross origin bundle");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSP for subresource WebBundle (allowed cases)</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
script-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn
|
||||
https://web-platform.test:8444/resources/testharness.js
|
||||
https://web-platform.test:8444/resources/testharnessreport.js
|
||||
'unsafe-inline';
|
||||
img-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/pass.png;
|
||||
frame-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/subresource.wbn",
|
||||
"resources": ["https://web-platform.test:8444/web-bundle/resources/wbn/pass.png"]
|
||||
}
|
||||
</script>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/uuid-in-package.wbn",
|
||||
"resources": ["uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720",
|
||||
"uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
promise_test(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = document.createElement("img");
|
||||
img.src =
|
||||
"https://web-platform.test:8444/web-bundle/resources/wbn/pass.png";
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
}, "URL matching of CSP should be done based on the subresource URL " +
|
||||
"when the subresource URL is HTTPS URL.");
|
||||
|
||||
promise_test(async () => {
|
||||
const result = await new Promise((resolve) => {
|
||||
// This function will be called from the script.
|
||||
window.report_result = resolve;
|
||||
const script = document.createElement("script");
|
||||
script.src = "uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720";
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
assert_equals(result, "OK");
|
||||
}, "URL matching of script-src CSP should be done based on the bundle URL " +
|
||||
"when the subresource URL is uuid-in-package: URL.");
|
||||
|
||||
promise_test(async () => {
|
||||
const frame_url = "uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae";
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = frame_url;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
iframe.addEventListener("load", resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
await load_promise;
|
||||
assert_equals(await evalInIframe(iframe, "location.href"), frame_url);
|
||||
}, "URL matching of frame-src CSP should be done based on the bundle URL " +
|
||||
"when the frame URL is uuid-in-package: URL.");
|
||||
|
||||
async function evalInIframe(iframe, code) {
|
||||
const message_promise = new Promise((resolve) => {
|
||||
window.addEventListener(
|
||||
"message",
|
||||
(e) => {
|
||||
resolve(e.data);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
iframe.contentWindow.postMessage(code, "*");
|
||||
return message_promise;
|
||||
}
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,162 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSP for subresource WebBundle (blocked cases)</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
script-src
|
||||
urn:
|
||||
https://web-platform.test:8444/resources/testharness.js
|
||||
https://web-platform.test:8444/resources/testharnessreport.js
|
||||
'unsafe-inline';
|
||||
img-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/subresource.wbn;
|
||||
frame-src
|
||||
urn:;
|
||||
report-to
|
||||
csp-group"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/subresource.wbn",
|
||||
"resources": ["https://web-platform.test:8444/web-bundle/resources/wbn/fail.png"]
|
||||
}
|
||||
</script>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/uuid-in-package.wbn",
|
||||
"resources": ["uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720",
|
||||
"uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae"]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
const uuid_bundle_url =
|
||||
"https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn";
|
||||
|
||||
function expect_violation() {
|
||||
return new Promise((resolve) => {
|
||||
document.addEventListener(
|
||||
"securitypolicyviolation",
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
resolve(e);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getReportID() {
|
||||
const cookies = document.cookie.split(";");
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
const name_value = cookies[i].split("=");
|
||||
const cookieName = name_value[0].trim();
|
||||
if (cookieName === "csp-blocked-report-id") {
|
||||
return name_value[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sortReportsByEffectiveDirective(reports) {
|
||||
reports.sort(
|
||||
(report1, report2) =>
|
||||
report1.body.effectiveDirective.localeCompare(
|
||||
report2.body.effectiveDirective
|
||||
) || report1.body.blockedURL.localeCompare(report2.body.blockedURL)
|
||||
);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
const p = expect_violation();
|
||||
const img = document.createElement("img");
|
||||
const error_promise = new Promise((resolve) => {
|
||||
img.onerror = resolve;
|
||||
});
|
||||
img.src =
|
||||
"https://web-platform.test:8444/web-bundle/resources/wbn/fail.png";
|
||||
document.body.appendChild(img);
|
||||
const e = await p;
|
||||
assert_equals(e.blockedURI, img.src);
|
||||
await error_promise;
|
||||
}, "URL matching of CSP should be done based on the subresource URL, " +
|
||||
"not on the bundle URL, when the subresource URL is HTTPS URL.");
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
prefix: "uuid-in-package:",
|
||||
bundle_url: uuid_bundle_url,
|
||||
},
|
||||
];
|
||||
for (const params of testCases) {
|
||||
promise_test(async () => {
|
||||
const urn_uuid = params.prefix + "020111b3-437a-4c5c-ae07-adb6bbffb720";
|
||||
const p = expect_violation();
|
||||
const script = document.createElement("script");
|
||||
script.src = urn_uuid;
|
||||
document.body.appendChild(script);
|
||||
const e = await p;
|
||||
// Currently Chromium is reporting the bundle URL.
|
||||
// TODO(crbug.com/1208659): Consider deeper integration with CSP for
|
||||
// providing the both URLs.
|
||||
assert_equals(e.blockedURI, params.bundle_url);
|
||||
assert_equals(e.violatedDirective, "script-src-elem");
|
||||
}, "URL matching of script-src CSP should be done based on the bundle URL " +
|
||||
`when the subresource URL is ${params.prefix} URL.`);
|
||||
|
||||
promise_test(async () => {
|
||||
const urn_uuid = params.prefix + "429fcc4e-0696-4bad-b099-ee9175f023ae";
|
||||
const p = expect_violation();
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = urn_uuid;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
iframe.addEventListener("load", resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
const e = await p;
|
||||
// Currently Chromium is reporting the bundle URL.
|
||||
// TODO(crbug.com/1208659): Consider deeper integration with CSP for
|
||||
// providing the both URLs.
|
||||
assert_equals(e.blockedURI, params.bundle_url);
|
||||
assert_equals(e.violatedDirective, "frame-src");
|
||||
|
||||
// Make sure that the blocked iframe load is finished.
|
||||
await load_promise;
|
||||
|
||||
// The blocked iframe is cross-origin. So accessing
|
||||
// iframe.contentWindow.location should throw a SecurityError.
|
||||
assert_throws_dom("SecurityError", () => {
|
||||
iframe.contentWindow.location.href;
|
||||
});
|
||||
}, "URL matching of frame-src CSP should be done based on the bundle URL " +
|
||||
`when the frame URL is ${params.prefix} URL.`);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
const retrieve_report_url =
|
||||
"/reporting/resources/report.py?op=retrieve_report&timeout=3&reportID=" +
|
||||
getReportID();
|
||||
const reports = await (await fetch(retrieve_report_url)).json();
|
||||
sortReportsByEffectiveDirective(reports);
|
||||
|
||||
assert_equals(reports.length, 3, "Report count.");
|
||||
|
||||
assert_equals(reports[0].body.blockedURL, uuid_bundle_url);
|
||||
assert_equals(reports[0].body.effectiveDirective, "frame-src");
|
||||
|
||||
assert_equals(
|
||||
reports[1].body.blockedURL,
|
||||
"https://web-platform.test:8444/web-bundle/resources/wbn/fail.png"
|
||||
);
|
||||
assert_equals(reports[1].body.effectiveDirective, "img-src");
|
||||
|
||||
assert_equals(reports[2].body.blockedURL, uuid_bundle_url);
|
||||
assert_equals(reports[2].body.effectiveDirective, "script-src-elem");
|
||||
}, "Check the CSP violation reports.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSP blocks WebBundle</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
default-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/relative-url-file.js
|
||||
https://web-platform.test:8444/resources/testharness.js
|
||||
https://web-platform.test:8444/resources/testharnessreport.js
|
||||
https://web-platform.test:8444/web-bundle/resources/test-helpers.js
|
||||
'unsafe-inline';
|
||||
img-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/pass.png;"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
// This bundle should be blocked because its URL is not listed in CSP directive.
|
||||
const bundle_url =
|
||||
"https://web-platform.test:8444/web-bundle/resources/wbn/relative-url.wbn";
|
||||
|
||||
const subresource_url =
|
||||
"https://web-platform.test:8444/web-bundle/resources/wbn/relative-url-file.js";
|
||||
|
||||
promise_test(() => {
|
||||
// if a WebBundle is blocked by CSP,
|
||||
// - A request for the WebBundle should fail.
|
||||
// - A subresource request associated with the bundle should fail.
|
||||
// - A window.load should be fired. In other words, any request shouldn't remain
|
||||
// pending forever.
|
||||
|
||||
const window_load = new Promise((resolve) => {
|
||||
window.addEventListener("load", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
const script_webbundle = createWebBundleElement(bundle_url, [
|
||||
subresource_url,
|
||||
]);
|
||||
const webbundle_error = new Promise((resolve) => {
|
||||
script_webbundle.addEventListener("error", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
document.body.appendChild(script_webbundle);
|
||||
|
||||
const script_js = document.createElement("script");
|
||||
script_js.src = subresource_url;
|
||||
const script_js_error = new Promise((resolve) => {
|
||||
script_js.addEventListener("error", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
document.body.appendChild(script_js);
|
||||
|
||||
return Promise.all([window_load, webbundle_error, script_js_error]);
|
||||
}, "WebBundle and subresource loadings should fail when CSP blocks a WebBundle");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
On-going subresource loading should fail immediately when the web bundle
|
||||
element is removed
|
||||
</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
const element = createWebBundleElement(
|
||||
"/xhr/resources/delay.py?ms=100000",
|
||||
["/xhr/resources/dummy"]
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
const waitUntilFail = new Promise((resolve) => {
|
||||
fetch("/xhr/resources/dummy").then(() => {}, resolve);
|
||||
});
|
||||
document.body.removeChild(element);
|
||||
await waitUntilFail;
|
||||
}, "On-going subresource loading should fail immediately when the element is " + "removed.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<title>WebBundle subresource loading with script API and invalid JSON</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(
|
||||
() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
},
|
||||
{ allow_uncaught_exception: true }
|
||||
);
|
||||
promise_test((t) => {
|
||||
const script = document.createElement("script");
|
||||
script.type = "webbundle";
|
||||
script.textContent = "invalid json";
|
||||
return new Promise((resolve, reject) => {
|
||||
script.onload = () => reject(script);
|
||||
script.onerror = () => reject(script);
|
||||
window.onerror = function (message, url, line, col, error) {
|
||||
assert_equals(error.name, "SyntaxError");
|
||||
resolve(script);
|
||||
};
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}, "Invalid JSON rule should throw a SyntaxError on the window.");
|
||||
promise_test((t) => {
|
||||
const script = document.createElement("script");
|
||||
script.type = "webbundle";
|
||||
const json_rule = { resources: [] };
|
||||
script.textContent = JSON.stringify(json_rule);
|
||||
return new Promise((resolve, reject) => {
|
||||
script.onload = () => reject(script);
|
||||
script.onerror = () => reject(script);
|
||||
window.onerror = function (message, url, line, col, error) {
|
||||
assert_equals(error.name, "TypeError");
|
||||
resolve(script);
|
||||
};
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}, "JSON rule with a type error should throw a TypeError on the window.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Accept: request header in webbundle requests</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/accept-header-test.js"></script>
|
||||
</body>
|
|
@ -1,34 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>COEP for WebBundle subresource loading</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/origin.html#coep" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`corp.wbn` includes three subresources:
|
||||
a. `no-corp.js`, which doesn't include a Cross-Origin-Resource-Policy response header.
|
||||
b. `corp-same-origin.js`, which includes a Cross-Origin-Resource-Policy: same-origin response header.
|
||||
c. `corp-cross-origin.js`, which includes a Cross-Origin-Resource-Policy: cross-origin response header.
|
||||
-->
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn"
|
||||
resources="https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/no-corp.js
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-same-origin.js
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-cross-origin.js
|
||||
urn:uuid:5eafff38-e0a0-4661-bde0-434255aa9d93
|
||||
urn:uuid:7e13b47a-8b91-4a0e-997c-993a5e2f3a34
|
||||
urn:uuid:86d5b696-8867-4454-8b07-51239a0817f7"
|
||||
/>
|
||||
<script src="resources/coep-test.js"></script>
|
||||
</body>
|
|
@ -1 +0,0 @@
|
|||
Cross-Origin-Embedder-Policy: require-corp
|
|
@ -1,34 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CORP for WebBundle subresource loading</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#cors-and-corp-for-subresource-requests" />
|
||||
<link rel="help" href="https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`corp.wbn` includes three subresources:
|
||||
a. `no-corp.js`, which doesn't include a Cross-Origin-Resource-Policy response header.
|
||||
b. `corp-same-origin.js`, which includes a Cross-Origin-Resource-Policy: same-origin response header.
|
||||
c. `corp-cross-origin.js`, which includes a Cross-Origin-Resource-Policy: cross-origin response header.
|
||||
-->
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn"
|
||||
resources="https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/no-corp.js
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-same-origin.js
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-cross-origin.js
|
||||
urn:uuid:5eafff38-e0a0-4661-bde0-434255aa9d93
|
||||
urn:uuid:7e13b47a-8b91-4a0e-997c-993a5e2f3a34
|
||||
urn:uuid:86d5b696-8867-4454-8b07-51239a0817f7"
|
||||
/>
|
||||
<script src="resources/corp-test.js"></script>
|
||||
</body>
|
|
@ -1,60 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Cross origin WebBundle subresource loading (error case)</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/no-cors/cross-origin.wbn,
|
||||
which is served *without* an Access-Control-Allow-Origin response header.
|
||||
|
||||
`cross-origin.wbn` includes two subresources:
|
||||
a. `resource.cors.js`, which includes an Access-Control-Allow-Origin response header.
|
||||
b. `resource.no-cors.js`, which doesn't include an Access-Control-Allow-Origin response header.
|
||||
-->
|
||||
<script>
|
||||
promise_test(async () => {
|
||||
const prefix =
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/no-cors/";
|
||||
const resources = [
|
||||
prefix + "resource.cors.js",
|
||||
prefix + "resource.no-cors.js",
|
||||
];
|
||||
for (const crossorigin_attribute_value of [
|
||||
undefined, // crossorigin attribute is not set
|
||||
"anonymous",
|
||||
"use-credentials",
|
||||
]) {
|
||||
for (const version_suffix of [
|
||||
"-b1", // b1
|
||||
"", // for b2
|
||||
]) {
|
||||
const link = await addLinkAndWaitForError(
|
||||
prefix + "cross-origin" + version_suffix + ".wbn",
|
||||
resources,
|
||||
crossorigin_attribute_value
|
||||
);
|
||||
|
||||
// A subresource in the bundle can not be used in any case.
|
||||
for (const resource of resources) {
|
||||
await fetchAndWaitForReject(resource);
|
||||
await addScriptAndWaitForError(resource);
|
||||
}
|
||||
link.remove();
|
||||
}
|
||||
}
|
||||
}, "Use CORS if crossorigin=anonymous or crossorigin=use-credential is specified. A cross origin bundle must not be loaded unless a server returns a valid Access-Control-Allow-Origin header.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,70 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Cross origin WebBundle subresource loading</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/cross-origin.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`cross-origin.wbn` includes two subresources:
|
||||
a. `resource.cors.json`, which includes an Access-Control-Allow-Origin response header.
|
||||
b. `resource.no-cors.json`, which doesn't include an Access-Control-Allow-Origin response header.
|
||||
-->
|
||||
<script>
|
||||
promise_test(async () => {
|
||||
const prefix =
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/";
|
||||
const resources = [
|
||||
prefix + "resource.cors.js",
|
||||
prefix + "resource.no-cors.js",
|
||||
];
|
||||
for (const crossorigin_attribute_value of [
|
||||
undefined, // crossorigin attribute is not set
|
||||
"anonymous",
|
||||
"use-credentials",
|
||||
]) {
|
||||
for (const version_suffix of [
|
||||
"-b1", // b1
|
||||
"", // for b2
|
||||
]) {
|
||||
const link = await addLinkAndWaitForLoad(
|
||||
prefix + "cross-origin" + version_suffix + ".wbn",
|
||||
resources,
|
||||
crossorigin_attribute_value
|
||||
);
|
||||
|
||||
// Can fetch a subresource which has a valid Access-Control-Allow-Origin response header.
|
||||
const response = await fetch(prefix + "resource.cors.js");
|
||||
assert_true(response.ok);
|
||||
const text = await response.text();
|
||||
assert_equals(text, "scriptLoaded('resource.cors.js');");
|
||||
|
||||
// Can not fetch a subresource which does NOT have a valid
|
||||
// Access-Control-Allow-Origin response header.
|
||||
await fetchAndWaitForReject(prefix + "resource.no-cors.js");
|
||||
|
||||
// Both subresource js can be loaded via a <script> element, which doesn't use cors.
|
||||
for (const resource of resources) {
|
||||
const scriptEvaluted = new Promise((resolve, reject) => {
|
||||
window.scriptLoaded = resolve;
|
||||
});
|
||||
const script = document.createElement("script");
|
||||
script.src = resource;
|
||||
document.body.appendChild(script);
|
||||
await scriptEvaluted;
|
||||
}
|
||||
link.remove();
|
||||
}
|
||||
}
|
||||
}, "request's mode must be cors. A server should return a valid Access-Control-Allow-Origin header if a bundle is a cross origin bundle.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,98 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
crossorigin= attribute and credentials in WebBundle subresource loading
|
||||
</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
// In this wpt, we only test request's credential mode, which controls
|
||||
// whether UA sends a credential or not.
|
||||
// We assume that a <link> element fires a load event correctly if
|
||||
// check-cookie-and-return-bundle.py returns a valid format webbundle. That
|
||||
// happens only when UA sends a credential. We don't care of the contents of
|
||||
// a bundle. That's out of scope of this wpt.
|
||||
|
||||
// See subresoruce-loading-cors{-error}.tentative.html, where we test subresource
|
||||
// loading with crossorigin= attribute, in terms of request's mode (cors or no-cors).
|
||||
|
||||
document.cookie = "milk=1";
|
||||
|
||||
// Make sure to set a cookie for a cross-origin domain from where a cross
|
||||
// origin bundle is served.
|
||||
const setCookiePromise = fetch(
|
||||
"https://{{domains[www1]}}:{{ports[https][0]}}/cookies/resources/set-cookie.py?name=milk&path=/web-bundle/subresource-loading/resources/",
|
||||
{
|
||||
mode: "no-cors",
|
||||
credentials: "include",
|
||||
}
|
||||
);
|
||||
|
||||
const same_origin_bundle = "./resources/check-cookie-and-return-bundle.py";
|
||||
const cross_origin_bundle = "https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/subresource-loading/resources/check-cookie-and-return-bundle.py";
|
||||
|
||||
promise_test(async () => {
|
||||
const link = document.createElement("link");
|
||||
link.rel = "webbundle";
|
||||
link.href = same_origin_bundle;
|
||||
await addElementAndWaitForLoad(link);
|
||||
link.remove()
|
||||
}, "'no crossorigin attribute' should send a credential to a same origin bundle");
|
||||
|
||||
promise_test(async () => {
|
||||
await setCookiePromise;
|
||||
const link = document.createElement("link");
|
||||
link.rel = "webbundle";
|
||||
link.href = cross_origin_bundle;
|
||||
await addElementAndWaitForError(link);
|
||||
link.remove()
|
||||
}, "'no crossorigin attribute' should not send a credential to a cross origin bundle");
|
||||
|
||||
promise_test(async () => {
|
||||
const link = document.createElement("link");
|
||||
link.rel = "webbundle";
|
||||
link.href = same_origin_bundle;
|
||||
link.crossOrigin = "anonymous";
|
||||
await addElementAndWaitForLoad(link);
|
||||
link.remove()
|
||||
}, "'anonymous' should send a credential to a same origin bundle");
|
||||
|
||||
promise_test(async () => {
|
||||
await setCookiePromise;
|
||||
const link = document.createElement("link");
|
||||
link.rel = "webbundle";
|
||||
link.href = cross_origin_bundle;
|
||||
link.crossOrigin = "anonymous";
|
||||
await addElementAndWaitForError(link);
|
||||
link.remove()
|
||||
}, "'anonymous' should not send a credential to a cross origin bundle");
|
||||
|
||||
promise_test(async () => {
|
||||
const link = document.createElement("link");
|
||||
link.rel = "webbundle";
|
||||
link.href = same_origin_bundle;
|
||||
link.crossOrigin = "use-credentials";
|
||||
await addElementAndWaitForLoad(link);
|
||||
link.remove()
|
||||
}, "'use-credentials' should send a credential to a same origin bundle");
|
||||
|
||||
promise_test(async () => {
|
||||
await setCookiePromise;
|
||||
const link = document.createElement("link");
|
||||
link.rel = "webbundle";
|
||||
link.href = cross_origin_bundle;
|
||||
link.crossOrigin = "use-credentials";
|
||||
await addElementAndWaitForLoad(link);
|
||||
link.remove()
|
||||
}, "'use-credentials' should send a credential to a cross origin bundle");
|
||||
</script>
|
||||
</body>
|
|
@ -1,110 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSP for subresource WebBundle (allowed cases)</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
script-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/urn-uuid.wbn
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn
|
||||
https://web-platform.test:8444/resources/testharness.js
|
||||
https://web-platform.test:8444/resources/testharnessreport.js
|
||||
'unsafe-inline';
|
||||
img-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/pass.png;
|
||||
frame-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/urn-uuid.wbn
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn"
|
||||
>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link rel="webbundle" href="../resources/wbn/subresource.wbn"
|
||||
resources="https://web-platform.test:8444/web-bundle/resources/wbn/pass.png" />
|
||||
<link rel="webbundle" href="../resources/wbn/urn-uuid.wbn"
|
||||
resources="urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720
|
||||
urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae" />
|
||||
<link rel="webbundle" href="../resources/wbn/uuid-in-package.wbn"
|
||||
resources="uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
|
||||
uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae" />
|
||||
<script>
|
||||
promise_test(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = document.createElement('img');
|
||||
img.src = 'https://web-platform.test:8444/web-bundle/resources/wbn/pass.png';
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
}, 'URL matching of CSP should be done based on the subresource URL ' +
|
||||
'when the subresource URL is HTTPS URL.');
|
||||
|
||||
promise_test(async () => {
|
||||
const result = await new Promise((resolve) => {
|
||||
// This function will be called from the script.
|
||||
window.report_result = resolve;
|
||||
const script = document.createElement('script');
|
||||
script.src = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
assert_equals(result, 'OK');
|
||||
}, 'URL matching of script-src CSP should be done based on the bundle URL ' +
|
||||
'when the subresource URL is urn:uuid URL.');
|
||||
|
||||
promise_test(async () => {
|
||||
const result = await new Promise((resolve) => {
|
||||
// This function will be called from the script.
|
||||
window.report_result = resolve;
|
||||
const script = document.createElement('script');
|
||||
script.src = 'uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
assert_equals(result, 'OK');
|
||||
}, 'URL matching of script-src CSP should be done based on the bundle URL ' +
|
||||
'when the subresource URL is uuid-in-package: URL.');
|
||||
|
||||
promise_test(async () => {
|
||||
const frame_url = 'urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = frame_url;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
iframe.addEventListener('load', resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
await load_promise;
|
||||
assert_equals(
|
||||
await evalInIframe(iframe, 'location.href'),
|
||||
frame_url);
|
||||
}, 'URL matching of frame-src CSP should be done based on the bundle URL ' +
|
||||
'when the frame URL is urn:uuid URL.');
|
||||
|
||||
promise_test(async () => {
|
||||
const frame_url = 'uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = frame_url;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
iframe.addEventListener('load', resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
await load_promise;
|
||||
assert_equals(
|
||||
await evalInIframe(iframe, 'location.href'),
|
||||
frame_url);
|
||||
}, 'URL matching of frame-src CSP should be done based on the bundle URL ' +
|
||||
'when the frame URL is uuid-in-package: URL.');
|
||||
|
||||
async function evalInIframe(iframe, code) {
|
||||
const message_promise = new Promise((resolve) => {
|
||||
window.addEventListener(
|
||||
'message',
|
||||
(e) => { resolve(e.data); },
|
||||
{ once : true });
|
||||
});
|
||||
iframe.contentWindow.postMessage(code,'*');
|
||||
return message_promise;
|
||||
}
|
||||
</script>
|
||||
</body>
|
|
@ -1,158 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSP for subresource WebBundle (blocked cases)</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
script-src
|
||||
urn:
|
||||
https://web-platform.test:8444/resources/testharness.js
|
||||
https://web-platform.test:8444/resources/testharnessreport.js
|
||||
'unsafe-inline';
|
||||
img-src
|
||||
https://web-platform.test:8444/web-bundle/resources/wbn/subresource.wbn;
|
||||
frame-src
|
||||
urn:;
|
||||
report-to
|
||||
csp-group"
|
||||
>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link rel="webbundle" href="../resources/wbn/subresource.wbn"
|
||||
resources="https://web-platform.test:8444/web-bundle/resources/wbn/fail.png" />
|
||||
<link rel="webbundle" href="../resources/wbn/urn-uuid.wbn"
|
||||
resources="urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720
|
||||
urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae" />
|
||||
<link rel="webbundle" href="../resources/wbn/uuid-in-package.wbn"
|
||||
resources="uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720
|
||||
uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae" />
|
||||
<script>
|
||||
const urn_bundle_url = 'https://web-platform.test:8444/web-bundle/resources/wbn/urn-uuid.wbn';
|
||||
const uuid_bundle_url = 'https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn';
|
||||
|
||||
function expect_violation() {
|
||||
return new Promise(resolve => {
|
||||
document.addEventListener('securitypolicyviolation', (e) => {
|
||||
e.stopPropagation();
|
||||
resolve(e);
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function getReportID() {
|
||||
const cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
const name_value = cookies[i].split('=');
|
||||
const cookieName = name_value[0].trim();
|
||||
if (cookieName === 'csp-blocked-report-id') {
|
||||
return name_value[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sortReportsByEffectiveDirective(reports) {
|
||||
reports.sort((report1, report2) =>
|
||||
report1.body.effectiveDirective.localeCompare(report2.body.effectiveDirective)
|
||||
|| report1.body.blockedURL.localeCompare(report2.body.blockedURL)
|
||||
);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
const p = expect_violation();
|
||||
const img = document.createElement('img');
|
||||
const error_promise = new Promise(resolve => {
|
||||
img.onerror = resolve;
|
||||
});
|
||||
img.src = 'https://web-platform.test:8444/web-bundle/resources/wbn/fail.png';
|
||||
document.body.appendChild(img);
|
||||
const e = await p;
|
||||
assert_equals(e.blockedURI, img.src);
|
||||
await error_promise;
|
||||
}, 'URL matching of CSP should be done based on the subresource URL, ' +
|
||||
'not on the bundle URL, when the subresource URL is HTTPS URL.');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
prefix: 'urn:uuid:',
|
||||
bundle_url: urn_bundle_url
|
||||
},
|
||||
{
|
||||
prefix: 'uuid-in-package:',
|
||||
bundle_url: uuid_bundle_url
|
||||
}
|
||||
];
|
||||
for (const params of testCases) {
|
||||
|
||||
promise_test(async () => {
|
||||
const urn_uuid = params.prefix + '020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const p = expect_violation();
|
||||
const script = document.createElement('script');
|
||||
script.src = urn_uuid;
|
||||
document.body.appendChild(script);
|
||||
const e = await p;
|
||||
// Currently Chromium is reporting the bundle URL.
|
||||
// TODO(crbug.com/1208659): Consider deeper integration with CSP for
|
||||
// providing the both URLs.
|
||||
assert_equals(e.blockedURI, params.bundle_url);
|
||||
assert_equals(e.violatedDirective, 'script-src-elem');
|
||||
}, 'URL matching of script-src CSP should be done based on the bundle URL ' +
|
||||
`when the subresource URL is ${params.prefix} URL.`);
|
||||
|
||||
promise_test(async () => {
|
||||
const urn_uuid = params.prefix + '429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const p = expect_violation();
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = urn_uuid;
|
||||
const load_promise = new Promise(resolve => {
|
||||
iframe.addEventListener('load', resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
const e = await p;
|
||||
// Currently Chromium is reporting the bundle URL.
|
||||
// TODO(crbug.com/1208659): Consider deeper integration with CSP for
|
||||
// providing the both URLs.
|
||||
assert_equals(e.blockedURI, params.bundle_url);
|
||||
assert_equals(e.violatedDirective, 'frame-src');
|
||||
|
||||
// Make sure that the blocked iframe load is finished.
|
||||
await load_promise;
|
||||
|
||||
// The blocked iframe is cross-origin. So accessing
|
||||
// iframe.contentWindow.location should throw a SecurityError.
|
||||
assert_throws_dom(
|
||||
"SecurityError",
|
||||
() => { iframe.contentWindow.location.href; });
|
||||
}, 'URL matching of frame-src CSP should be done based on the bundle URL ' +
|
||||
`when the frame URL is ${params.prefix} URL.`);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
const retrieve_report_url =
|
||||
"/reporting/resources/report.py?op=retrieve_report&timeout=3&reportID=" +
|
||||
getReportID();
|
||||
const reports = await (await fetch(retrieve_report_url)).json();
|
||||
sortReportsByEffectiveDirective(reports);
|
||||
|
||||
assert_equals(reports.length, 5, "Report count.");
|
||||
|
||||
assert_equals(reports[0].body.blockedURL, urn_bundle_url);
|
||||
assert_equals(reports[0].body.effectiveDirective, 'frame-src');
|
||||
assert_equals(reports[1].body.blockedURL, uuid_bundle_url);
|
||||
assert_equals(reports[1].body.effectiveDirective, 'frame-src');
|
||||
|
||||
assert_equals(
|
||||
reports[2].body.blockedURL,
|
||||
'https://web-platform.test:8444/web-bundle/resources/wbn/fail.png');
|
||||
assert_equals(reports[2].body.effectiveDirective, 'img-src',);
|
||||
|
||||
assert_equals(reports[3].body.blockedURL, urn_bundle_url);
|
||||
assert_equals(reports[3].body.effectiveDirective, 'script-src-elem');
|
||||
assert_equals(reports[4].body.blockedURL, uuid_bundle_url);
|
||||
assert_equals(reports[4].body.effectiveDirective, 'script-src-elem');
|
||||
}, 'Check the CSP violation reports.');
|
||||
</script>
|
||||
</body>
|
|
@ -1,119 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>A link element with rel="webbundle"</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link id="link_empty" />
|
||||
<link id="link_web_bundle_1" rel="webbundle" />
|
||||
<link id="link_web_bundle_2" rel="webbundle" resources="foo" />
|
||||
<link id="link_web_bundle_3" rel="webbundle" scopes="bar" />
|
||||
<script>
|
||||
test(() => {
|
||||
assert_false(
|
||||
"resources" in Element.prototype,
|
||||
"resources must not be defined on Element prototype"
|
||||
);
|
||||
assert_true(
|
||||
"resources" in HTMLLinkElement.prototype,
|
||||
"resources must be defined on HTMLLinkElement prototype"
|
||||
);
|
||||
}, "resources must be defined on HTMLLinkElement prototype");
|
||||
|
||||
test(() => {
|
||||
assert_false(
|
||||
"scopes" in Element.prototype,
|
||||
"scopes must not be defined on Element prototype"
|
||||
);
|
||||
assert_true(
|
||||
"scopes" in HTMLLinkElement.prototype,
|
||||
"scopes must be defined on HTMLLinkElement prototype"
|
||||
);
|
||||
}, "scopes must be defined on HTMLLinkElement prototype");
|
||||
|
||||
test(() => {
|
||||
const link = document.createElement("link");
|
||||
assert_true(link.relList.supports("webbundle"));
|
||||
}, "webbundle must be a supported token of a link element's relList");
|
||||
|
||||
test(() => {
|
||||
const link_web_bundle = document.querySelector("#link_web_bundle_1");
|
||||
assert_equals(
|
||||
link_web_bundle.getAttribute("rel"),
|
||||
"webbundle",
|
||||
"rel attribute must return webbundle"
|
||||
);
|
||||
assert_true(
|
||||
link_web_bundle.relList.contains("webbundle"),
|
||||
"relList must contain webbundle for <link rel=webbundle>."
|
||||
);
|
||||
assert_false(
|
||||
document.querySelector("#link_empty").relList.contains("webbundle"),
|
||||
"relList must not contain webbundle for <link>"
|
||||
);
|
||||
}, "relList must contain webbundle if rel attribute contains it");
|
||||
|
||||
test(() => {
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_1").getAttribute("resources"),
|
||||
null,
|
||||
"resources attribute must return null when the attribute is not given"
|
||||
);
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_2").getAttribute("resources"),
|
||||
"foo",
|
||||
"resources attribute must return the specified value"
|
||||
);
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_2").getAttribute("scopes"),
|
||||
null,
|
||||
"scopes attribute must return null when the attribute is not given"
|
||||
);
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_3").getAttribute("scopes"),
|
||||
"bar",
|
||||
"scopes attribute must return the specified value"
|
||||
);
|
||||
// TODO: Test more variant of resoruces attribute values.
|
||||
}, "resoruces and scopes attribute must return null or specified value");
|
||||
|
||||
test(() => {
|
||||
const link = document.createElement("link");
|
||||
assert_class_string(link.resources, "DOMTokenList");
|
||||
assert_equals(
|
||||
String(link.resources.value),
|
||||
"",
|
||||
"resources.value should return the empty list for an undefined resources attribute"
|
||||
);
|
||||
link.setAttribute(
|
||||
"resources",
|
||||
"https://test1.example.com https://test2.example.com "
|
||||
);
|
||||
assert_array_equals(link.resources, [
|
||||
"https://test1.example.com",
|
||||
"https://test2.example.com"
|
||||
]);
|
||||
}, "resources must be DOMTokenList");
|
||||
|
||||
test(() => {
|
||||
const link = document.createElement("link");
|
||||
assert_class_string(link.scopes, "DOMTokenList");
|
||||
assert_equals(
|
||||
String(link.scopes.value),
|
||||
"",
|
||||
"scopes.value should return the empty list for an undefined scopes attribute"
|
||||
);
|
||||
link.setAttribute(
|
||||
"scopes",
|
||||
"https://test1.example.com https://test2.example.com "
|
||||
);
|
||||
assert_array_equals(link.scopes, [
|
||||
"https://test1.example.com",
|
||||
"https://test2.example.com"
|
||||
]);
|
||||
}, "scopes must be DOMTokenList");
|
||||
</script>
|
||||
</body>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>On-going subresource loading should fail immediately when the web bundle element is removed</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/element-removal-test.js"></script>
|
||||
</body>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>A nested bundle is not supported</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<link rel="webbundle" href="https://web-platform.test:8444/web-bundle/resources/wbn/nested-main.wbn"
|
||||
resources="https://web-platform.test:8444/web-bundle/resources/wbn/nested-sub.wbn" />
|
||||
<script src="resources/nested-bundle-test.js"></script>
|
||||
</body>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching failed due to a network error</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/network-error-test.sub.js"></script>
|
||||
</body>
|
|
@ -1,92 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>A link element with rel="webbundle" in no secure context</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link id="link_empty" />
|
||||
<link id="link_web_bundle_1" rel="webbundle" />
|
||||
<link id="link_web_bundle_2" rel="webbundle" resources="foo" />
|
||||
<link id="link_web_bundle_3" rel="webbundle" scopes="bar" />
|
||||
<script>
|
||||
test(() => {
|
||||
assert_false(
|
||||
"resources" in Element.prototype,
|
||||
"resources must not be defined on Element prototype"
|
||||
);
|
||||
assert_false(
|
||||
"resources" in HTMLLinkElement.prototype,
|
||||
"resources must not be defined on HTMLLinkElement prototype"
|
||||
);
|
||||
}, "resources must not be defined on HTMLLinkElement prototype in no secure context");
|
||||
|
||||
test(() => {
|
||||
assert_false(
|
||||
"scopes" in Element.prototype,
|
||||
"scopes must not be defined on Element prototype"
|
||||
);
|
||||
assert_false(
|
||||
"scopes" in HTMLLinkElement.prototype,
|
||||
"scopes must not be defined on HTMLLinkElement prototype"
|
||||
);
|
||||
}, "scopes must not be defined on HTMLLinkElement prototype in no secure context");
|
||||
|
||||
test(() => {
|
||||
const link = document.createElement("link");
|
||||
assert_false(link.relList.supports("webbundle"));
|
||||
}, "webbundle must not be a supported token of a link element's relList");
|
||||
|
||||
test(() => {
|
||||
const link_web_bundle = document.querySelector("#link_web_bundle_1");
|
||||
assert_equals(
|
||||
link_web_bundle.getAttribute("rel"),
|
||||
"webbundle",
|
||||
"rel attribute must return webbundle"
|
||||
);
|
||||
assert_true(
|
||||
link_web_bundle.relList.contains("webbundle"),
|
||||
"relList must contain webbundle for <link rel=webbundle>."
|
||||
);
|
||||
assert_false(
|
||||
document.querySelector("#link_empty").relList.contains("webbundle"),
|
||||
"relList must not contain webbundle for <link>"
|
||||
);
|
||||
}, "relList must contain webbundle if rel attribute contains it");
|
||||
|
||||
test(() => {
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_1").getAttribute("resources"),
|
||||
null,
|
||||
"resources attribute must return null when the attribute is not given"
|
||||
);
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_2").getAttribute("resources"),
|
||||
"foo",
|
||||
"resources attribute must return the specified value"
|
||||
);
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_2").getAttribute("scopes"),
|
||||
null,
|
||||
"scopes attribute must return null when the attribute is not given"
|
||||
);
|
||||
assert_equals(
|
||||
document.querySelector("#link_web_bundle_3").getAttribute("scopes"),
|
||||
"bar",
|
||||
"scopes attribute must return the specified value"
|
||||
);
|
||||
}, "resoruces and scopes attribute must return null or specified value");
|
||||
|
||||
test(() => {
|
||||
const link = document.createElement("link");
|
||||
assert_equals(link.resources, undefined);
|
||||
}, "resources must be undefined");
|
||||
|
||||
test(() => {
|
||||
const link = document.createElement("link");
|
||||
assert_equals(link.scopes, undefined);
|
||||
}, "scopes must be undefined");
|
||||
</script>
|
||||
</body>
|
|
@ -1,33 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="euc-jp"/>
|
||||
<title>WebBundle subresource loading with non utf-8 query encoding and encoded src</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/non-utf8-query-encoding.wbn"
|
||||
resources="https://web-platform.test:8444/web-bundle/resources/wbn/static-element/resources/script.js?x=<3D><>"
|
||||
/>
|
||||
|
||||
<script id="script" src="/web-bundle/resources/wbn/static-element/resources/script.js?x=%A4%A2"></script>
|
||||
|
||||
<script>
|
||||
// This test is using a non-ascii character whose Unicode point is U+3042.
|
||||
// URL encode (in EUC-JP) of the character is "%A4%A2".
|
||||
|
||||
const onLoadPromise = new Promise((resolve) => {
|
||||
window.addEventListener('load', resolve, false);
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
await onLoadPromise;
|
||||
assert_equals(resources_script_result, 'loaded from webbundle');
|
||||
}, "Query encoding should be correctly handled in non utf-8 encoding " +
|
||||
"document when script src is encoded.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="euc-jp"/>
|
||||
<title>WebBundle subresource loading with non utf-8 query encoding</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/non-utf8-query-encoding.wbn"
|
||||
resources="https://web-platform.test:8444/web-bundle/resources/wbn/static-element/resources/script.js?x=<3D><>"
|
||||
/>
|
||||
|
||||
<script id="script" src="/web-bundle/resources/wbn/static-element/resources/script.js?x=<3D><>"></script>
|
||||
|
||||
<script>
|
||||
const onLoadPromise = new Promise((resolve) => {
|
||||
window.addEventListener('load', resolve, false);
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
await onLoadPromise;
|
||||
assert_equals(resources_script_result, 'loaded from webbundle');
|
||||
}, "Query encoding should be correctly handled in non utf-8 encoding document.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching failed due to not found error</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/not-found-test.js"></script>
|
||||
</body>
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Path restriction on subresource loading with WebBundles (b1 version)</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/path-restriction-b1.wbn"
|
||||
resources="/web-bundle/resources/wbn/resource.js
|
||||
/web-bundle/resources/wbn/sub/resource.js
|
||||
/web-bundle/resources/wbn-resource.js
|
||||
/web-bundle/resources/wbn1/resource.js
|
||||
/web-bundle/resources/other/resource.js
|
||||
/web-bundle/resources/resource.js"
|
||||
/>
|
||||
<script src="resources/path-restriction-test.js"></script>
|
||||
</body>
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Path restriction on subresource loading with WebBundles</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/path-restriction.wbn"
|
||||
resources="/web-bundle/resources/wbn/resource.js
|
||||
/web-bundle/resources/wbn/sub/resource.js
|
||||
/web-bundle/resources/wbn-resource.js
|
||||
/web-bundle/resources/wbn1/resource.js
|
||||
/web-bundle/resources/other/resource.js
|
||||
/web-bundle/resources/resource.js"
|
||||
/>
|
||||
/>
|
||||
<script src="resources/path-restriction-test.js"></script>
|
||||
</body>
|
|
@ -1,39 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Relative Url in cross origin web bundle</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url.wbn"
|
||||
resources="
|
||||
//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url-file.js
|
||||
//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/start-with-double-slash-cors.js
|
||||
//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/start-with-slash.js
|
||||
//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/subdirectory-path.js
|
||||
//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/starts-with-two-dots.js
|
||||
//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/starts-with-two-dots-out-of-scope.js
|
||||
" />
|
||||
<script>
|
||||
const loaded_scripts = [];
|
||||
function scriptLoaded(file) {
|
||||
loaded_scripts.push(file);
|
||||
}
|
||||
const failed_scripts = [];
|
||||
function scriptFailed(file) {
|
||||
failed_scripts.push(file);
|
||||
}
|
||||
</script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url-file.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/start-with-double-slash-cors.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/start-with-slash.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/subdirectory-path.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/starts-with-two-dots.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/starts-with-two-dots-out-of-scope.js"
|
||||
onerror="scriptFailed('starts-with-two-dots-out-of-scope.js')"></script>
|
||||
|
||||
<script src="resources/relative-url-in-web-bundle-cors-test.js"></script>
|
||||
</body>
|
|
@ -1,39 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Relative Url in web bundle</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/relative-url.wbn"
|
||||
resources="
|
||||
../resources/wbn/relative-url-file.js
|
||||
../resources/wbn/relative-url/start-with-double-slash.js
|
||||
../resources/wbn/relative-url/start-with-slash.js
|
||||
../resources/wbn/relative-url/subdirectory-path.js
|
||||
../resources/wbn/starts-with-two-dots.js
|
||||
../resources/starts-with-two-dots-out-of-scope.js
|
||||
" />
|
||||
<script>
|
||||
const loaded_scripts = [];
|
||||
function scriptLoaded(file) {
|
||||
loaded_scripts.push(file);
|
||||
}
|
||||
const failed_scripts = [];
|
||||
function scriptFailed(file) {
|
||||
failed_scripts.push(file);
|
||||
}
|
||||
</script>
|
||||
<script src="../resources/wbn/relative-url-file.js"></script>
|
||||
<script src="../resources/wbn/relative-url/start-with-double-slash.js"></script>
|
||||
<script src="../resources/wbn/relative-url/start-with-slash.js"></script>
|
||||
<script src="../resources/wbn/relative-url/subdirectory-path.js"></script>
|
||||
<script src="../resources/wbn/starts-with-two-dots.js"></script>
|
||||
<script src="../resources/starts-with-two-dots-out-of-scope.js"
|
||||
onerror="scriptFailed('starts-with-two-dots-out-of-scope.js')"></script>
|
||||
|
||||
<script src="resources/relative-url-in-web-bundle-test.js"></script>
|
||||
</body>
|
|
@ -1,21 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subresource loading using relative URLs in the 'resources' and 'scopes' attributes with a base element</title>
|
||||
<base href="../resources/wbn/">
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="static-element.wbn"
|
||||
resources="static-element/resources/script.js"/>
|
||||
<script id="script" src="static-element/resources/script.js"></script>
|
||||
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="dynamic1.wbn"
|
||||
scopes="dynamic/resource"/>
|
||||
|
||||
<script src="/web-bundle/subresource-loading/resources/relative-url-with-base-test.js"></script>
|
||||
</body>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subresource loading using relative URLs in the 'resources' attribute</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/static-element.wbn"
|
||||
resources="/web-bundle/resources/wbn/static-element/resources/script.js"/>
|
||||
<script id="script" src="/web-bundle/resources/wbn/static-element/resources/script.js"></script>
|
||||
|
||||
<script src="resources/relative-url-test.js"></script>
|
||||
</body>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Request's destination must be "webbundle" with the link-based API</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/request-destination-test.sub.js"></script>
|
||||
</body>
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Resource timing attributes are consistent for the same-origin subresources.</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/resource-timing-attributes-consistent-test.sub.js"></script>
|
||||
</body>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Resource timing entries present for urn:uuid resources</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/resource-timing-test.js"></script>
|
||||
</body>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching and the inner resouirce fetching should skip service worker</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/service-worker-controlled-test.js"></script>
|
||||
</body>
|
|
@ -1,32 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>WebBundle subresource loading for static elements with a base element</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<base href="../resources/wbn/static-element/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../static-element.wbn"
|
||||
resources="
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/script.js
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style.css
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-file.css
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-tag.css"
|
||||
scopes="https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/scopes/"
|
||||
/>
|
||||
<style type="text/css">
|
||||
@import 'resources/style-imported-from-tag.css';
|
||||
@import 'scopes/style-imported-from-tag.css';
|
||||
</style>
|
||||
<link href="resources/style.css" rel=stylesheet>
|
||||
<link href="scopes/style.css" rel=stylesheet>
|
||||
<script src="resources/script.js"></script>
|
||||
<script src="scopes/script.js"></script>
|
||||
<script src="out-of-scope/script.js"></script>
|
||||
|
||||
<script src="/web-bundle/subresource-loading/resources/static-element-with-test.js"></script>
|
||||
</body>
|
|
@ -1,31 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>WebBundle subresource loading for static elements</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<link
|
||||
rel="webbundle"
|
||||
href="../resources/wbn/static-element.wbn"
|
||||
resources="
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/script.js
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style.css
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-file.css
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-tag.css"
|
||||
scopes="https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/scopes/"
|
||||
/>
|
||||
<style type="text/css">
|
||||
@import '../resources/wbn/static-element/resources/style-imported-from-tag.css';
|
||||
@import '../resources/wbn/static-element/scopes/style-imported-from-tag.css';
|
||||
</style>
|
||||
<link href="../resources/wbn/static-element/resources/style.css" rel=stylesheet>
|
||||
<link href="../resources/wbn/static-element/scopes/style.css" rel=stylesheet>
|
||||
<script src="../resources/wbn/static-element/resources/script.js"></script>
|
||||
<script src="../resources/wbn/static-element/scopes/script.js"></script>
|
||||
<script src="../resources/wbn/static-element/out-of-scope/script.js"></script>
|
||||
|
||||
<script src="resources/static-element-with-test.js"></script>
|
||||
</body>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subframe loading from Web Bundles</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/subframe-from-web-bundle-test.js"></script>
|
||||
</body>
|
|
@ -1,27 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subresource loading with link rel="webbundle"</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'link';
|
||||
</script>
|
||||
<body>
|
||||
<link id="link-web-bundle" rel="webbundle" href="../resources/wbn/subresource.wbn" resources="https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js
|
||||
https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/submodule.js" />
|
||||
<script src="resources/subresource-load-test.sub.js"></script>
|
||||
<script>
|
||||
promise_test(async () => {
|
||||
const wbn_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/subresource.wbn?test-resources-update';
|
||||
const resource_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/submodule.js';
|
||||
const element = await addWebBundleElementAndWaitForLoad(wbn_url, /*resources=*/[]);
|
||||
changeWebBundleResourcesInPlace(element, [resource_url]);
|
||||
const resp = await fetch(resource_url, { cache: 'no-store' });
|
||||
assert_true(resp.ok);
|
||||
assert_equals(performance.getEntriesByName(wbn_url).length, 1);
|
||||
document.body.removeChild(element);
|
||||
}, 'Updating resource attribute should not reload the bundle');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<title>A nested bundle is not supported</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "/web-bundle/resources/wbn/nested-main.wbn",
|
||||
"resources": ["/web-bundle/resources/wbn/nested-sub.wbn"]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
const response = await fetch("/web-bundle/resources/wbn/nested-sub.wbn");
|
||||
assert_true(response.ok);
|
||||
}, "A nested bundle can be fetched");
|
||||
|
||||
promise_test(async () => {
|
||||
await addWebBundleElementAndWaitForError(
|
||||
"/web-bundle/resources/wbn/nested-sub.wbn",
|
||||
["/web-bundle/resources/wbn/root.js"]
|
||||
);
|
||||
const response = await fetch("/web-bundle/resources/wbn/root.js");
|
||||
assert_false(response.ok);
|
||||
}, "Subresources in a nested bundle should not be loaded");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching failed due to a network error</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
// This test uses a non-existing WebBundle from a non-existent host, which makes
|
||||
// Web Bundle fetching fail due to a network error. The intent of is to check if
|
||||
// failing to fetch a WebBundle also makes subresource fetch requests fail.
|
||||
promise_test(async () => {
|
||||
const prefix = "https://{{hosts[][nonexistent]}}/";
|
||||
const resources = [prefix + "resource.js"];
|
||||
await addWebBundleElementAndWaitForError(
|
||||
prefix + "non-existing.wbn",
|
||||
resources
|
||||
);
|
||||
|
||||
// Can not fetch a subresource because Web Bundle fetch failed.
|
||||
await fetchAndWaitForReject(prefix + "resource.js");
|
||||
}, "Subresource fetch requests for non-existing Web Bundle should fail.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching failed due to not found error</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
// This test uses a non-existing WebBundle,
|
||||
// /web-bundle/resources/wbn/cors/non-existing.wbn.
|
||||
// The intent of this test is to check if failing to fetch a WebBundle due to
|
||||
// not found error also makes subresource fetch requests fail.
|
||||
promise_test(async () => {
|
||||
const prefix = "/web-bundle/resources/wbn/";
|
||||
const resources = [prefix + "resource.js"];
|
||||
const element = await createWebBundleElement(
|
||||
prefix + "non-existing.wbn",
|
||||
resources
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
|
||||
// Can not fetch a subresource because Web Bundle fetch failed.
|
||||
await fetchAndWaitForReject(prefix + "resource.js");
|
||||
}, "Subresource fetch requests for non-existing Web Bundle should fail.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Path restriction on subresource loading with WebBundles</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/path-restriction.wbn",
|
||||
"resources": [
|
||||
"/web-bundle/resources/wbn/resource.js",
|
||||
"/web-bundle/resources/wbn/sub/resource.js",
|
||||
"/web-bundle/resources/wbn-resource.js",
|
||||
"/web-bundle/resources/wbn1/resource.js",
|
||||
"/web-bundle/resources/other/resource.js",
|
||||
"/web-bundle/resources/resource.js"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
const resources = [
|
||||
"/web-bundle/resources/wbn/resource.js",
|
||||
"/web-bundle/resources/wbn/sub/resource.js",
|
||||
];
|
||||
for (const resource of resources) {
|
||||
const response = await fetch(resource);
|
||||
assert_true(response.ok, resource + " should be loaded");
|
||||
}
|
||||
}, "Subresources should be loaded.");
|
||||
|
||||
promise_test(async () => {
|
||||
const resources = [
|
||||
"/web-bundle/resources/wbn-resource.js",
|
||||
"/web-bundle/resources/wbn1/resource.js",
|
||||
"/web-bundle/resources/other/resource.js",
|
||||
"/web-bundle/resources/resource.js",
|
||||
];
|
||||
for (const resource of resources) {
|
||||
const response = await fetch(resource);
|
||||
assert_false(response.ok, resource + " should not be loaded");
|
||||
}
|
||||
}, "Subresources should not be loaded due to path restriction.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,11 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Relative Url in cross origin web bundle</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
const loaded_scripts = [];
|
||||
function scriptLoaded(file) {
|
||||
loaded_scripts.push(file);
|
||||
}
|
||||
const failed_scripts = [];
|
||||
function scriptFailed(file) {
|
||||
failed_scripts.push(file);
|
||||
}
|
||||
</script>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url.wbn",
|
||||
|
@ -19,27 +34,27 @@
|
|||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
|
||||
const loaded_scripts = [];
|
||||
function scriptLoaded(file) {
|
||||
loaded_scripts.push(file);
|
||||
}
|
||||
const failed_scripts = [];
|
||||
function scriptFailed(file) {
|
||||
failed_scripts.push(file);
|
||||
}
|
||||
</script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url-file.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/start-with-double-slash-cors.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/start-with-slash.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/relative-url/subdirectory-path.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/starts-with-two-dots.js"></script>
|
||||
<script src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/starts-with-two-dots-out-of-scope.js"
|
||||
onerror="scriptFailed('starts-with-two-dots-out-of-scope.js')"></script>
|
||||
|
||||
<script src="resources/relative-url-in-web-bundle-cors-test.js"></script>
|
||||
<script
|
||||
src="//{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/starts-with-two-dots-out-of-scope.js"
|
||||
onerror="scriptFailed('starts-with-two-dots-out-of-scope.js')"
|
||||
></script>
|
||||
<script>
|
||||
promise_test(async (t) => {
|
||||
assert_array_equals(loaded_scripts, [
|
||||
"relative-url-file.js",
|
||||
"start-with-double-slash-cors.js",
|
||||
"start-with-slash.js",
|
||||
"subdirectory-path.js",
|
||||
"starts-with-two-dots.js",
|
||||
]);
|
||||
assert_array_equals(failed_scripts, [
|
||||
"starts-with-two-dots-out-of-scope.js",
|
||||
]);
|
||||
}, "Relative Url in web bundle.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,11 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Relative Url in web bundle</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
const loaded_scripts = [];
|
||||
function scriptLoaded(file) {
|
||||
loaded_scripts.push(file);
|
||||
}
|
||||
const failed_scripts = [];
|
||||
function scriptFailed(file) {
|
||||
failed_scripts.push(file);
|
||||
}
|
||||
</script>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/relative-url.wbn",
|
||||
|
@ -19,27 +34,27 @@
|
|||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
|
||||
const loaded_scripts = [];
|
||||
function scriptLoaded(file) {
|
||||
loaded_scripts.push(file);
|
||||
}
|
||||
const failed_scripts = [];
|
||||
function scriptFailed(file) {
|
||||
failed_scripts.push(file);
|
||||
}
|
||||
</script>
|
||||
<script src="../resources/wbn/relative-url-file.js"></script>
|
||||
<script src="../resources/wbn/relative-url/start-with-double-slash.js"></script>
|
||||
<script src="../resources/wbn/relative-url/start-with-slash.js"></script>
|
||||
<script src="../resources/wbn/relative-url/subdirectory-path.js"></script>
|
||||
<script src="../resources/wbn/starts-with-two-dots.js"></script>
|
||||
<script src="../resources/starts-with-two-dots-out-of-scope.js"
|
||||
onerror="scriptFailed('starts-with-two-dots-out-of-scope.js')"></script>
|
||||
|
||||
<script src="resources/relative-url-in-web-bundle-test.js"></script>
|
||||
<script
|
||||
src="../resources/starts-with-two-dots-out-of-scope.js"
|
||||
onerror="scriptFailed('starts-with-two-dots-out-of-scope.js')"
|
||||
></script>
|
||||
<script>
|
||||
promise_test(async (t) => {
|
||||
assert_array_equals(loaded_scripts, [
|
||||
"relative-url-file.js",
|
||||
"start-with-double-slash.js",
|
||||
"start-with-slash.js",
|
||||
"subdirectory-path.js",
|
||||
"starts-with-two-dots.js",
|
||||
]);
|
||||
assert_array_equals(failed_scripts, [
|
||||
"starts-with-two-dots-out-of-scope.js",
|
||||
]);
|
||||
}, "Relative Url in web bundle.");
|
||||
</script>
|
||||
</body>
|
|
@ -9,7 +9,6 @@
|
|||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = "script";
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
|
@ -1,7 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
Subresource loading using relative URLs in the 'scopes'
|
||||
</title>
|
||||
<title>Subresource loading using relative URLs in the 'scopes'</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
|
@ -11,7 +9,6 @@
|
|||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = "script";
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
@ -35,13 +32,17 @@
|
|||
}
|
||||
|
||||
async function assertResourceCanBeFetched() {
|
||||
const response = await fetch("../resources/wbn/relative-url/subdirectory-path.js");
|
||||
const response = await fetch(
|
||||
"../resources/wbn/relative-url/subdirectory-path.js"
|
||||
);
|
||||
const text = await response.text();
|
||||
assert_equals(text, "scriptLoaded('subdirectory-path.js');");
|
||||
}
|
||||
|
||||
async function assertResourceNotFound() {
|
||||
const response = await fetch("../resources/wbn/relative-url/subdirectory-path.js");
|
||||
const response = await fetch(
|
||||
"../resources/wbn/relative-url/subdirectory-path.js"
|
||||
);
|
||||
const status = await response.status;
|
||||
assert_equals(status, 404);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
Subresource loading using relative URLs in the 'resources' attribute with a
|
||||
base element
|
||||
</title>
|
||||
<base href="../resources/wbn/" />
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "static-element.wbn",
|
||||
"resources": ["static-element/resources/script.js"]
|
||||
}
|
||||
</script>
|
||||
<script id="script" src="static-element/resources/script.js"></script>
|
||||
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "dynamic1.wbn",
|
||||
"scopes": ["dynamic/resource"]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
test(() => {
|
||||
assert_equals(resources_script_result, "loaded from webbundle");
|
||||
}, "A subresource script.js should be loaded from WebBundle using the relative " + "URL and a base element.");
|
||||
|
||||
promise_test(async () => {
|
||||
const module = await import(
|
||||
"/web-bundle/resources/wbn/dynamic/resource1.js"
|
||||
);
|
||||
assert_equals(module.result, "resource1 from dynamic1.wbn");
|
||||
const module2 = await import(
|
||||
"/web-bundle/resources/wbn/dynamic/resource2.js"
|
||||
);
|
||||
assert_equals(module2.result, "resource2 from dynamic1.wbn");
|
||||
const module3 = await import(
|
||||
"/web-bundle/resources/wbn/dynamic/resource3.js"
|
||||
);
|
||||
assert_equals(module3.result, "resource3 from dynamic1.wbn");
|
||||
const module4 = await import(
|
||||
"/web-bundle/resources/wbn/dynamic/resource4.js"
|
||||
);
|
||||
assert_equals(module4.result, "resource4 from dynamic1.wbn");
|
||||
const result_promise = new Promise((resolve) => {
|
||||
// This function will be called from script.js
|
||||
window.report_result = resolve;
|
||||
});
|
||||
|
||||
const script = document.createElement("script");
|
||||
script.src = "/web-bundle/resources/wbn/dynamic/classic_script.js";
|
||||
document.body.appendChild(script);
|
||||
assert_equals(await result_promise, "classic script from network");
|
||||
}, "Subresources that start with 'resource' should be loaded from dynamic1.wbn while others from network.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
Request's destination must be "webbundle" with the script-based API
|
||||
</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
// check-sec-fetch-dest-header-and-return-bundle.py returns a valid format
|
||||
// bundle only if a 'Sec-Fetch-Dest: webbundle' header is present in a request.
|
||||
// Otherwise, returns an empty body with 400 status code.
|
||||
//
|
||||
// In this wpt, we assume that a <script> element fires a load event correctly if
|
||||
// a valid format webbundle is returned.
|
||||
|
||||
const same_origin_bundle =
|
||||
"../resources/check-sec-fetch-dest-header-and-return-bundle.py";
|
||||
const cross_origin_bundle =
|
||||
"https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/check-sec-fetch-dest-header-and-return-bundle.py";
|
||||
|
||||
promise_test(async () => {
|
||||
for (const bundle of [same_origin_bundle, cross_origin_bundle]) {
|
||||
const element = createWebBundleElement(bundle, /*resources=*/ []);
|
||||
await addElementAndWaitForLoad(element);
|
||||
element.remove();
|
||||
}
|
||||
}, '"Sec-Fetch-Dest: webbundle" header must be present in a request for a bundle'
|
||||
+ " with <script type=webbundle>.");
|
||||
|
||||
promise_test(async () => {
|
||||
const res = await fetch(same_origin_bundle);
|
||||
assert_false(res.ok);
|
||||
}, '"Sec-Fetch-Dest: webbundle" header must not be present in a fetch request' + " for a same-origin resource.");
|
||||
|
||||
promise_test(async () => {
|
||||
const res = await fetch(cross_origin_bundle);
|
||||
assert_false(res.ok);
|
||||
}, '"Sec-Fetch-Dest: webbundle" header must not be present in a fetch request' + " for a cross-origin resource.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>
|
||||
Resource timing attributes are consistent for the same-origin subresources.
|
||||
</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async (t) => {
|
||||
const bundle_url =
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic1.wbn?pipe=trickle(d0.5)";
|
||||
const script_url =
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js";
|
||||
const element = createWebBundleElement(
|
||||
"../resources/wbn/dynamic1.wbn?pipe=trickle(d0.5)",
|
||||
/*resources=*/ [script_url]
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
var script_entries = 0;
|
||||
var web_bundle_entries = 0;
|
||||
var web_bundle_entry, script_entry;
|
||||
const promise = new Promise((resolve) => {
|
||||
new PerformanceObserver(
|
||||
t.step_func((entryList) => {
|
||||
var entries = entryList.getEntriesByType("resource");
|
||||
for (var i = 0; i < entries.length; ++i) {
|
||||
if (entries[i].name === script_url) {
|
||||
script_entry = entries[i];
|
||||
script_entries++;
|
||||
}
|
||||
|
||||
if (entries[i].name === bundle_url) {
|
||||
web_bundle_entry = entries[i];
|
||||
web_bundle_entries++;
|
||||
}
|
||||
}
|
||||
|
||||
if (web_bundle_entries > 0 && script_entries > 0) {
|
||||
// Check timestamps.
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseStart,
|
||||
script_entry.requestStart + 500
|
||||
);
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseStart,
|
||||
web_bundle_entry.responseStart
|
||||
);
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseEnd,
|
||||
script_entry.responseStart
|
||||
);
|
||||
assert_greater_than_equal(
|
||||
script_entry.requestStart,
|
||||
script_entry.connectEnd
|
||||
);
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseEnd,
|
||||
script_entry.responseStart
|
||||
);
|
||||
// Check sizes.
|
||||
assert_greater_than(script_entry.encodedBodySize, 0);
|
||||
assert_equals(
|
||||
script_entry.transferSize,
|
||||
script_entry.encodedBodySize + 300
|
||||
);
|
||||
assert_equals(
|
||||
script_entry.encodedBodySize,
|
||||
script_entry.decodedBodySize
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
).observe({ entryTypes: ["resource"] });
|
||||
});
|
||||
const script = document.createElement("script");
|
||||
script.type = "module";
|
||||
script.src = script_url;
|
||||
document.body.appendChild(script);
|
||||
return promise;
|
||||
}, "Timestamp attributes filled in resource timing entries should be consistent.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>Resource timing entries present for uuid-in-package resources</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async (t) => {
|
||||
const frame_id = "uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae";
|
||||
const script_id = "uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720";
|
||||
const element = createWebBundleElement(
|
||||
"../resources/wbn/uuid-in-package.wbn",
|
||||
/*resources=*/ [frame_id, script_id]
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
let iframe_entries = 0;
|
||||
let script_entries = 0;
|
||||
// Declare the report_result function as outputting into stderr
|
||||
// because it is used in the WebBundle script to report the script load.
|
||||
window.report_result = console.error;
|
||||
const promise = new Promise((resolve) => {
|
||||
new PerformanceObserver(
|
||||
t.step_func((entryList) => {
|
||||
let entries = entryList.getEntriesByType("resource");
|
||||
for (let i = 0; i < entries.length; ++i) {
|
||||
// Ignore any entries for the test harness files if present.
|
||||
if (/testharness(report)?\.js/.test(entries[i].name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entries[i].name === frame_id) ++iframe_entries;
|
||||
if (entries[i].name === script_id) ++script_entries;
|
||||
}
|
||||
if (iframe_entries == 1 && script_entries == 1) {
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
).observe({ entryTypes: ["resource"] });
|
||||
});
|
||||
// Add iframe and the script so we get the ResourceTiming
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = frame_id;
|
||||
document.body.appendChild(iframe);
|
||||
const script = document.createElement("script");
|
||||
script.src = script_id;
|
||||
document.body.appendChild(script);
|
||||
return promise;
|
||||
}, "Each uuid-in-package resource should have exactly 1 ResourceTiming entry.");
|
||||
</script>
|
||||
</body>
|
|
@ -1,7 +0,0 @@
|
|||
promise_test(async () => {
|
||||
await addWebBundleElementAndWaitForLoad(
|
||||
'../resources/check-accept-header-and-return-bundle.py',
|
||||
/*resources=*/[]);
|
||||
},
|
||||
'"Accept:" header in a request for a bundle should contain ' +
|
||||
'application/webbundle MIME type.');
|
|
@ -1,75 +0,0 @@
|
|||
async function expectCOEPReport(func) {
|
||||
const reportsPromise = new Promise((resolve) => {
|
||||
const observer = new ReportingObserver((reports) => {
|
||||
observer.disconnect();
|
||||
resolve(reports.map(r => r.toJSON()));
|
||||
});
|
||||
observer.observe();
|
||||
});
|
||||
|
||||
await func();
|
||||
|
||||
const reports = await reportsPromise;
|
||||
assert_equals(reports.length, 1);
|
||||
assert_equals(reports[0].type, "coep");
|
||||
assert_equals(reports[0].url, location.href);
|
||||
return reports[0];
|
||||
}
|
||||
|
||||
const prefix = 'https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/';
|
||||
const no_corp_url = 'urn:uuid:5eafff38-e0a0-4661-bde0-434255aa9d93';
|
||||
const corp_same_origin_url = 'urn:uuid:7e13b47a-8b91-4a0e-997c-993a5e2f3a34';
|
||||
const corp_cross_origin_url = 'urn:uuid:86d5b696-8867-4454-8b07-51239a0817f7';
|
||||
|
||||
promise_test(async () => {
|
||||
const report = await expectCOEPReport(async () => {
|
||||
await addScriptAndWaitForError(prefix + 'no-corp.js');
|
||||
});
|
||||
assert_equals(report.body.blockedURL, prefix + 'no-corp.js');
|
||||
assert_equals(report.body.type, "corp");
|
||||
assert_equals(report.body.disposition, "enforce");
|
||||
assert_equals(report.body.destination, "script");
|
||||
}, "Cross-origin subresource without Cross-Origin-Resource-Policy: header should be blocked and generate a report.");
|
||||
|
||||
promise_test(async () => {
|
||||
await addScriptAndWaitForError(prefix + 'corp-same-origin.js');
|
||||
}, "Cross-origin subresource with Cross-Origin-Resource-Policy: same-origin should be blocked.");
|
||||
|
||||
promise_test(async () => {
|
||||
await addScriptAndWaitForExecution(prefix + 'corp-cross-origin.js');
|
||||
}, "Cross-origin subresource with Cross-Origin-Resource-Policy: cross-origin should be loaded.");
|
||||
|
||||
promise_test(async () => {
|
||||
const report = await expectCOEPReport(async () => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = no_corp_url;
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
|
||||
assert_equals(report.body.blockedURL, no_corp_url);
|
||||
assert_equals(report.body.type, "corp");
|
||||
assert_equals(report.body.disposition, "enforce");
|
||||
assert_equals(report.body.destination, "iframe");
|
||||
}, "Urn:uuid iframe without Cross-Origin-Resource-Policy: header should be blocked and generate a report.");
|
||||
|
||||
promise_test(async () => {
|
||||
const report = await expectCOEPReport(async () => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = corp_same_origin_url;
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
|
||||
assert_equals(report.body.blockedURL, corp_same_origin_url);
|
||||
assert_equals(report.body.type, "corp");
|
||||
assert_equals(report.body.disposition, "enforce");
|
||||
assert_equals(report.body.destination, "iframe");
|
||||
}, "Urn:uuid iframe with Cross-Origin-Resource-Policy: same-origin should be blocked and generate a report.");
|
||||
|
||||
promise_test(async () => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = corp_cross_origin_url;
|
||||
await addElementAndWaitForLoad(iframe);
|
||||
assert_equals(
|
||||
await evalInIframe(iframe, 'location.href'),
|
||||
corp_cross_origin_url);
|
||||
}, "Urn:uuid iframe with Cross-Origin-Resource-Policy: cross-origin should not be blocked.");
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
promise_test(async () => {
|
||||
const prefix = 'https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/';
|
||||
await addScriptAndWaitForExecution(prefix + 'no-corp.js');
|
||||
await addScriptAndWaitForError(prefix + 'corp-same-origin.js');
|
||||
await addScriptAndWaitForExecution(prefix + 'corp-cross-origin.js');
|
||||
}, "Subresource loading from WebBundles should respect Cross-Origin-Resource-Policy header.");
|
||||
|
||||
promise_test(async () => {
|
||||
const no_corp_url = 'urn:uuid:5eafff38-e0a0-4661-bde0-434255aa9d93';
|
||||
const corp_same_origin_url = 'urn:uuid:7e13b47a-8b91-4a0e-997c-993a5e2f3a34';
|
||||
const corp_cross_origin_url = 'urn:uuid:86d5b696-8867-4454-8b07-51239a0817f7';
|
||||
await iframeLocationTest(no_corp_url);
|
||||
await iframeLocationTest(corp_same_origin_url);
|
||||
await iframeLocationTest(corp_cross_origin_url);
|
||||
}, "Urn:uuid iframes should not be blocked regardless of the Cross-Origin-Resource-Policy header, if Cross-Origin-Embedder-Policy is not set.");
|
||||
|
||||
async function iframeLocationTest(url) {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = url;
|
||||
await addElementAndWaitForLoad(iframe);
|
||||
assert_equals(await evalInIframe(iframe, 'location.href'), url);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
promise_test(async () => {
|
||||
const element = createWebBundleElement(
|
||||
'/xhr/resources/delay.py?ms=100000',
|
||||
['/xhr/resources/dummy']);
|
||||
document.body.appendChild(element);
|
||||
const waitUntilFail = new Promise((resolve) => {
|
||||
fetch("/xhr/resources/dummy").then(() => {}, resolve);
|
||||
});
|
||||
document.body.removeChild(element);
|
||||
await waitUntilFail;
|
||||
},
|
||||
'On-going subresource loading should fail immediately when the element is ' +
|
||||
'removed.');
|
|
@ -1,12 +0,0 @@
|
|||
promise_test(async () => {
|
||||
const response = await fetch('/web-bundle/resources/wbn/nested-sub.wbn');
|
||||
assert_true(response.ok);
|
||||
}, 'A nested bundle can be fetched');
|
||||
|
||||
promise_test(async () => {
|
||||
await addWebBundleElementAndWaitForError(
|
||||
'/web-bundle/resources/wbn/nested-sub.wbn',
|
||||
['/web-bundle/resources/wbn/root.js']);
|
||||
const response = await fetch('/web-bundle/resources/wbn/root.js');
|
||||
assert_false(response.ok);
|
||||
}, 'Subresources in a nested bundle should not be loaded');
|
|
@ -1,15 +0,0 @@
|
|||
// This test uses a non-existing WebBundle from a non-existent host, which makes
|
||||
// Web Bundle fetching fail due to a network error. The intent of is to check if
|
||||
// failing to fetch a WebBundle also makes subresource fetch requests fail.
|
||||
promise_test(async () => {
|
||||
const prefix = 'https://{{hosts[][nonexistent]}}/';
|
||||
const resources = [
|
||||
prefix + 'resource.js',
|
||||
];
|
||||
const link = await addWebBundleElementAndWaitForError(
|
||||
prefix + 'non-existing.wbn',
|
||||
resources);
|
||||
|
||||
// Can not fetch a subresource because Web Bundle fetch failed.
|
||||
await fetchAndWaitForReject(prefix + 'resource.js');
|
||||
}, 'Subresource fetch requests for non-existing Web Bundle should fail.');
|
|
@ -1,17 +0,0 @@
|
|||
// This test uses a non-existing WebBundle,
|
||||
// /web-bundle/resources/wbn/cors/non-existing.wbn.
|
||||
// The intent of this test is to check if failing to fetch a WebBundle due to
|
||||
// not found error also makes subresource fetch requests fail.
|
||||
promise_test(async () => {
|
||||
const prefix = '/web-bundle/resources/wbn/';
|
||||
const resources = [
|
||||
prefix + 'resource.js',
|
||||
];
|
||||
const element = await createWebBundleElement(
|
||||
prefix + 'non-existing.wbn',
|
||||
resources);
|
||||
document.body.appendChild(element);
|
||||
|
||||
// Can not fetch a subresource because Web Bundle fetch failed.
|
||||
await fetchAndWaitForReject(prefix + 'resource.js');
|
||||
}, 'Subresource fetch requests for non-existing Web Bundle should fail.');
|
|
@ -1,23 +0,0 @@
|
|||
promise_test(async () => {
|
||||
const resources = [
|
||||
"/web-bundle/resources/wbn/resource.js",
|
||||
"/web-bundle/resources/wbn/sub/resource.js",
|
||||
];
|
||||
for (const resource of resources) {
|
||||
const response = await fetch(resource);
|
||||
assert_true(response.ok, resource + " should be loaded");
|
||||
}
|
||||
}, "Subresources should be loaded.");
|
||||
|
||||
promise_test(async () => {
|
||||
const resources = [
|
||||
"/web-bundle/resources/wbn-resource.js",
|
||||
"/web-bundle/resources/wbn1/resource.js",
|
||||
"/web-bundle/resources/other/resource.js",
|
||||
"/web-bundle/resources/resource.js",
|
||||
];
|
||||
for (const resource of resources) {
|
||||
const response = await fetch(resource);
|
||||
assert_false(response.ok, resource + " should not be loaded");
|
||||
}
|
||||
}, "Subresources should not be loaded due to path restriction.");
|
|
@ -1,17 +0,0 @@
|
|||
promise_test(async (t) => {
|
||||
assert_array_equals(
|
||||
loaded_scripts,
|
||||
[
|
||||
'relative-url-file.js',
|
||||
'start-with-double-slash-cors.js',
|
||||
'start-with-slash.js',
|
||||
'subdirectory-path.js',
|
||||
'starts-with-two-dots.js',
|
||||
]);
|
||||
assert_array_equals(
|
||||
failed_scripts,
|
||||
[
|
||||
'starts-with-two-dots-out-of-scope.js',
|
||||
]);
|
||||
},
|
||||
'Relative Url in web bundle.');
|
|
@ -1,17 +0,0 @@
|
|||
promise_test(async (t) => {
|
||||
assert_array_equals(
|
||||
loaded_scripts,
|
||||
[
|
||||
'relative-url-file.js',
|
||||
'start-with-double-slash.js',
|
||||
'start-with-slash.js',
|
||||
'subdirectory-path.js',
|
||||
'starts-with-two-dots.js',
|
||||
]);
|
||||
assert_array_equals(
|
||||
failed_scripts,
|
||||
[
|
||||
'starts-with-two-dots-out-of-scope.js',
|
||||
]);
|
||||
},
|
||||
'Relative Url in web bundle.');
|
|
@ -1,79 +0,0 @@
|
|||
// This test tries to load 'script.js' subresource from a static-element.wbn,
|
||||
// using a relative URL instead of an absolute one with a <link> and <script>
|
||||
// elements directly in the document (they are used only for this test).
|
||||
promise_test(async () => {
|
||||
assert_equals(resources_script_result, 'loaded from webbundle');
|
||||
},
|
||||
'A subresource script.js should be loaded from WebBundle using the relative ' +
|
||||
'URL.');
|
||||
|
||||
// Simple load of a root.js subresource from subresource.wbn using a relative
|
||||
// URL.
|
||||
promise_test(async () => {
|
||||
const resource_url = '/web-bundle/resources/wbn/root.js';
|
||||
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/subresource.wbn',
|
||||
[resource_url]);
|
||||
document.body.appendChild(element);
|
||||
|
||||
const response = await fetch(resource_url);
|
||||
assert_true(response.ok);
|
||||
const root = await response.text();
|
||||
assert_equals(root, 'export * from \'./submodule.js\';\n');
|
||||
}, 'Subresources with relative URLs should be loaded from the WebBundle.');
|
||||
|
||||
// Simple load of a root.js subresource from subresource.wbn using an
|
||||
// incorrect relative URL leading to a failed fetch.
|
||||
promise_test(async () => {
|
||||
const resource_url = 'web-bundle/resources/wbn/root.js';
|
||||
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/subresource.wbn',
|
||||
[resource_url]);
|
||||
document.body.appendChild(element);
|
||||
|
||||
const response = await fetch(resource_url);
|
||||
assert_false(response.ok);
|
||||
}, 'Wrong relative URL should result in a failed fetch.');
|
||||
|
||||
// Simple load of subresources under a scope from dynamic1.wbn using a relative
|
||||
// URL.
|
||||
promise_test(async () => {
|
||||
const resource_scope = '/web-bundle/resources/wbn/dynamic/resource';
|
||||
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn',
|
||||
[], {scopes: [resource_scope]});
|
||||
document.body.appendChild(element);
|
||||
|
||||
const module = await import('/web-bundle/resources/wbn/dynamic/resource1.js');
|
||||
assert_equals(module.result, 'resource1 from dynamic1.wbn');
|
||||
const module2 = await import('/web-bundle/resources/wbn/dynamic/resource2.js');
|
||||
assert_equals(module2.result, 'resource2 from dynamic1.wbn');
|
||||
const module3 = await import('/web-bundle/resources/wbn/dynamic/resource3.js');
|
||||
assert_equals(module3.result, 'resource3 from dynamic1.wbn');
|
||||
const module4 = await import('/web-bundle/resources/wbn/dynamic/resource4.js');
|
||||
assert_equals(module4.result, 'resource4 from dynamic1.wbn');
|
||||
}, 'Subresources inside the scope specified with relative URL should be loaded from the WebBundle.');
|
||||
|
||||
// Simple load of subresources under a scope from dynamic1.wbn using a relative
|
||||
// URL. As the scope URL is wrong, the fetch should fail.
|
||||
promise_test(async () => {
|
||||
const resource_scope = '/web-bundle/resources/wbn/dynami/';
|
||||
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn',
|
||||
[], {scopes: [resource_scope]});
|
||||
document.body.appendChild(element);
|
||||
|
||||
const result_promise = new Promise((resolve) => {
|
||||
// This function will be called from script.js
|
||||
window.report_result = resolve;
|
||||
});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = '/web-bundle/resources/wbn/dynamic/classic_script.js';
|
||||
document.body.appendChild(script);
|
||||
assert_equals(await result_promise, 'classic script from network');
|
||||
}, 'No subresources should be loaded from the bundle when the relative url of the scope is wrong');
|
|
@ -1,25 +0,0 @@
|
|||
test(() => {
|
||||
assert_equals(resources_script_result, 'loaded from webbundle');
|
||||
},
|
||||
'A subresource script.js should be loaded from WebBundle using the relative ' +
|
||||
'URL and a base element.');
|
||||
|
||||
promise_test(async () => {
|
||||
const module = await import("/web-bundle/resources/wbn/dynamic/resource1.js");
|
||||
assert_equals(module.result, "resource1 from dynamic1.wbn");
|
||||
const module2 = await import("/web-bundle/resources/wbn/dynamic/resource2.js");
|
||||
assert_equals(module2.result, "resource2 from dynamic1.wbn");
|
||||
const module3 = await import("/web-bundle/resources/wbn/dynamic/resource3.js");
|
||||
assert_equals(module3.result, "resource3 from dynamic1.wbn");
|
||||
const module4 = await import("/web-bundle/resources/wbn/dynamic/resource4.js");
|
||||
assert_equals(module4.result, "resource4 from dynamic1.wbn");
|
||||
const result_promise = new Promise((resolve) => {
|
||||
// This function will be called from script.js
|
||||
window.report_result = resolve;
|
||||
});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = "/web-bundle/resources/wbn/dynamic/classic_script.js";
|
||||
document.body.appendChild(script);
|
||||
assert_equals(await result_promise, "classic script from network");
|
||||
}, "Subresources that start with 'resource' should be loaded from dynamic1.wbn while others from network.");
|
|
@ -1,37 +0,0 @@
|
|||
// check-sec-fetch-dest-header-and-return-bundle.py returns a valid format
|
||||
// bundle only if a 'Sec-Fetch-Dest: webbundle' header is present in a request.
|
||||
// Otherwise, returns an empty body with 400 status code.
|
||||
//
|
||||
// In this wpt, we assume that a <link> element fires a load event correctly if
|
||||
// a valid format webbundle is returned.
|
||||
|
||||
const same_origin_bundle =
|
||||
'../resources/check-sec-fetch-dest-header-and-return-bundle.py';
|
||||
const cross_origin_bundle =
|
||||
'https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/check-sec-fetch-dest-header-and-return-bundle.py';
|
||||
|
||||
promise_test(async () => {
|
||||
for (const bundle of [same_origin_bundle, cross_origin_bundle]) {
|
||||
const element = createWebBundleElement(
|
||||
bundle,
|
||||
/*resources=*/[]);
|
||||
await addElementAndWaitForLoad(element);
|
||||
element.remove();
|
||||
}
|
||||
},
|
||||
'"Sec-Fetch-Dest: webbundle" header must be present in a request for a bundle' +
|
||||
' with the <link>-based API.');
|
||||
|
||||
promise_test(async () => {
|
||||
const res = await fetch(same_origin_bundle);
|
||||
assert_false(res.ok);
|
||||
},
|
||||
'"Sec-Fetch-Dest: webbundle" header must not be present in a fetch request' +
|
||||
' for a same-origin resource.');
|
||||
|
||||
promise_test(async () => {
|
||||
const res = await fetch(cross_origin_bundle);
|
||||
assert_false(res.ok);
|
||||
},
|
||||
'"Sec-Fetch-Dest: webbundle" header must not be present in a fetch request' +
|
||||
' for a cross-origin resource.');
|
|
@ -1,61 +0,0 @@
|
|||
promise_test(async t => {
|
||||
const bundle_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic1.wbn?pipe=trickle(d0.5)';
|
||||
const script_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn?pipe=trickle(d0.5)',
|
||||
/*resources=*/[script_url]);
|
||||
document.body.appendChild(element);
|
||||
var script_entries = 0;
|
||||
var web_bundle_entries = 0;
|
||||
var web_bundle_entry, script_entry;
|
||||
const promise = new Promise(resolve => {
|
||||
new PerformanceObserver(t.step_func(entryList => {
|
||||
var entries = entryList.getEntriesByType('resource');
|
||||
for (var i = 0; i < entries.length; ++i) {
|
||||
if (entries[i].name === script_url) {
|
||||
script_entry = entries[i];
|
||||
script_entries++;
|
||||
}
|
||||
|
||||
if (entries[i].name === bundle_url) {
|
||||
web_bundle_entry = entries[i];
|
||||
web_bundle_entries++;
|
||||
}
|
||||
}
|
||||
|
||||
if (web_bundle_entries > 0 && script_entries > 0) {
|
||||
// Check timestamps.
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseStart,
|
||||
script_entry.requestStart + 500);
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseStart,
|
||||
web_bundle_entry.responseStart);
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseEnd,
|
||||
script_entry.responseStart);
|
||||
assert_greater_than_equal(
|
||||
script_entry.requestStart,
|
||||
script_entry.connectEnd);
|
||||
assert_greater_than_equal(
|
||||
script_entry.responseEnd,
|
||||
script_entry.responseStart);
|
||||
// Check sizes.
|
||||
assert_greater_than(script_entry.encodedBodySize, 0);
|
||||
assert_equals(
|
||||
script_entry.transferSize,
|
||||
script_entry.encodedBodySize + 300);
|
||||
assert_equals(
|
||||
script_entry.encodedBodySize,
|
||||
script_entry.decodedBodySize);
|
||||
resolve();
|
||||
}
|
||||
})).observe({entryTypes: ['resource']});
|
||||
});
|
||||
const script = document.createElement('script');
|
||||
script.type = 'module';
|
||||
script.src = script_url;
|
||||
document.body.appendChild(script);
|
||||
return promise;
|
||||
},
|
||||
'Timestamp attributes filled in resource timing entries should be consistent.');
|
|
@ -1,40 +0,0 @@
|
|||
promise_test(async t => {
|
||||
const frame_id = 'urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const script_id = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/urn-uuid.wbn',
|
||||
/*resources=*/[frame_id, script_id]);
|
||||
document.body.appendChild(element);
|
||||
let iframe_entries = 0;
|
||||
let script_entries = 0;
|
||||
// Declare the report_result function as outputting into stderr
|
||||
// because it is used in the WebBundle script to report the script load.
|
||||
window.report_result = console.error;
|
||||
const promise = new Promise(resolve => {
|
||||
new PerformanceObserver(t.step_func(entryList => {
|
||||
let entries = entryList.getEntriesByType('resource');
|
||||
for (let i = 0; i < entries.length; ++i) {
|
||||
// Ignore any entries for the test harness files if present.
|
||||
if (/testharness(report)?\.js/.test(entries[i].name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entries[i].name === frame_id)
|
||||
++iframe_entries;
|
||||
if (entries[i].name === script_id)
|
||||
++script_entries;
|
||||
}
|
||||
if (iframe_entries == 1 && script_entries == 1) {
|
||||
resolve();
|
||||
}
|
||||
})).observe({entryTypes: ['resource']});
|
||||
});
|
||||
// Add iframe and the script so we get the ResourceTiming
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = frame_id;
|
||||
document.body.appendChild(iframe);
|
||||
const script = document.createElement('script');
|
||||
script.src = script_id;
|
||||
document.body.appendChild(script);
|
||||
return promise;
|
||||
}, 'Each urn:uuid resource should have exactly 1 ResourceTiming entry.');
|
|
@ -1,102 +0,0 @@
|
|||
async function registerServiceWorkerAndReturnActiveWorker(t, script, scope) {
|
||||
const reg = await navigator.serviceWorker.register(script, {scope: scope});
|
||||
t.add_cleanup(() => reg.unregister());
|
||||
if (reg.active)
|
||||
return reg.active;
|
||||
const worker = reg.installing || reg.waiting;
|
||||
await new Promise((resolve) => {
|
||||
worker.addEventListener('statechange', (event) => {
|
||||
if (event.target.state == 'activated')
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return worker;
|
||||
}
|
||||
|
||||
async function getRequestedUrls(worker) {
|
||||
return new Promise(resolve => {
|
||||
navigator.serviceWorker.addEventListener(
|
||||
'message',
|
||||
e => {resolve(e.data);},
|
||||
{once: true})
|
||||
worker.postMessage(null);
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(async (t) => {
|
||||
const iframe_path = './resources/service-worker-controlled-iframe.html';
|
||||
const iframe_url = new URL(iframe_path, location).href
|
||||
|
||||
// Register a service worker.
|
||||
const worker = await registerServiceWorkerAndReturnActiveWorker(
|
||||
t,
|
||||
'./resources/service-worker-for-request-monitor.js',
|
||||
iframe_path);
|
||||
|
||||
// Load an iframe which is controlled by the service worker.
|
||||
const iframe = await new Promise(resolve => {
|
||||
const frame = document.createElement('iframe');
|
||||
t.add_cleanup(() => frame.remove());
|
||||
frame.src = iframe_url;
|
||||
frame.onload = () => { resolve(frame); };
|
||||
document.body.appendChild(frame);
|
||||
});
|
||||
// The iframe request should be intercepted by the service worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), [iframe_url]);
|
||||
|
||||
// Add a web bundle element in the service worker controlled iframe.
|
||||
const frame_id = 'urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const script_id = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
|
||||
const element = createWebBundleElement(
|
||||
'../../resources/wbn/urn-uuid.wbn',
|
||||
/*resources=*/[frame_id, script_id]);
|
||||
|
||||
const element_load_promise = new Promise(resolve => {
|
||||
element.addEventListener('load', () => {resolve();});
|
||||
});
|
||||
iframe.contentDocument.body.appendChild(element);
|
||||
await element_load_promise;
|
||||
// The web bundle request should not be intercepted by the service worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), []);
|
||||
|
||||
// Add an urn uuid URL script element in the service worker controlled
|
||||
// iframe.
|
||||
const result_promise = new Promise(resolve => {
|
||||
// window.report_result() method will be called by the injected script.
|
||||
iframe.contentWindow.report_result = resolve;
|
||||
});
|
||||
const script = iframe.contentDocument.createElement('script');
|
||||
script.src = script_id;
|
||||
iframe.contentDocument.body.appendChild(script);
|
||||
assert_equals(await result_promise, 'OK');
|
||||
// The urn uuld URL script request should not be intercepted by the
|
||||
// service worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), []);
|
||||
|
||||
// Add an urn uuid URL iframe element in the service worker controlled
|
||||
// iframe.
|
||||
const inner_iframe = iframe.contentDocument.createElement('iframe');
|
||||
inner_iframe.src = frame_id;
|
||||
const load_promise = new Promise(resolve => {
|
||||
inner_iframe.addEventListener('load', () => {resolve();});
|
||||
});
|
||||
iframe.contentDocument.body.appendChild(inner_iframe);
|
||||
await load_promise;
|
||||
// The urn uuld URL iframe request should not intercepted by the service
|
||||
// worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), []);
|
||||
|
||||
// Check if the urn uuid URL iframe element is loaded correctly.
|
||||
const message_promise = new Promise(resolve => {
|
||||
window.addEventListener(
|
||||
'message',
|
||||
e => {resolve(e.data);},
|
||||
{once: true});
|
||||
});
|
||||
// location.href is evaluated in the urn uuid URL iframe element.
|
||||
inner_iframe.contentWindow.postMessage('location.href', '*');
|
||||
assert_equals(await message_promise, frame_id);
|
||||
},
|
||||
'Both Web Bundle request and Subresource fetch requests inside the Web ' +
|
||||
'Bundle should skip the service worker.');
|
|
@ -1,18 +0,0 @@
|
|||
promise_test(async () => {
|
||||
assert_equals(resources_script_result, 'loaded from webbundle');
|
||||
assert_equals(scopes_script_result, 'loaded from webbundle');
|
||||
assert_equals(out_of_scope_script_result, 'loaded from network');
|
||||
|
||||
['resources_', 'scopes_'].forEach((type) => {
|
||||
['style_target',
|
||||
'style_imported_from_file_target',
|
||||
'style_imported_from_tag_target'].forEach((target) => {
|
||||
const element = document.createElement('div');
|
||||
element.id = type + target;
|
||||
document.body.appendChild(element);
|
||||
assert_equals(window.getComputedStyle(element).color,
|
||||
'rgb(0, 0, 255)',
|
||||
element.id + ' color must be blue');
|
||||
});
|
||||
});
|
||||
}, 'Subresources from static elements should be loaded from web bundle.');
|
|
@ -1,116 +0,0 @@
|
|||
promise_test(async (t) => {
|
||||
const bundle_url = '../resources/wbn/urn-uuid.wbn';
|
||||
const frame_url = 'urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const iframe = await createWebBundleElementAndIframe(t, bundle_url, frame_url);
|
||||
// The iframe is cross-origin. So accessing iframe.contentWindow.location
|
||||
// should throw a SecurityError.
|
||||
assert_throws_dom(
|
||||
"SecurityError",
|
||||
() => { iframe.contentWindow.location.href; });
|
||||
}, 'The urn:uuid URL iframe must be cross-origin.');
|
||||
|
||||
promise_test(async (t) => {
|
||||
const bundle_url = '../resources/wbn/uuid-in-package.wbn';
|
||||
const frame_url = 'uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const iframe = await createWebBundleElementAndIframe(t, bundle_url, frame_url);
|
||||
// The iframe is cross-origin. So accessing iframe.contentWindow.location
|
||||
// should throw a SecurityError.
|
||||
assert_throws_dom(
|
||||
"SecurityError",
|
||||
() => { iframe.contentWindow.location.href; });
|
||||
}, 'The uuid-in-package: URL iframe must be cross-origin.');
|
||||
|
||||
uuid_iframe_test(
|
||||
'location.href',
|
||||
['urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae',
|
||||
'uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae'],
|
||||
'location.href in opaque-origin iframe.');
|
||||
|
||||
uuid_iframe_test(
|
||||
'(' + (() => {
|
||||
try {
|
||||
let result = window.localStorage;
|
||||
return 'no error';
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() + ')()',
|
||||
'SecurityError',
|
||||
'Accesing window.localStorage should throw a SecurityError.');
|
||||
|
||||
uuid_iframe_test(
|
||||
'(' + (() => {
|
||||
try {
|
||||
let result = window.sessionStorage;
|
||||
return 'no error';
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() + ')()',
|
||||
'SecurityError',
|
||||
'Accesing window.sessionStorage should throw a SecurityError.');
|
||||
|
||||
uuid_iframe_test(
|
||||
'(' + (() => {
|
||||
try {
|
||||
let result = document.cookie;
|
||||
return 'no error';
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() + ')()',
|
||||
'SecurityError',
|
||||
'Accesing document.cookie should throw a SecurityError.');
|
||||
|
||||
uuid_iframe_test(
|
||||
'(' + (() => {
|
||||
try {
|
||||
let request = window.indexedDB.open("db");
|
||||
return 'no error';
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() + ')()',
|
||||
'SecurityError',
|
||||
'Opening an indexedDB should throw a SecurityError.');
|
||||
|
||||
uuid_iframe_test(
|
||||
'window.caches === undefined',
|
||||
true,
|
||||
'window.caches should be undefined.');
|
||||
|
||||
function uuid_iframe_test(code, expected, name) {
|
||||
if (!Array.isArray(expected)) {
|
||||
expected = [expected, expected];
|
||||
}
|
||||
promise_test(async (t) => {
|
||||
const bundle_url = '../resources/wbn/urn-uuid.wbn';
|
||||
const frame_url = 'urn:uuid:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const iframe = await createWebBundleElementAndIframe(t, bundle_url, frame_url);
|
||||
assert_equals(await evalInIframe(iframe, code), expected[0]);
|
||||
}, name + '(urn:uuid)');
|
||||
|
||||
promise_test(async (t) => {
|
||||
const bundle_url = '../resources/wbn/uuid-in-package.wbn';
|
||||
const frame_url = 'uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae';
|
||||
const iframe = await createWebBundleElementAndIframe(t, bundle_url, frame_url);
|
||||
assert_equals(await evalInIframe(iframe, code), expected[1]);
|
||||
}, name + 'uuid-in-package');
|
||||
}
|
||||
|
||||
async function createWebBundleElementAndIframe(t, bundle_url, frame_url) {
|
||||
const element = createWebBundleElement(bundle_url, [frame_url]);
|
||||
document.body.appendChild(element);
|
||||
const iframe = document.createElement('iframe');
|
||||
t.add_cleanup(() => {
|
||||
document.body.removeChild(element);
|
||||
document.body.removeChild(iframe);
|
||||
});
|
||||
iframe.src = frame_url;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
iframe.addEventListener('load', resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
await load_promise;
|
||||
return iframe;
|
||||
}
|
|
@ -1,307 +0,0 @@
|
|||
|
||||
promise_test(async () => {
|
||||
const module = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js');
|
||||
assert_equals(module.result, 'OK');
|
||||
}, 'Subresource loading with WebBundle');
|
||||
|
||||
promise_test(async () => {
|
||||
const response = await fetch('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js');
|
||||
const text = await response.text();
|
||||
assert_equals(text, 'export * from \'./submodule.js\';\n');
|
||||
}, 'Subresource loading with WebBundle (Fetch API)');
|
||||
|
||||
promise_test(t => {
|
||||
const url =
|
||||
'/common/redirect.py?location=https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js';
|
||||
return promise_rejects_js(t, TypeError, import(url));
|
||||
}, 'Subresource loading with WebBundle shouldn\'t affect redirect');
|
||||
|
||||
promise_test(async () => {
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1-b1.wbn',
|
||||
[
|
||||
'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js',
|
||||
'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource2.js',
|
||||
'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource4.js'
|
||||
]);
|
||||
document.body.appendChild(element);
|
||||
|
||||
const module = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js');
|
||||
assert_equals(module.result, 'resource1 from dynamic1.wbn');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading from a b1 bundle');
|
||||
|
||||
promise_test(async () => {
|
||||
const classic_script_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1-b1.wbn',
|
||||
[classic_script_url]);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic1.wbn');
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {url: '../resources/wbn/dynamic2-b1.wbn'});
|
||||
// Loading the classic script should not reuse the previously loaded
|
||||
// script. So in this case, the script must be loaded from dynamic2-b1.wbn.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic2.wbn');
|
||||
document.body.removeChild(new_element);
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from network');
|
||||
}, 'Dynamically loading classic script from a \'b1\' web bundle with resources attribute');
|
||||
|
||||
promise_test(async () => {
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn',
|
||||
[
|
||||
'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js',
|
||||
'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource2.js',
|
||||
'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource4.js'
|
||||
]);
|
||||
document.body.appendChild(element);
|
||||
|
||||
const module = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js');
|
||||
assert_equals(module.result, 'resource1 from dynamic1.wbn');
|
||||
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {url: '../resources/wbn/dynamic2-b1.wbn'});
|
||||
const module2 = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource2.js');
|
||||
assert_equals(module2.result, 'resource2 from dynamic2.wbn');
|
||||
|
||||
// A resource not specified in the resources attribute, but in the bundle.
|
||||
const module3 = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource3.js');
|
||||
assert_equals(module3.result, 'resource3 from network');
|
||||
|
||||
document.body.removeChild(new_element);
|
||||
const module4 = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource4.js');
|
||||
assert_equals(module4.result, 'resource4 from network');
|
||||
|
||||
// Module scripts are stored to the Document's module map once loaded.
|
||||
// So import()ing the same module script will reuse the previously loaded
|
||||
// script.
|
||||
const module_second = await import('https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js');
|
||||
assert_equals(module_second.result, 'resource1 from dynamic1.wbn');
|
||||
}, 'Dynamically adding / updating / removing the webbundle element.');
|
||||
|
||||
promise_test(async () => {
|
||||
const classic_script_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn',
|
||||
[classic_script_url]);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic1.wbn');
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {url: '../resources/wbn/dynamic2-b1.wbn'});
|
||||
// Loading the classic script should not reuse the previously loaded
|
||||
// script. So in this case, the script must be loaded from dynamic2.wbn.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic2.wbn');
|
||||
document.body.removeChild(new_element);
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from network');
|
||||
}, 'Dynamically loading classic script from web bundle');
|
||||
|
||||
promise_test(async (t) => {
|
||||
// To avoid caching mechanism, this test is using fetch() API with
|
||||
// { cache: 'no-store' } to load the resource.
|
||||
const classic_script_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js';
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url)).text(),
|
||||
'window.report_result(\'classic script from network\');\n');
|
||||
|
||||
const element1 = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn',
|
||||
[classic_script_url]);
|
||||
document.body.appendChild(element1);
|
||||
t.add_cleanup(() => {
|
||||
if (element1.parentElement)
|
||||
element1.parentElement.removeChild(element1);
|
||||
});
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: 'no-store' })).text(),
|
||||
'window.report_result(\'classic script from dynamic1.wbn\');\n');
|
||||
|
||||
const element2 = createWebBundleElement(
|
||||
'../resources/wbn/dynamic2.wbn',
|
||||
[classic_script_url]);
|
||||
document.body.appendChild(element2);
|
||||
t.add_cleanup(() => {
|
||||
if (element2.parentElement)
|
||||
element2.parentElement.removeChild(element2);
|
||||
});
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: 'no-store' })).text(),
|
||||
'window.report_result(\'classic script from dynamic2.wbn\');\n');
|
||||
|
||||
document.body.removeChild(element2);
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: 'no-store' })).text(),
|
||||
'window.report_result(\'classic script from dynamic1.wbn\');\n');
|
||||
|
||||
document.body.removeChild(element1);
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: 'no-store' })).text(),
|
||||
'window.report_result(\'classic script from network\');\n');
|
||||
}, 'Multiple web bundle elements. The last added element must be refered.');
|
||||
|
||||
promise_test(async () => {
|
||||
const classic_script_url = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js';
|
||||
const scope = 'https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1.wbn',
|
||||
[],
|
||||
{scopes: [scope]});
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic1.wbn');
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {url: '../resources/wbn/dynamic2.wbn'});
|
||||
// Loading the classic script should not reuse the previously loaded
|
||||
// script. So in this case, the script must be loaded from dynamic2.wbn.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic2.wbn');
|
||||
// Changes the scope not to hit the classic_script.js.
|
||||
const new_element2 = removeAndAppendNewElementWithUpdatedRule(new_element, {scopes: [scope + 'dummy']});
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from network');
|
||||
// Adds the scope to hit the classic_script.js.
|
||||
const new_element3 = removeAndAppendNewElementWithUpdatedRule(new_element2, {scopes: [scope + 'dummy', scope + 'classic_']});
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from dynamic2.wbn');
|
||||
document.body.removeChild(new_element3);
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
'classic script from network');
|
||||
}, 'Dynamically loading classic script from web bundle with scopes');
|
||||
|
||||
promise_test(() => {
|
||||
return addWebBundleElementAndWaitForLoad(
|
||||
'../resources/wbn/dynamic1.wbn?test-event',
|
||||
/*resources=*/[],
|
||||
{crossOrigin: undefined});
|
||||
}, 'The webbundle element fires a load event on load success');
|
||||
|
||||
promise_test((t) => {
|
||||
return addWebBundleElementAndWaitForError(
|
||||
'../resources/wbn/nonexistent.wbn',
|
||||
/*resources=*/[],
|
||||
{crossOrigin: undefined});
|
||||
}, 'The webbundle element fires an error event on load failure');
|
||||
|
||||
promise_test(async () => {
|
||||
const module_script_url = 'https://www1.{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1-crossorigin.wbn',
|
||||
[module_script_url]);
|
||||
document.body.appendChild(element);
|
||||
const module = await import(module_script_url);
|
||||
assert_equals(module.result, 'resource1 from network');
|
||||
}, 'Subresource URL must be same-origin with bundle URL');
|
||||
|
||||
promise_test(async () => {
|
||||
const module_script_url = 'https://www1.{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/dynamic1-crossorigin-b1.wbn',
|
||||
[module_script_url]);
|
||||
document.body.appendChild(element);
|
||||
const module = await import(module_script_url);
|
||||
assert_equals(module.result, 'resource1 from network');
|
||||
}, 'Subresource URL must be same-origin with bundle URL (for \'b1\' bundles too)');
|
||||
|
||||
promise_test(async () => {
|
||||
const url = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/urn-uuid.wbn',
|
||||
[url]);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), 'OK');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading with urn:uuid: URL with resources attribute');
|
||||
|
||||
promise_test(async () => {
|
||||
const url = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/urn-uuid.wbn',
|
||||
[],
|
||||
{scopes: ['urn:uuid:']});
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), 'OK');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading with urn:uuid: URL with scopes attribute');
|
||||
|
||||
promise_test(async () => {
|
||||
const url = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/urn-uuid-b1.wbn',
|
||||
[url]);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), 'OK');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading with urn:uuid: URL of a \'b1\' bundle with resources attribute');
|
||||
|
||||
promise_test(async () => {
|
||||
const url = 'urn:uuid:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/urn-uuid-b1.wbn',
|
||||
[],
|
||||
{scopes: ['urn:uuid:']});
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), 'OK');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading with urn:uuid: URL of a \'b1\' bundle with scopes attribute');
|
||||
|
||||
promise_test(async () => {
|
||||
const url = 'uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/uuid-in-package.wbn',
|
||||
[url]);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), 'OK');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading with uuid-in-package: URL with resources attribute');
|
||||
|
||||
promise_test(async () => {
|
||||
const url = 'uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720';
|
||||
const element = createWebBundleElement(
|
||||
'../resources/wbn/uuid-in-package.wbn',
|
||||
[],
|
||||
{scopes: ['uuid-in-package:']});
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), 'OK');
|
||||
document.body.removeChild(element);
|
||||
}, 'Subresource loading with uuid-in-package: URL with scopes attribute');
|
||||
|
||||
async function loadScriptAndWaitReport(script_url) {
|
||||
const result_promise = new Promise((resolve) => {
|
||||
// This function will be called from script.js
|
||||
window.report_result = resolve;
|
||||
});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = script_url;
|
||||
document.body.appendChild(script);
|
||||
return result_promise;
|
||||
}
|
||||
|
||||
function removeAndAppendNewElementWithUpdatedRule(element, new_rule) {
|
||||
const new_element = createNewWebBundleElementWithUpdatedRule(element, new_rule);
|
||||
element.remove();
|
||||
document.body.appendChild(new_element);
|
||||
return new_element;
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
<body>
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = "script";
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
@ -57,7 +56,11 @@
|
|||
}
|
||||
|
||||
function createScriptWebBundle2(options) {
|
||||
return createWebBundleElement(wbn_url, /*resources=*/ [resource2], /*options=*/ options);
|
||||
return createWebBundleElement(
|
||||
wbn_url,
|
||||
/*resources=*/ [resource2],
|
||||
/*options=*/ options
|
||||
);
|
||||
}
|
||||
|
||||
async function appendScriptWebBundle1AndFetchResource1() {
|
||||
|
@ -88,7 +91,7 @@
|
|||
script2 = createScriptWebBundle2();
|
||||
document.body.appendChild(script2);
|
||||
|
||||
await assertResource1CanBeFetched()
|
||||
await assertResource1CanBeFetched();
|
||||
await assertResource2CanBeFetched();
|
||||
assert_equals(webBundleFetchCount(wbn_suffix), 1);
|
||||
}, "A webbundle should be fetched again when new script element is appended.");
|
||||
|
@ -215,7 +218,6 @@
|
|||
assert_equals(webBundleFetchCount(wbn_suffix), 0);
|
||||
}, "Multiple 'remove(), then append()' for the same element should reuse webbundle resources");
|
||||
|
||||
|
||||
promise_test(async (t) => {
|
||||
t.add_cleanup(cleanUp);
|
||||
await appendScriptWebBundle1AndFetchResource1();
|
||||
|
@ -225,7 +227,7 @@
|
|||
script1.remove();
|
||||
|
||||
// Then append script2 in a separet task.
|
||||
await new Promise(resolve => t.step_timeout(resolve, 0));
|
||||
await new Promise((resolve) => t.step_timeout(resolve, 0));
|
||||
script2 = createScriptWebBundle2();
|
||||
document.body.append(script2);
|
||||
|
||||
|
@ -234,7 +236,6 @@
|
|||
assert_equals(webBundleFetchCount(wbn_suffix), 1);
|
||||
}, "'remove(), then append() in a separate task' should not reuse webbundle resources");
|
||||
|
||||
|
||||
promise_test(async (t) => {
|
||||
t.add_cleanup(cleanUp);
|
||||
await appendScriptWebBundle1AndFetchResource1();
|
||||
|
@ -279,13 +280,19 @@
|
|||
promise_test(async (t) => {
|
||||
t.add_cleanup(cleanUp);
|
||||
clearWebBundleFetchCount();
|
||||
script1 = createWebBundleElement(wbn_url + "?pipe=trickle(d0.1)", resource1);
|
||||
script1 = createWebBundleElement(
|
||||
wbn_url + "?pipe=trickle(d0.1)",
|
||||
[resource1]
|
||||
);
|
||||
document.body.appendChild(script1);
|
||||
|
||||
// While script1 is still loading, remove it and make script2
|
||||
// reuse the resources.
|
||||
script1.remove();
|
||||
script2 = createWebBundleElement(wbn_url + "?pipe=trickle(d0.1)", resource2);
|
||||
script2 = createWebBundleElement(
|
||||
wbn_url + "?pipe=trickle(d0.1)",
|
||||
[resource2]
|
||||
);
|
||||
await addElementAndWaitForLoad(script2);
|
||||
|
||||
assert_equals(webBundleFetchCount(wbn_suffix + "?pipe=trickle(d0.1)"), 1);
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Accept: request header in webbundle requests</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/accept-header-test.js"></script>
|
||||
</body>
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>COEP for WebBundle subresource loading</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/origin.html#coep" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`corp.wbn` includes three subresources:
|
||||
a. `no-corp.js`, which doesn't include a Cross-Origin-Resource-Policy response header.
|
||||
b. `corp-same-origin.js`, which includes a Cross-Origin-Resource-Policy: same-origin response header.
|
||||
c. `corp-cross-origin.js`, which includes a Cross-Origin-Resource-Policy: cross-origin response header.
|
||||
-->
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn",
|
||||
"resources": [
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/no-corp.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-same-origin.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-cross-origin.js",
|
||||
"urn:uuid:5eafff38-e0a0-4661-bde0-434255aa9d93",
|
||||
"urn:uuid:7e13b47a-8b91-4a0e-997c-993a5e2f3a34",
|
||||
"urn:uuid:86d5b696-8867-4454-8b07-51239a0817f7"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<script src="resources/coep-test.js"></script>
|
||||
</body>
|
|
@ -1,42 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CORP for WebBundle subresource loading</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#cors-and-corp-for-subresource-requests" />
|
||||
<link rel="help" href="https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This wpt should run on an origin different from https://www1.web-platform.test:8444/,
|
||||
from where cross-orign WebBundles are served.
|
||||
|
||||
This test uses a cross-origin WebBundle,
|
||||
https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn,
|
||||
which is served with an Access-Control-Allow-Origin response header.
|
||||
|
||||
`corp.wbn` includes three subresources:
|
||||
a. `no-corp.js`, which doesn't include a Cross-Origin-Resource-Policy response header.
|
||||
b. `corp-same-origin.js`, which includes a Cross-Origin-Resource-Policy: same-origin response header.
|
||||
c. `corp-cross-origin.js`, which includes a Cross-Origin-Resource-Policy: cross-origin response header.
|
||||
-->
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp.wbn",
|
||||
"resources": [
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/no-corp.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-same-origin.js",
|
||||
"https://www1.web-platform.test:8444/web-bundle/resources/wbn/cors/corp-cross-origin.js",
|
||||
"urn:uuid:5eafff38-e0a0-4661-bde0-434255aa9d93",
|
||||
"urn:uuid:7e13b47a-8b91-4a0e-997c-993a5e2f3a34",
|
||||
"urn:uuid:86d5b696-8867-4454-8b07-51239a0817f7"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<script src="resources/corp-test.js"></script>
|
||||
</body>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>On-going subresource loading should fail immediately when the web bundle element is removed</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/element-removal-test.js"></script>
|
||||
</body>
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>A nested bundle is not supported</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "/web-bundle/resources/wbn/nested-main.wbn",
|
||||
"resources": ["/web-bundle/resources/wbn/nested-sub.wbn"]
|
||||
}
|
||||
</script>
|
||||
<script src="resources/nested-bundle-test.js"></script>
|
||||
</body>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching failed due to a network error</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/network-error-test.sub.js"></script>
|
||||
</body>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching failed due to not found error</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/not-found-test.js"></script>
|
||||
</body>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Path restriction on subresource loading with WebBundles</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/path-restriction.wbn",
|
||||
"resources": [
|
||||
"/web-bundle/resources/wbn/resource.js",
|
||||
"/web-bundle/resources/wbn/sub/resource.js",
|
||||
"/web-bundle/resources/wbn-resource.js",
|
||||
"/web-bundle/resources/wbn1/resource.js",
|
||||
"/web-bundle/resources/other/resource.js",
|
||||
"/web-bundle/resources/resource.js"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<script src="resources/path-restriction-test.js"></script>
|
||||
</body>
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subresource loading using relative URLs in the 'resources' attribute with a base element</title>
|
||||
<base href="../resources/wbn/">
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "static-element.wbn",
|
||||
"resources": ["static-element/resources/script.js"]
|
||||
}
|
||||
</script>
|
||||
<script id="script" src="static-element/resources/script.js"></script>
|
||||
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "dynamic1.wbn",
|
||||
"scopes": ["dynamic/resource"]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<script src="/web-bundle/subresource-loading/resources/relative-url-with-base-test.js"></script>
|
||||
</body>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Request's destination must be "webbundle" with the script-based API</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/request-destination-test.sub.js"></script>
|
||||
</body>
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Resource timing attributes are consistent for the same-origin subresources.</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/resource-timing-attributes-consistent-test.sub.js"></script>
|
||||
</body>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Resource timing entries present for urn:uuid resources</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/resource-timing-test.js"></script>
|
||||
</body>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Web Bundle fetching and the inner resouirce fetching should skip service worker</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/service-worker-controlled-test.js"></script>
|
||||
</body>
|
|
@ -1,41 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>WebBundle subresource loading for static elements with a base element</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<base href="../resources/wbn/static-element/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../static-element.wbn",
|
||||
"resources": [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/script.js",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style.css",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-file.css",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-tag.css"
|
||||
],
|
||||
"scopes": [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/scopes/"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<style type="text/css">
|
||||
@import 'resources/style-imported-from-tag.css';
|
||||
@import 'scopes/style-imported-from-tag.css';
|
||||
</style>
|
||||
<link href="resources/style.css" rel=stylesheet>
|
||||
<link href="scopes/style.css" rel=stylesheet>
|
||||
<script src="resources/script.js"></script>
|
||||
<script src="scopes/script.js"></script>
|
||||
<script src="out-of-scope/script.js"></script>
|
||||
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<script src="/web-bundle/subresource-loading/resources/static-element-with-test.js"></script>
|
||||
</body>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subframe loading from Web Bundles</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script src="resources/subframe-from-web-bundle-test.js"></script>
|
||||
</body>
|
|
@ -1,25 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subresource loading with script type="webbundle"</title>
|
||||
<link rel="help" href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
|
||||
<script>
|
||||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = 'script';
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/subresource.wbn",
|
||||
"resources": [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/submodule.js"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script src="resources/subresource-load-test.sub.js"></script>
|
||||
</body>
|
|
@ -0,0 +1,138 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
Web Bundle fetching and the inner resouirce fetching should skip service
|
||||
worker
|
||||
</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
async function registerServiceWorkerAndReturnActiveWorker(
|
||||
t,
|
||||
script,
|
||||
scope
|
||||
) {
|
||||
const reg = await navigator.serviceWorker.register(script, {
|
||||
scope: scope,
|
||||
});
|
||||
t.add_cleanup(() => reg.unregister());
|
||||
if (reg.active) return reg.active;
|
||||
const worker = reg.installing || reg.waiting;
|
||||
await new Promise((resolve) => {
|
||||
worker.addEventListener("statechange", (event) => {
|
||||
if (event.target.state == "activated") resolve();
|
||||
});
|
||||
});
|
||||
return worker;
|
||||
}
|
||||
|
||||
async function getRequestedUrls(worker) {
|
||||
return new Promise((resolve) => {
|
||||
navigator.serviceWorker.addEventListener(
|
||||
"message",
|
||||
(e) => {
|
||||
resolve(e.data);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
worker.postMessage(null);
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(async (t) => {
|
||||
const iframe_path = "./resources/service-worker-controlled-iframe.html";
|
||||
const iframe_url = new URL(iframe_path, location).href;
|
||||
|
||||
// Register a service worker.
|
||||
const worker = await registerServiceWorkerAndReturnActiveWorker(
|
||||
t,
|
||||
"./resources/service-worker-for-request-monitor.js",
|
||||
iframe_path
|
||||
);
|
||||
|
||||
// Load an iframe which is controlled by the service worker.
|
||||
const iframe = await new Promise((resolve) => {
|
||||
const frame = document.createElement("iframe");
|
||||
t.add_cleanup(() => frame.remove());
|
||||
frame.src = iframe_url;
|
||||
frame.onload = () => {
|
||||
resolve(frame);
|
||||
};
|
||||
document.body.appendChild(frame);
|
||||
});
|
||||
// The iframe request should be intercepted by the service worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), [iframe_url]);
|
||||
|
||||
// Add a web bundle element in the service worker controlled iframe.
|
||||
const frame_id = "uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae";
|
||||
const script_id = "uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720";
|
||||
|
||||
const element = createWebBundleElement(
|
||||
"../../resources/wbn/uuid-in-package.wbn",
|
||||
/*resources=*/ [frame_id, script_id]
|
||||
);
|
||||
|
||||
const element_load_promise = new Promise((resolve) => {
|
||||
element.addEventListener("load", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
iframe.contentDocument.body.appendChild(element);
|
||||
await element_load_promise;
|
||||
// The web bundle request should not be intercepted by the service worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), []);
|
||||
|
||||
// Add a uuid-in-package URL script element in the service worker
|
||||
// controlled iframe.
|
||||
const result_promise = new Promise((resolve) => {
|
||||
// window.report_result() method will be called by the injected script.
|
||||
iframe.contentWindow.report_result = resolve;
|
||||
});
|
||||
const script = iframe.contentDocument.createElement("script");
|
||||
script.src = script_id;
|
||||
iframe.contentDocument.body.appendChild(script);
|
||||
assert_equals(await result_promise, "OK");
|
||||
// The urn uuld URL script request should not be intercepted by the
|
||||
// service worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), []);
|
||||
|
||||
// Add a uuid-in-package URL iframe element in the service worker controlled
|
||||
// iframe.
|
||||
const inner_iframe = iframe.contentDocument.createElement("iframe");
|
||||
inner_iframe.src = frame_id;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
inner_iframe.addEventListener("load", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
iframe.contentDocument.body.appendChild(inner_iframe);
|
||||
await load_promise;
|
||||
// The urn uuld URL iframe request should not intercepted by the service
|
||||
// worker.
|
||||
assert_array_equals(await getRequestedUrls(worker), []);
|
||||
|
||||
// Check if the uuid-in-package URL iframe element is loaded correctly.
|
||||
const message_promise = new Promise((resolve) => {
|
||||
window.addEventListener(
|
||||
"message",
|
||||
(e) => {
|
||||
resolve(e.data);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
// location.href is evaluated in the uuid-in-package URL iframe element.
|
||||
inner_iframe.contentWindow.postMessage("location.href", "*");
|
||||
assert_equals(await message_promise, frame_id);
|
||||
}, "Both Web Bundle request and Subresource fetch requests inside the Web " + "Bundle should skip the service worker.");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<title>
|
||||
WebBundle subresource loading for static elements with a base element
|
||||
</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<base href="../resources/wbn/static-element/" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../static-element.wbn",
|
||||
"resources": [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/script.js",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style.css",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-file.css",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/resources/style-imported-from-tag.css"
|
||||
],
|
||||
"scopes": [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/static-element/scopes/"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<style type="text/css">
|
||||
@import "resources/style-imported-from-tag.css";
|
||||
@import "scopes/style-imported-from-tag.css";
|
||||
</style>
|
||||
<link href="resources/style.css" rel="stylesheet" />
|
||||
<link href="scopes/style.css" rel="stylesheet" />
|
||||
<script src="resources/script.js"></script>
|
||||
<script src="scopes/script.js"></script>
|
||||
<script src="out-of-scope/script.js"></script>
|
||||
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
assert_equals(resources_script_result, "loaded from webbundle");
|
||||
assert_equals(scopes_script_result, "loaded from webbundle");
|
||||
assert_equals(out_of_scope_script_result, "loaded from network");
|
||||
|
||||
["resources_", "scopes_"].forEach((type) => {
|
||||
[
|
||||
"style_target",
|
||||
"style_imported_from_file_target",
|
||||
"style_imported_from_tag_target",
|
||||
].forEach((target) => {
|
||||
const element = document.createElement("div");
|
||||
element.id = type + target;
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
window.getComputedStyle(element).color,
|
||||
"rgb(0, 0, 255)",
|
||||
element.id + " color must be blue"
|
||||
);
|
||||
});
|
||||
});
|
||||
}, "Subresources from static elements should be loaded from web bundle.");
|
||||
</script>
|
||||
</body>
|
|
@ -22,19 +22,47 @@
|
|||
}
|
||||
</script>
|
||||
<style type="text/css">
|
||||
@import '../resources/wbn/static-element/resources/style-imported-from-tag.css';
|
||||
@import '../resources/wbn/static-element/scopes/style-imported-from-tag.css';
|
||||
@import "../resources/wbn/static-element/resources/style-imported-from-tag.css";
|
||||
@import "../resources/wbn/static-element/scopes/style-imported-from-tag.css";
|
||||
</style>
|
||||
<link href="../resources/wbn/static-element/resources/style.css" rel=stylesheet>
|
||||
<link href="../resources/wbn/static-element/scopes/style.css" rel=stylesheet>
|
||||
<link
|
||||
href="../resources/wbn/static-element/resources/style.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="../resources/wbn/static-element/scopes/style.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="../resources/wbn/static-element/resources/script.js"></script>
|
||||
<script src="../resources/wbn/static-element/scopes/script.js"></script>
|
||||
<script src="../resources/wbn/static-element/out-of-scope/script.js"></script>
|
||||
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports('webbundle'));
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
assert_equals(resources_script_result, "loaded from webbundle");
|
||||
assert_equals(scopes_script_result, "loaded from webbundle");
|
||||
assert_equals(out_of_scope_script_result, "loaded from network");
|
||||
|
||||
["resources_", "scopes_"].forEach((type) => {
|
||||
[
|
||||
"style_target",
|
||||
"style_imported_from_file_target",
|
||||
"style_imported_from_tag_target",
|
||||
].forEach((target) => {
|
||||
const element = document.createElement("div");
|
||||
element.id = type + target;
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
window.getComputedStyle(element).color,
|
||||
"rgb(0, 0, 255)",
|
||||
element.id + " color must be blue"
|
||||
);
|
||||
});
|
||||
});
|
||||
}, "Subresources from static elements should be loaded from web bundle.");
|
||||
</script>
|
||||
<script src="resources/static-element-with-test.js"></script>
|
||||
</body>
|
|
@ -0,0 +1,134 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subframe loading from Web Bundles</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async (t) => {
|
||||
const bundle_url = "../resources/wbn/uuid-in-package.wbn";
|
||||
const frame_url = "uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae";
|
||||
const iframe = await createWebBundleElementAndIframe(
|
||||
t,
|
||||
bundle_url,
|
||||
frame_url
|
||||
);
|
||||
// The iframe is cross-origin. So accessing iframe.contentWindow.location
|
||||
// should throw a SecurityError.
|
||||
assert_throws_dom("SecurityError", () => {
|
||||
iframe.contentWindow.location.href;
|
||||
});
|
||||
}, "The uuid-in-package: URL iframe must be cross-origin.");
|
||||
|
||||
uuid_iframe_test(
|
||||
"location.href",
|
||||
"uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae",
|
||||
"location.href in opaque-origin iframe."
|
||||
);
|
||||
|
||||
uuid_iframe_test(
|
||||
"(" +
|
||||
(() => {
|
||||
try {
|
||||
let result = window.localStorage;
|
||||
return "no error";
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() +
|
||||
")()",
|
||||
"SecurityError",
|
||||
"Accesing window.localStorage should throw a SecurityError."
|
||||
);
|
||||
|
||||
uuid_iframe_test(
|
||||
"(" +
|
||||
(() => {
|
||||
try {
|
||||
let result = window.sessionStorage;
|
||||
return "no error";
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() +
|
||||
")()",
|
||||
"SecurityError",
|
||||
"Accesing window.sessionStorage should throw a SecurityError."
|
||||
);
|
||||
|
||||
uuid_iframe_test(
|
||||
"(" +
|
||||
(() => {
|
||||
try {
|
||||
let result = document.cookie;
|
||||
return "no error";
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() +
|
||||
")()",
|
||||
"SecurityError",
|
||||
"Accesing document.cookie should throw a SecurityError."
|
||||
);
|
||||
|
||||
uuid_iframe_test(
|
||||
"(" +
|
||||
(() => {
|
||||
try {
|
||||
let request = window.indexedDB.open("db");
|
||||
return "no error";
|
||||
} catch (e) {
|
||||
return e.name;
|
||||
}
|
||||
}).toString() +
|
||||
")()",
|
||||
"SecurityError",
|
||||
"Opening an indexedDB should throw a SecurityError."
|
||||
);
|
||||
|
||||
uuid_iframe_test(
|
||||
"window.caches === undefined",
|
||||
true,
|
||||
"window.caches should be undefined."
|
||||
);
|
||||
|
||||
function uuid_iframe_test(code, expected, name) {
|
||||
promise_test(async (t) => {
|
||||
const bundle_url = "../resources/wbn/uuid-in-package.wbn";
|
||||
const frame_url =
|
||||
"uuid-in-package:429fcc4e-0696-4bad-b099-ee9175f023ae";
|
||||
const iframe = await createWebBundleElementAndIframe(
|
||||
t,
|
||||
bundle_url,
|
||||
frame_url
|
||||
);
|
||||
assert_equals(await evalInIframe(iframe, code), expected);
|
||||
}, name + "uuid-in-package");
|
||||
}
|
||||
|
||||
async function createWebBundleElementAndIframe(t, bundle_url, frame_url) {
|
||||
const element = createWebBundleElement(bundle_url, [frame_url]);
|
||||
document.body.appendChild(element);
|
||||
const iframe = document.createElement("iframe");
|
||||
t.add_cleanup(() => {
|
||||
document.body.removeChild(element);
|
||||
document.body.removeChild(iframe);
|
||||
});
|
||||
iframe.src = frame_url;
|
||||
const load_promise = new Promise((resolve) => {
|
||||
iframe.addEventListener("load", resolve);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
await load_promise;
|
||||
return iframe;
|
||||
}
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,294 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Subresource loading with script type="webbundle"</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
|
||||
/>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.js"></script>
|
||||
<body>
|
||||
<script type="webbundle">
|
||||
{
|
||||
"source": "../resources/wbn/subresource.wbn",
|
||||
"resources": [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/submodule.js"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
setup(() => {
|
||||
assert_true(HTMLScriptElement.supports("webbundle"));
|
||||
});
|
||||
|
||||
promise_test(async () => {
|
||||
const module = await import(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js"
|
||||
);
|
||||
assert_equals(module.result, "OK");
|
||||
}, "Subresource loading with WebBundle");
|
||||
|
||||
promise_test(async () => {
|
||||
const response = await fetch(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js"
|
||||
);
|
||||
const text = await response.text();
|
||||
assert_equals(text, "export * from './submodule.js';\n");
|
||||
}, "Subresource loading with WebBundle (Fetch API)");
|
||||
|
||||
promise_test((t) => {
|
||||
const url =
|
||||
"/common/redirect.py?location=https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/root.js";
|
||||
return promise_rejects_js(t, TypeError, import(url));
|
||||
}, "Subresource loading with WebBundle shouldn't affect redirect");
|
||||
|
||||
promise_test(async () => {
|
||||
const element = createWebBundleElement("../resources/wbn/dynamic1.wbn", [
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource2.js",
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource4.js",
|
||||
]);
|
||||
document.body.appendChild(element);
|
||||
|
||||
const module = await import(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js"
|
||||
);
|
||||
assert_equals(module.result, "resource1 from dynamic1.wbn");
|
||||
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {
|
||||
url: "../resources/wbn/dynamic2.wbn",
|
||||
});
|
||||
const module2 = await import(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource2.js"
|
||||
);
|
||||
assert_equals(module2.result, "resource2 from dynamic2.wbn");
|
||||
|
||||
// A resource not specified in the resources attribute, but in the bundle.
|
||||
const module3 = await import(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource3.js"
|
||||
);
|
||||
assert_equals(module3.result, "resource3 from network");
|
||||
|
||||
document.body.removeChild(new_element);
|
||||
const module4 = await import(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource4.js"
|
||||
);
|
||||
assert_equals(module4.result, "resource4 from network");
|
||||
|
||||
// Module scripts are stored to the Document's module map once loaded.
|
||||
// So import()ing the same module script will reuse the previously loaded
|
||||
// script.
|
||||
const module_second = await import(
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js"
|
||||
);
|
||||
assert_equals(module_second.result, "resource1 from dynamic1.wbn");
|
||||
}, "Dynamically adding / updating / removing the webbundle element.");
|
||||
|
||||
promise_test(async () => {
|
||||
const classic_script_url =
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js";
|
||||
const element = createWebBundleElement("../resources/wbn/dynamic1.wbn", [
|
||||
classic_script_url,
|
||||
]);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from dynamic1.wbn"
|
||||
);
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {
|
||||
url: "../resources/wbn/dynamic2.wbn",
|
||||
});
|
||||
// Loading the classic script should not reuse the previously loaded
|
||||
// script. So in this case, the script must be loaded from dynamic2.wbn.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from dynamic2.wbn"
|
||||
);
|
||||
document.body.removeChild(new_element);
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from network"
|
||||
);
|
||||
}, "Dynamically loading classic script from web bundle");
|
||||
|
||||
promise_test(async (t) => {
|
||||
// To avoid caching mechanism, this test is using fetch() API with
|
||||
// { cache: 'no-store' } to load the resource.
|
||||
const classic_script_url =
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js";
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url)).text(),
|
||||
"window.report_result('classic script from network');\n"
|
||||
);
|
||||
|
||||
const element1 = createWebBundleElement("../resources/wbn/dynamic1.wbn", [
|
||||
classic_script_url,
|
||||
]);
|
||||
document.body.appendChild(element1);
|
||||
t.add_cleanup(() => {
|
||||
if (element1.parentElement)
|
||||
element1.parentElement.removeChild(element1);
|
||||
});
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: "no-store" })).text(),
|
||||
"window.report_result('classic script from dynamic1.wbn');\n"
|
||||
);
|
||||
|
||||
const element2 = createWebBundleElement("../resources/wbn/dynamic2.wbn", [
|
||||
classic_script_url,
|
||||
]);
|
||||
document.body.appendChild(element2);
|
||||
t.add_cleanup(() => {
|
||||
if (element2.parentElement)
|
||||
element2.parentElement.removeChild(element2);
|
||||
});
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: "no-store" })).text(),
|
||||
"window.report_result('classic script from dynamic2.wbn');\n"
|
||||
);
|
||||
|
||||
document.body.removeChild(element2);
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: "no-store" })).text(),
|
||||
"window.report_result('classic script from dynamic1.wbn');\n"
|
||||
);
|
||||
|
||||
document.body.removeChild(element1);
|
||||
|
||||
assert_equals(
|
||||
await (await fetch(classic_script_url, { cache: "no-store" })).text(),
|
||||
"window.report_result('classic script from network');\n"
|
||||
);
|
||||
}, "Multiple web bundle elements. The last added element must be refered.");
|
||||
|
||||
promise_test(async () => {
|
||||
const classic_script_url =
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/classic_script.js";
|
||||
const scope =
|
||||
"https://{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/";
|
||||
const element = createWebBundleElement(
|
||||
"../resources/wbn/dynamic1.wbn",
|
||||
[],
|
||||
{ scopes: [scope] }
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from dynamic1.wbn"
|
||||
);
|
||||
const new_element = removeAndAppendNewElementWithUpdatedRule(element, {
|
||||
url: "../resources/wbn/dynamic2.wbn",
|
||||
});
|
||||
// Loading the classic script should not reuse the previously loaded
|
||||
// script. So in this case, the script must be loaded from dynamic2.wbn.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from dynamic2.wbn"
|
||||
);
|
||||
// Changes the scope not to hit the classic_script.js.
|
||||
const new_element2 = removeAndAppendNewElementWithUpdatedRule(
|
||||
new_element,
|
||||
{ scopes: [scope + "dummy"] }
|
||||
);
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from network"
|
||||
);
|
||||
// Adds the scope to hit the classic_script.js.
|
||||
const new_element3 = removeAndAppendNewElementWithUpdatedRule(
|
||||
new_element2,
|
||||
{ scopes: [scope + "dummy", scope + "classic_"] }
|
||||
);
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from dynamic2.wbn"
|
||||
);
|
||||
document.body.removeChild(new_element3);
|
||||
// And in this case, the script must be loaded from network.
|
||||
assert_equals(
|
||||
await loadScriptAndWaitReport(classic_script_url),
|
||||
"classic script from network"
|
||||
);
|
||||
}, "Dynamically loading classic script from web bundle with scopes");
|
||||
|
||||
promise_test(() => {
|
||||
return addWebBundleElementAndWaitForLoad(
|
||||
"../resources/wbn/dynamic1.wbn?test-event",
|
||||
/*resources=*/ [],
|
||||
{ crossOrigin: undefined }
|
||||
);
|
||||
}, "The webbundle element fires a load event on load success");
|
||||
|
||||
promise_test((t) => {
|
||||
return addWebBundleElementAndWaitForError(
|
||||
"../resources/wbn/nonexistent.wbn",
|
||||
/*resources=*/ [],
|
||||
{ crossOrigin: undefined }
|
||||
);
|
||||
}, "The webbundle element fires an error event on load failure");
|
||||
|
||||
promise_test(async () => {
|
||||
const module_script_url =
|
||||
"https://www1.{{domains[]}}:{{ports[https][0]}}/web-bundle/resources/wbn/dynamic/resource1.js";
|
||||
const element = createWebBundleElement(
|
||||
"../resources/wbn/dynamic1-crossorigin.wbn",
|
||||
[module_script_url]
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
const module = await import(module_script_url);
|
||||
assert_equals(module.result, "resource1 from network");
|
||||
}, "Subresource URL must be same-origin with bundle URL");
|
||||
|
||||
promise_test(async () => {
|
||||
const url = "uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720";
|
||||
const element = createWebBundleElement(
|
||||
"../resources/wbn/uuid-in-package.wbn",
|
||||
[url]
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), "OK");
|
||||
document.body.removeChild(element);
|
||||
}, "Subresource loading with uuid-in-package: URL with resources attribute");
|
||||
|
||||
promise_test(async () => {
|
||||
const url = "uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720";
|
||||
const element = createWebBundleElement(
|
||||
"../resources/wbn/uuid-in-package.wbn",
|
||||
[],
|
||||
{ scopes: ["uuid-in-package:"] }
|
||||
);
|
||||
document.body.appendChild(element);
|
||||
assert_equals(await loadScriptAndWaitReport(url), "OK");
|
||||
document.body.removeChild(element);
|
||||
}, "Subresource loading with uuid-in-package: URL with scopes attribute");
|
||||
|
||||
async function loadScriptAndWaitReport(script_url) {
|
||||
const result_promise = new Promise((resolve) => {
|
||||
// This function will be called from script.js
|
||||
window.report_result = resolve;
|
||||
});
|
||||
|
||||
const script = document.createElement("script");
|
||||
script.src = script_url;
|
||||
document.body.appendChild(script);
|
||||
return result_promise;
|
||||
}
|
||||
|
||||
function removeAndAppendNewElementWithUpdatedRule(element, new_rule) {
|
||||
const new_element = createNewWebBundleElementWithUpdatedRule(
|
||||
element,
|
||||
new_rule
|
||||
);
|
||||
element.remove();
|
||||
document.body.appendChild(new_element);
|
||||
return new_element;
|
||||
}
|
||||
</script>
|
||||
</body>
|
|
@ -1,5 +1,4 @@
|
|||
<DOCTYPE html>
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<title>HTMLScriptElement.supports webbundle</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
Loading…
Add table
Add a link
Reference in a new issue