diff options
Diffstat (limited to 'testing/web-platform/tests/web-bundle/subresource-loading/subresource-load.https.tentative.sub.html')
-rw-r--r-- | testing/web-platform/tests/web-bundle/subresource-loading/subresource-load.https.tentative.sub.html | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-bundle/subresource-loading/subresource-load.https.tentative.sub.html b/testing/web-platform/tests/web-bundle/subresource-loading/subresource-load.https.tentative.sub.html new file mode 100644 index 0000000000..10c207020c --- /dev/null +++ b/testing/web-platform/tests/web-bundle/subresource-loading/subresource-load.https.tentative.sub.html @@ -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> |