diff options
Diffstat (limited to 'testing/web-platform/tests/preload/modulepreload.html')
-rw-r--r-- | testing/web-platform/tests/preload/modulepreload.html | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/testing/web-platform/tests/preload/modulepreload.html b/testing/web-platform/tests/preload/modulepreload.html new file mode 100644 index 0000000000..4764b58261 --- /dev/null +++ b/testing/web-platform/tests/preload/modulepreload.html @@ -0,0 +1,383 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<body> +<script> +host_info = get_host_info(); + +function verifyNumberOfDownloads(url, number, allowTransferSizeOfZero = false) { + var numDownloads = 0; + let absoluteURL = new URL(url, location.href).href; + performance.getEntriesByName(absoluteURL).forEach(entry => { + if (entry.transferSize > 0 || allowTransferSizeOfZero) { + numDownloads++; + } + }); + assert_equals(numDownloads, number, url); +} + +function attachAndWaitForLoad(element) { + return new Promise((resolve, reject) => { + element.onload = resolve; + element.onerror = reject; + document.body.appendChild(element); + }); +} + +function attachAndWaitForError(element) { + return new Promise((resolve, reject) => { + element.onload = reject; + element.onerror = resolve; + document.body.appendChild(element); + }); +} + +function attachAndWaitForTimeout(element, t) { + return new Promise((resolve, reject) => { + element.onload = reject; + element.onerror = reject; + t.step_timeout(resolve, 1000); + document.body.appendChild(element); + }); +} + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/dummy.js?unique'; + return attachAndWaitForLoad(link).then(() => { + verifyNumberOfDownloads('resources/dummy.js?unique', 1); + + // Verify that <script> doesn't fetch the module again. + var script = document.createElement('script'); + script.type = 'module'; + script.src = 'resources/dummy.js?unique'; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads('resources/dummy.js?unique', 1); + }); +}, 'link rel=modulepreload'); + +/** + * Begin tests to ensure crossorigin value behaves the same on + * link rel=modulepreload as it does script elements. + */ +promise_test(function(t) { + document.cookie = 'same=1'; + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.crossOrigin = 'anonymous'; + link.href = 'resources/dummy.js?sameOriginAnonymous'; + return attachAndWaitForLoad(link).then(() => { + verifyNumberOfDownloads('resources/dummy.js?sameOriginAnonymous', 1); + + // Verify that <script> doesn't fetch the module again. + var script = document.createElement('script'); + script.type = 'module'; + script.crossOrigin = 'anonymous'; + script.src = 'resources/dummy.js?sameOriginAnonymous'; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads('resources/dummy.js?sameOriginAnonymous', 1); + }); +}, 'same-origin link rel=modulepreload crossorigin=anonymous'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.crossOrigin = 'use-credentials'; + link.href = 'resources/dummy.js?sameOriginUseCredentials'; + return attachAndWaitForLoad(link).then(() => { + verifyNumberOfDownloads('resources/dummy.js?sameOriginUseCredentials', 1); + + // Verify that <script> doesn't fetch the module again. + var script = document.createElement('script'); + script.type = 'module'; + script.crossOrigin = 'use-credentials'; + script.src = 'resources/dummy.js?sameOriginUseCredentials'; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads('resources/dummy.js?sameOriginUseCredentials', 1); + }); +}, 'same-origin link rel=modulepreload crossorigin=use-credentials'); + +promise_test(function(t) { + const setCookiePromise = fetch( + `${host_info.HTTP_REMOTE_ORIGIN}/cookies/resources/set-cookie.py?name=cross&path=/preload/`, + { + mode: 'no-cors', + credentials: 'include', + }); + + return setCookiePromise.then(() => { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`; + return attachAndWaitForLoad(link); + }).then(() => { + verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`, 1, true); + + // Verify that <script> doesn't fetch the module again. + var script = document.createElement('script'); + script.type = 'module'; + script.src = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`, 1, true); + }); +}, 'cross-origin link rel=modulepreload'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.crossOrigin = 'anonymous'; + link.href = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`; + return attachAndWaitForLoad(link).then(() => { + verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`, 1, true); + + // Verify that <script> doesn't fetch the module again. + var script = document.createElement('script'); + script.type = 'module'; + script.crossOrigin = 'anonymous'; + script.src = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`, 1, true); + }); +}, 'cross-origin link rel=modulepreload crossorigin=anonymous'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.crossOrigin = 'use-credentials'; + link.href = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`; + return attachAndWaitForLoad(link).then(() => { + verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`, 1, true); + + // Verify that <script> doesn't fetch the module again. + var script = document.createElement('script'); + script.type = 'module'; + script.crossOrigin = 'use-credentials'; + script.src = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`, 1, true); + }); +}, 'cross-origin link rel=modulepreload crossorigin=use-credentials'); +/** + * End link rel=modulepreload crossorigin attribute tests. + */ + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.js?submodule'; + return attachAndWaitForLoad(link).then(() => { + verifyNumberOfDownloads('resources/module1.js?submodule', 1); + // The load event fires before (optional) submodules fetch. + verifyNumberOfDownloads('resources/module2.js', 0); + + var script = document.createElement('script'); + script.type = 'module'; + script.src = 'resources/module1.js?submodule'; + return attachAndWaitForLoad(script); + }).then(() => { + verifyNumberOfDownloads('resources/module1.js?submodule', 1); + verifyNumberOfDownloads('resources/module2.js', 1); + }); +}, 'link rel=modulepreload with submodules'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/syntax-error.js'; + return attachAndWaitForLoad(link); +}, 'link rel=modulepreload for a module with syntax error'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/not-exist.js'; + return attachAndWaitForError(link); +}, 'link rel=modulepreload for a module with network error'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = null; + return attachAndWaitForError(link); +}, 'link rel=modulepreload with bad href attribute'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.js?as-script'; + link.as = 'script' + return attachAndWaitForLoad(link); +}, 'link rel=modulepreload as=script'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.js?as-image'; + link.as = 'image' + return attachAndWaitForError(link); +}, 'link rel=modulepreload with non-script-like as= value (image)'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.js?as-xslt'; + link.as = 'xslt' + return attachAndWaitForError(link); +}, 'link rel=modulepreload with non-script-like as= value (xslt)'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.js?integrity-match'; + link.integrity = 'sha256-+Ks3iNIiTq2ujlWhvB056cmXobrCFpU9hd60xZ1WCaA=' + return attachAndWaitForLoad(link); +}, 'link rel=modulepreload with integrity match'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.mjs?integrity-match'; + link.integrity = 'sha256-+Ks3iNIiTq2ujlWhvB056cmXobrCFpU9hd60xZ1WCaA=' + return attachAndWaitForLoad(link); +}, 'link rel=modulepreload with integrity match2'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.js?integrity-doesnotmatch'; + link.integrity = 'sha384-doesnotmatch' + return attachAndWaitForError(link); +}, 'link rel=modulepreload with integrity mismatch'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.mjs?integrity-doesnotmatch'; + link.integrity = 'sha256-dOxReWMnMSPfUvxEbBqIrjNh8ZN8n05j7h3JmhF8gQc=' + return attachAndWaitForError(link); +}, 'link rel=modulepreload with integrity mismatch2'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.mjs?integrity-invalid'; + link.integrity = 'sha256-dOxReWMnMSPfUvxEbBqIrjNh8ZN8n05j7h3JmhF8gQc=%' + return attachAndWaitForError(link); +}, 'link rel=modulepreload with integrity mismatch3'); + +promise_test(function(t) { + var link1 = document.createElement('link'); + var link2 = document.createElement('link'); + link1.rel = 'modulepreload'; + link2.rel = 'modulepreload'; + link1.href = 'resources/module1.js?same-url'; + link2.href = 'resources/module1.js?same-url'; + return Promise.all([ + attachAndWaitForLoad(link1), + attachAndWaitForLoad(link2), + ]); +}, 'multiple link rel=modulepreload with same href'); + +promise_test(function(t) { + var link1 = document.createElement('link'); + var link2 = document.createElement('link'); + link1.rel = 'modulepreload'; + link2.rel = 'modulepreload'; + link1.href = 'resources/module2.js?child-before'; + link2.href = 'resources/module1.js?child-before'; + return attachAndWaitForLoad(link1) + .then(() => attachAndWaitForLoad(link2)) + .then(() => new Promise(r => t.step_timeout(r, 1000))) + .then(() => { + verifyNumberOfDownloads('resources/module2.js?child-before', 1); + }); + +}, 'multiple link rel=modulepreload with child module before parent'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.mjs?matching-media'; + link.media = 'all'; + return attachAndWaitForLoad(link); +}, 'link rel=modulepreload with matching media'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.mjs?non-matching-media'; + link.media = 'not all'; + return attachAndWaitForTimeout(link, t); +}, 'link rel=modulepreload with non-matching media'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = 'resources/module1.mjs?empty-media'; + link.media = ''; + return attachAndWaitForLoad(link); +}, 'link rel=modulepreload with empty media'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = ''; + return attachAndWaitForTimeout(link, t); +}, 'link rel=modulepreload with empty href'); + +promise_test(function(t) { + var link = document.createElement('link'); + link.rel = 'modulepreload'; + link.href = ''; + link.as = 'fetch'; + return attachAndWaitForTimeout(link, t); +}, 'link rel=modulepreload with empty href and invalid as= value'); + +promise_test(function(t) { + var link = document.createElement('link'); + var script = document.createElement('script'); + link.rel = 'modulepreload'; + script.type = 'module'; + link.href = 'resources/module1.mjs?non-matching-crossorigin'; + script.src = link.href; + script.crossOrigin = 'anonymous'; + document.body.append(link); + return attachAndWaitForLoad(script); +}, 'link rel=modulepreload and script with non-matching crossorigin values'); + +promise_test(function(t) { + var link = document.createElement('link'); + var script = document.createElement('script'); + link.rel = 'modulepreload'; + script.type = 'module'; + link.href = 'resources/module1.mjs?non-matching-crossorigin'; + script.src = link.href; + link.crossOrigin = 'anonymous'; + script.crossOrigin = 'use-credentials'; + document.body.append(link); + return attachAndWaitForLoad(script); +}, 'link rel=modulepreload and script with non-matching crossorigin values2'); + +promise_test(function(t) { + var link = document.createElement('link'); + var moduleScript = document.createElement('script'); + var classicScript = document.createElement('script'); + link.rel = 'modulepreload'; + moduleScript.type = 'module'; + link.href = 'resources/dummy.js?non-module script'; + classicScript.src = link.href; + moduleScript.src = link.href; + document.body.append(link); + document.body.append(classicScript); + return attachAndWaitForLoad(moduleScript); +}, 'link rel=modulepreload and non-module script'); +</script> +</body> |