diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html')
-rw-r--r-- | testing/web-platform/tests/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html b/testing/web-platform/tests/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html new file mode 100644 index 0000000000..81d87bcbf0 --- /dev/null +++ b/testing/web-platform/tests/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html @@ -0,0 +1,329 @@ +<!DOCTYPE html> +<title>script type="webbundle" reuses webbundle resources</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")); + }); + + const wbn_url = "../resources/wbn/subresource.wbn"; + const wbn_suffix = "subresource.wbn"; + const resource1 = "root.js"; + const resource2 = "submodule.js"; + + const resource1_url = `../resources/wbn/${resource1}`; + const resource2_url = `../resources/wbn/${resource2}`; + + let script1; + let script2; + + function cleanUp() { + if (script1) { + script1.remove(); + } + if (script2) { + script2.remove(); + } + } + + async function assertResource1CanBeFetched() { + const response = await fetch(resource1_url); + const text = await response.text(); + assert_equals(text, "export * from './submodule.js';\n"); + } + + async function assertResource1CanNotBeFetched() { + const response = await fetch(resource1_url); + assert_equals(response.status, 404); + } + + async function assertResource2CanBeFetched() { + const response = await fetch(resource2_url); + const text = await response.text(); + assert_equals(text, "export const result = 'OK';\n"); + } + + function createScriptWebBundle1() { + return createWebBundleElement(wbn_url, /*resources=*/ [resource1]); + } + + function createScriptWebBundle2(options) { + return createWebBundleElement( + wbn_url, + /*resources=*/ [resource2], + /*options=*/ options + ); + } + + async function appendScriptWebBundle1AndFetchResource1() { + clearWebBundleFetchCount(); + script1 = createScriptWebBundle1(); + document.body.append(script1); + await assertResource1CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 1); + } + + function clearWebBundleFetchCount() { + performance.clearResourceTimings(); + } + + function webBundleFetchCount(web_bundle_suffix) { + return performance + .getEntriesByType("resource") + .filter((e) => e.name.endsWith(web_bundle_suffix)).length; + } + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Append script2 without removing script1. + // script2 should fetch the wbn again. + script2 = createScriptWebBundle2(); + document.body.appendChild(script2); + + await assertResource1CanBeFetched(); + await assertResource2CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 1); + }, "A webbundle should be fetched again when new script element is appended."); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Remove script1, then append script2 + // script2 should reuse webbundle resources. + script1.remove(); + script2 = createScriptWebBundle2(); + document.body.append(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 0); + }, "'remove(), then append()' should reuse webbundle resources"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + clearWebBundleFetchCount(); + script1 = createScriptWebBundle1(); + await addElementAndWaitForLoad(script1); + clearWebBundleFetchCount(); + + // Remove script1, then append script2 + // script2 should reuse webbundle resources. + // And it should also fire a load event. + script1.remove(); + script2 = createScriptWebBundle2(); + await addElementAndWaitForLoad(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 0); + }, "'remove(), then append()' should reuse webbundle resources and both scripts should fire load events"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + script1 = createWebBundleElement("nonexistent.wbn", []); + await addElementAndWaitForError(script1); + + // Remove script1, then append script2 + // script2 should reuse webbundle resources (but we don't verify that). + // And it should also fire an error event. + script1.remove(); + script2 = createWebBundleElement("nonexistent.wbn", []); + await addElementAndWaitForError(script2); + }, "'remove(), then append()' should reuse webbundle resources and both scripts should fire error events"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Remove script1, then append script2 with an explicit 'same-origin' credentials mode. + script1.remove(); + script2 = createScriptWebBundle2({ credentials: "same-origin" }); + document.body.append(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 0); + }, "Should reuse webbundle resources if a credential mode is same"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Remove script1, then append script2 with a different credentials mode. + script1.remove(); + script2 = createScriptWebBundle2({ credentials: "omit" }); + document.body.append(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 1); + }, "Should not reuse webbundle resources if a credentials mode is different (same-origin vs omit)"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Remove script1, then append script2 with a different credentials mode. + script1.remove(); + script2 = createScriptWebBundle2({ credentials: "include" }); + document.body.append(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 1); + }, "Should not reuse webbundle resources if a credential mode is different (same-origin vs include"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Remove script1, then append the removed one. + script1.remove(); + document.body.append(script1); + + await assertResource1CanNotBeFetched(); + assert_equals(webBundleFetchCount(wbn_suffix), 0); + }, "'remove(), then append()' for the same element should reuse webbundle resources"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Multiple 'remove(), then append()' for the same element. + script1.remove(); + document.body.append(script1); + + script1.remove(); + document.body.append(script1); + + await assertResource1CanNotBeFetched(); + 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(); + clearWebBundleFetchCount(); + + // Remove script1. + script1.remove(); + + // Then append script2 in a separet task. + await new Promise((resolve) => t.step_timeout(resolve, 0)); + script2 = createScriptWebBundle2(); + document.body.append(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + 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(); + clearWebBundleFetchCount(); + + // Use replaceWith() to replace script1 with script2. + // script2 should reuse webbundle resources. + script2 = createScriptWebBundle2(); + script1.replaceWith(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + + assert_equals(webBundleFetchCount(wbn_suffix), 0); + }, "replaceWith() should reuse webbundle resources."); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + await appendScriptWebBundle1AndFetchResource1(); + clearWebBundleFetchCount(); + + // Move script1 to another document. Then append script2. + // script2 should reuse webbundle resources. + const another_document = new Document(); + another_document.append(script1); + script2 = createScriptWebBundle2(); + document.body.append(script2); + + await assertResource1CanNotBeFetched(); + await assertResource2CanBeFetched(); + + assert_equals(webBundleFetchCount(wbn_suffix), 0); + + // TODO: Test the following cases: + // - The resources are not loaded from the webbundle in the new Document + // (Probably better to use a <iframe>.contentDocument) + // - Even if we move the script element back to the original Document, + // even immediately, the resources are not loaded from the webbundle in the + // original Document. + }, "append() should reuse webbundle resoruces even if the old script was moved to another document."); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + clearWebBundleFetchCount(); + 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] + ); + await addElementAndWaitForLoad(script2); + + assert_equals(webBundleFetchCount(wbn_suffix + "?pipe=trickle(d0.1)"), 1); + }, "Even if the bundle is still loading, we should reuse the resources."); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + script1 = createScriptWebBundle1(); + document.body.appendChild(script1); + + // Don't wait for the load event for script1. + script1.remove(); + script2 = createScriptWebBundle2(); + + // Load event should be fired for script2 regardless of + // whether script1 fired a load or not. + await addElementAndWaitForLoad(script2); + }, "When reusing the resources with script2, a load event should be fired regardless of if the script1 fired a load"); + + promise_test(async (t) => { + t.add_cleanup(cleanUp); + script1 = createWebBundleElement("nonexistent.wbn", []); + document.body.appendChild(script1); + + // Don't wait for the error event for script1. + script1.remove(); + script2 = createWebBundleElement("nonexistent.wbn", []); + + // Error event should be fired for script2 regardless of + // whether script1 fired an error event or not. + await addElementAndWaitForError(script2); + }, "When reusing the resources with script2, an error event should be fired regardless of if the script1 fired an error"); + </script> +</body> |