| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 1 | <!DOCTYPE html> |
| 2 | <script src="/resources/testharness.js"></script> |
| 3 | <script src="/resources/testharnessreport.js"></script> |
| Dominic Farolino | 7d985c2 | 2018-10-26 03:11:12 | [diff] [blame] | 4 | <script src="/common/get-host-info.sub.js"></script> |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 5 | <body> |
| 6 | <script> |
| Dominic Farolino | 7d985c2 | 2018-10-26 03:11:12 | [diff] [blame] | 7 | host_info = get_host_info(); |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 8 | |
| 9 | function verifyNumberOfDownloads(url, number) { |
| 10 | var numDownloads = 0; |
| 11 | let absoluteURL = new URL(url, location.href).href; |
| 12 | performance.getEntriesByName(absoluteURL).forEach(entry => { |
| 13 | if (entry.transferSize > 0) { |
| 14 | numDownloads++; |
| 15 | } |
| 16 | }); |
| 17 | assert_equals(numDownloads, number, url); |
| 18 | } |
| 19 | |
| 20 | function attachAndWaitForLoad(element) { |
| 21 | return new Promise((resolve, reject) => { |
| 22 | element.onload = resolve; |
| 23 | element.onerror = reject; |
| 24 | document.body.appendChild(element); |
| 25 | }); |
| 26 | } |
| 27 | |
| 28 | function attachAndWaitForError(element) { |
| 29 | return new Promise((resolve, reject) => { |
| 30 | element.onload = reject; |
| 31 | element.onerror = resolve; |
| 32 | document.body.appendChild(element); |
| 33 | }); |
| 34 | } |
| 35 | |
| 36 | promise_test(function(t) { |
| 37 | var link = document.createElement('link'); |
| 38 | link.rel = 'modulepreload'; |
| 39 | link.href = 'resources/dummy.js'; |
| 40 | return attachAndWaitForLoad(link).then(() => { |
| 41 | verifyNumberOfDownloads('resources/dummy.js', 1); |
| 42 | |
| 43 | // Verify that <script> doesn't fetch the module again. |
| 44 | var script = document.createElement('script'); |
| 45 | script.type = 'module'; |
| 46 | script.src = 'resources/dummy.js'; |
| 47 | return attachAndWaitForLoad(script); |
| 48 | }).then(() => { |
| 49 | verifyNumberOfDownloads('resources/dummy.js', 1); |
| 50 | }); |
| 51 | }, 'link rel=modulepreload'); |
| 52 | |
| Dominic Farolino | 7d985c2 | 2018-10-26 03:11:12 | [diff] [blame] | 53 | /** |
| 54 | * Begin tests to ensure crossorigin value behaves the same on |
| 55 | * link rel=modulepreload as it does script elements. |
| 56 | */ |
| 57 | promise_test(function(t) { |
| 58 | document.cookie = 'same=1'; |
| 59 | var link = document.createElement('link'); |
| 60 | link.rel = 'modulepreload'; |
| 61 | link.crossorigin = 'anonymous'; |
| 62 | link.href = 'resources/dummy.js?sameOriginAnonymous'; |
| 63 | return attachAndWaitForLoad(link).then(() => { |
| 64 | verifyNumberOfDownloads('resources/dummy.js?sameOriginAnonymous', 1); |
| 65 | |
| 66 | // Verify that <script> doesn't fetch the module again. |
| 67 | var script = document.createElement('script'); |
| 68 | script.type = 'module'; |
| 69 | script.crossorigin = 'anonymous'; |
| 70 | script.src = 'resources/dummy.js?sameOriginAnonymous'; |
| 71 | return attachAndWaitForLoad(script); |
| 72 | }).then(() => { |
| 73 | verifyNumberOfDownloads('resources/dummy.js?sameOriginAnonymous', 1); |
| 74 | }); |
| 75 | }, 'same-origin link rel=modulepreload crossorigin=anonymous'); |
| 76 | |
| 77 | promise_test(function(t) { |
| 78 | var link = document.createElement('link'); |
| 79 | link.rel = 'modulepreload'; |
| 80 | link.crossorigin = 'use-credentials'; |
| 81 | link.href = 'resources/dummy.js?sameOriginUseCredentials'; |
| 82 | return attachAndWaitForLoad(link).then(() => { |
| 83 | verifyNumberOfDownloads('resources/dummy.js?sameOriginUseCredentials', 1); |
| 84 | |
| 85 | // Verify that <script> doesn't fetch the module again. |
| 86 | var script = document.createElement('script'); |
| 87 | script.type = 'module'; |
| 88 | script.crossorigin = 'use-credentials'; |
| 89 | script.src = 'resources/dummy.js?sameOriginUseCredentials'; |
| 90 | return attachAndWaitForLoad(script); |
| 91 | }).then(() => { |
| 92 | verifyNumberOfDownloads('resources/dummy.js?sameOriginUseCredentials', 1); |
| 93 | }); |
| 94 | }, 'same-origin link rel=modulepreload crossorigin=use-credentials'); |
| 95 | |
| 96 | promise_test(function(t) { |
| 97 | const setCookiePromise = fetch( |
| 98 | `${host_info.HTTP_REMOTE_ORIGIN}/cookies/resources/set-cookie.py?name=cross&path=/preload/`, |
| 99 | { |
| 100 | mode: 'no-cors', |
| 101 | credentials: 'include', |
| 102 | }); |
| 103 | |
| 104 | return setCookiePromise.then(() => { |
| 105 | var link = document.createElement('link'); |
| 106 | link.rel = 'modulepreload'; |
| 107 | link.href = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`; |
| 108 | return attachAndWaitForLoad(link); |
| 109 | }).then(() => { |
| 110 | verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`, 1); |
| 111 | |
| 112 | // Verify that <script> doesn't fetch the module again. |
| 113 | var script = document.createElement('script'); |
| 114 | script.type = 'module'; |
| 115 | script.src = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`; |
| 116 | return attachAndWaitForLoad(script); |
| 117 | }).then(() => { |
| 118 | verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginNone`, 1); |
| 119 | }); |
| 120 | }, 'cross-origin link rel=modulepreload'); |
| 121 | |
| 122 | promise_test(function(t) { |
| 123 | var link = document.createElement('link'); |
| 124 | link.rel = 'modulepreload'; |
| 125 | link.crossorigin = 'anonymous'; |
| 126 | link.href = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`; |
| 127 | return attachAndWaitForLoad(link).then(() => { |
| 128 | verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`, 1); |
| 129 | |
| 130 | // Verify that <script> doesn't fetch the module again. |
| 131 | var script = document.createElement('script'); |
| 132 | script.type = 'module'; |
| 133 | script.crossorigin = 'anonymous'; |
| 134 | script.src = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`; |
| 135 | return attachAndWaitForLoad(script); |
| 136 | }).then(() => { |
| 137 | verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginAnonymous`, 1); |
| 138 | }); |
| 139 | }, 'cross-origin link rel=modulepreload crossorigin=anonymous'); |
| 140 | |
| 141 | promise_test(function(t) { |
| 142 | var link = document.createElement('link'); |
| 143 | link.rel = 'modulepreload'; |
| 144 | link.crossorigin = 'use-credentials'; |
| 145 | link.href = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`; |
| 146 | return attachAndWaitForLoad(link).then(() => { |
| 147 | verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`, 1); |
| 148 | |
| 149 | // Verify that <script> doesn't fetch the module again. |
| 150 | var script = document.createElement('script'); |
| 151 | script.type = 'module'; |
| 152 | script.crossorigin = 'use-credentials'; |
| 153 | script.src = `${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`; |
| 154 | return attachAndWaitForLoad(script); |
| 155 | }).then(() => { |
| 156 | verifyNumberOfDownloads(`${host_info.HTTP_REMOTE_ORIGIN}/preload/resources/cross-origin-module.py?crossOriginUseCredentials`, 1); |
| 157 | }); |
| 158 | }, 'cross-origin link rel=modulepreload crossorigin=use-credentials'); |
| 159 | /** |
| 160 | * End link rel=modulepreload crossorigin attribute tests. |
| 161 | */ |
| 162 | |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 163 | promise_test(function(t) { |
| 164 | var link = document.createElement('link'); |
| 165 | link.rel = 'modulepreload'; |
| 166 | link.href = 'resources/module1.js'; |
| 167 | return attachAndWaitForLoad(link).then(() => { |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 168 | verifyNumberOfDownloads('resources/module1.js', 1); |
| Kunihiko Sakamoto | 95cea0b | 2017-12-18 03:30:29 | [diff] [blame] | 169 | // The load event fires before (optional) submodules fetch. |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 170 | verifyNumberOfDownloads('resources/module2.js', 0); |
| 171 | |
| 172 | var script = document.createElement('script'); |
| 173 | script.type = 'module'; |
| 174 | script.src = 'resources/module1.js'; |
| 175 | return attachAndWaitForLoad(script); |
| 176 | }).then(() => { |
| 177 | verifyNumberOfDownloads('resources/module1.js', 1); |
| 178 | verifyNumberOfDownloads('resources/module2.js', 1); |
| 179 | }); |
| 180 | }, 'link rel=modulepreload with submodules'); |
| 181 | |
| 182 | promise_test(function(t) { |
| 183 | var link = document.createElement('link'); |
| 184 | link.rel = 'modulepreload'; |
| 185 | link.href = 'resources/syntax-error.js'; |
| Hiroshige Hayashizaki | 56bf49d | 2017-12-05 17:21:56 | [diff] [blame] | 186 | return attachAndWaitForLoad(link); |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 187 | }, 'link rel=modulepreload for a module with syntax error'); |
| 188 | |
| 189 | promise_test(function(t) { |
| 190 | var link = document.createElement('link'); |
| 191 | link.rel = 'modulepreload'; |
| 192 | link.href = 'resources/not-exist.js'; |
| 193 | return attachAndWaitForError(link); |
| 194 | }, 'link rel=modulepreload for a module with network error'); |
| 195 | |
| 196 | promise_test(function(t) { |
| 197 | var link = document.createElement('link'); |
| 198 | link.rel = 'modulepreload'; |
| 199 | link.href = null; |
| 200 | return attachAndWaitForError(link); |
| 201 | }, 'link rel=modulepreload with bad href attribute'); |
| 202 | |
| Kunihiko Sakamoto | ad1c8d8 | 2017-11-16 03:58:33 | [diff] [blame] | 203 | promise_test(function(t) { |
| 204 | var link = document.createElement('link'); |
| 205 | link.rel = 'modulepreload'; |
| 206 | link.href = 'resources/module1.js?as-script'; |
| 207 | link.as = 'script' |
| 208 | return attachAndWaitForLoad(link); |
| 209 | }, 'link rel=modulepreload as=script'); |
| 210 | |
| 211 | promise_test(function(t) { |
| 212 | var link = document.createElement('link'); |
| 213 | link.rel = 'modulepreload'; |
| 214 | link.href = 'resources/module1.js?as-image'; |
| 215 | link.as = 'image' |
| 216 | return attachAndWaitForError(link); |
| 217 | }, 'link rel=modulepreload with invalid as= value'); |
| 218 | |
| Kunihiko Sakamoto | c16fbd4 | 2017-11-21 01:44:54 | [diff] [blame] | 219 | promise_test(function(t) { |
| 220 | var link = document.createElement('link'); |
| 221 | link.rel = 'modulepreload'; |
| 222 | link.href = 'resources/module1.js?integrity-match'; |
| 223 | link.integrity = 'sha256-ZPBZ+J9CiHzZXaBBluSeCpjzuTUkT+rSWIdXUV3AtVo=' |
| 224 | return attachAndWaitForLoad(link); |
| 225 | }, 'link rel=modulepreload with integrity match'); |
| 226 | |
| 227 | promise_test(function(t) { |
| 228 | var link = document.createElement('link'); |
| 229 | link.rel = 'modulepreload'; |
| 230 | link.href = 'resources/module1.js?integrity-doesnotmatch'; |
| 231 | link.integrity = 'sha384-doesnotmatch' |
| 232 | return attachAndWaitForError(link); |
| 233 | }, 'link rel=modulepreload with integrity mismatch'); |
| 234 | |
| Kunihiko Sakamoto | 828d028 | 2017-11-10 07:01:59 | [diff] [blame] | 235 | </script> |
| 236 | </body> |