diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module')
40 files changed, 709 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json new file mode 100644 index 0000000000..e77e32d338 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/array.json @@ -0,0 +1 @@ +["en", "try"] diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.json Binary files differnew file mode 100644 index 0000000000..d22a45a591 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16be.json diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.json Binary files differnew file mode 100644 index 0000000000..4d1aa264a6 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-16le.json diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json new file mode 100644 index 0000000000..07ba933e86 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/bom-utf-8.json @@ -0,0 +1 @@ +{ "data": "hello" }
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html new file mode 100644 index 0000000000..dfadaba4d1 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-2.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="windows-1250"> +<title>JSON modules: UTF-8 decoding</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script type="module"> + import json from "../serve-with-content-type.py?fn=json-module/utf-8.json" with { type: "json"}; + test(() => { + assert_equals(json.data, "śćążź"); + }, "JSON module should be loaded as utf-8 even though document's encoding is windows-1250"); +</script> +<script type="module"> + import json from "../serve-with-content-type.py?fn=json-module/windows-1250.json&ct=text/json%3Bcharset=windows-1250" with { type: "json"}; + test(() => { + assert_not_equals(json.data, "śćążź", + 'Should be decoded as UTF-8'); + }, "JSON module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header, and this document's encoding is windows-1250"); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js new file mode 100644 index 0000000000..483936a4f7 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset-bom.any.js @@ -0,0 +1,17 @@ +// META: global=window,dedicatedworker,sharedworker +// META: script=/common/utils.js + +promise_test(async () => { + const jsonModule = await import('./bom-utf-8.json', { with: { type: 'json' } }); + assert_equals(jsonModule.default.data, 'hello'); +}, 'UTF-8 BOM should be stripped when decoding JSON module script'); + +promise_test(async test => { + await promise_rejects_js(test, SyntaxError, + import('./bom-utf-16be.json', { with: { type: 'json' } }), 'Expected parse error from UTF-16BE BOM'); +}, 'UTF-16BE BOM should result in parse error in JSON module script'); + +promise_test(async test => { + await promise_rejects_js(test, SyntaxError, + import('./bom-utf-16le.json', { with: { type: 'json' } }), 'Expected parse error from UTF-16LE BOM'); +}, 'UTF-16LE BOM should result in parse error in JSON module script'); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html new file mode 100644 index 0000000000..ce72f0ef1b --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/charset.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>JSON modules: UTF-8 decoding</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script type="module" onerror="unreachable()"> + import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=utf-8" with { type: "json"}; + test(() => { + assert_equals(json.data, "śćążź"); + }, "JSON module should be loaded as utf-8 when charset=utf8 is specified"); +</script> +<script type="module" onerror="unreachable()"> + import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=shift-jis" with { type: "json"}; + test(() => { + assert_equals(json.data, "śćążź"); + }, "JSON module should be loaded as utf-8 when charset=shift-jis is specified"); +</script> +<script type="module" onerror="unreachable()"> + import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=windows-1252" with { type: "json"}; + test(() => { + assert_equals(json.data, "śćążź"); + }, "JSON module should be loaded as utf-8 when charset=windows-1252 is specified"); +</script> +<script type="module" onerror="unreachable()"> + import json from "../serve-with-content-type.py?fn=json-module/utf-8.json&ct=text/json%3Bcharset=utf-7" with { type: "json"};; + test(() => { + assert_equals(json.data, "śćążź"); + }, "JSON module should be loaded as utf-8 when charset=utf-7 is specified"); +</script> +<script type="module" onerror="unreachable()"> + import json from "../serve-with-content-type.py?fn=json-module/windows-1250.json&ct=text/json%3Bcharset=windows-1250" with { type: "json"}; + test(() => { + assert_not_equals(json.data, "śćążź", + 'Should be decoded as UTF-8'); + }, "JSON module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header"); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html new file mode 100644 index 0000000000..99ff2f67e8 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html @@ -0,0 +1,33 @@ +<!doctype html> +<html> +<head> + <title>json-module-crossorigin</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> +<body> + <h1>json-module-crossorigin</h1> + <iframe id="import-WithCORS" src="crossorigin-import-with-cors.sub.html"></iframe> + <iframe id="import-NoCORS" src="crossorigin-import-without-cors.sub.html"></iframe> + <iframe id="import-parseerror-WithCors" src="crossorigin-import-parse-error-with-cors.sub.html"></iframe> + <script> + + var tests = [ + { "obj": async_test("Imported JSON module, cross-origin with CORS"), "id": "import-WithCORS", "expected": "imported JSON: 42" }, + { "obj": async_test("Imported JSON module, cross-origin, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" }, + { "obj": async_test("Imported JSON module with parse error, cross-origin, with CORS"), "id": "import-parseerror-WithCors", "expected": "0-0" }, + ]; + + window.addEventListener("load", function () { + tests.forEach(function (test) { + var target = document.getElementById(test.id); + test.obj.step(function () { + assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value"); + }); + test.obj.done(); + }); + }); + + </script> +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html new file mode 100644 index 0000000000..b89edf8d31 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials-iframe.sub.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> + +<script type="module"> + import json from "./cross-origin.py?id=sameOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" }; + window.sameOriginNoneDescendant = json.requestHadCookies; +</script> +<script type="module" crossOrigin="anonymous"> + import json from "./cross-origin.py?id=sameOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" }; + window.sameOriginAnonymousDescendant = json.requestHadCookies; +</script> +<script type="module" crossOrigin="use-credentials"> + import json from "./cross-origin.py?id=sameOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" }; + window.sameOriginUseCredentialsDescendant = json.requestHadCookies; +</script> +<script type="module"> + import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py?id=crossOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" }; + window.crossOriginNoneDescendant = json.requestHadCookies; +</script> +<script type="module" crossOrigin="anonymous"> + import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py?id=crossOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" }; + window.crossOriginAnonymousDescendant = json.requestHadCookies; +</script> +<script type="module" crossOrigin="use-credentials"> +import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py?id=crossOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" with { type: "json" }; +window.crossOriginUseCredentialsDescendant = json.requestHadCookies; +</script> + +<script type="text/javascript"> +window.addEventListener('load', event => { + window.parent.postMessage({}, '*'); +}); +</script> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html new file mode 100644 index 0000000000..a6df506e21 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/credentials.sub.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +document.cookie = 'milk=1'; + +const setCookiePromise = fetch( + 'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=milk&path=/html/semantics/scripting-1/the-script-element/json-module/', + { + mode: 'no-cors', + credentials: 'include', + }); + +const windowLoadPromise = new Promise(resolve => { + window.addEventListener('load', () => { + resolve(); + }); +}); + +promise_test(t => { + const iframe = document.createElement('iframe'); + + return Promise.all([setCookiePromise, windowLoadPromise]).then(() => { + const messagePromise = new Promise(resolve => { + window.addEventListener('message', event => { + resolve(); + }); + }); + + iframe.src = 'credentials-iframe.sub.html'; + document.body.appendChild(iframe); + + return messagePromise; + }).then(() => { + const w = iframe.contentWindow; + + assert_equals(w.sameOriginNoneDescendant, true, + 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin'); + assert_equals(w.sameOriginAnonymousDescendant, true, + 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin'); + assert_equals(w.sameOriginUseCredentialsDescendant, true, + 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin'); + assert_equals(w.crossOriginNoneDescendant, false, + 'Descendant JSON modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin'); + assert_equals(w.crossOriginAnonymousDescendant, false, + 'Descendant JSON modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin'); + assert_equals(w.crossOriginUseCredentialsDescendant, true, + 'Descendant JSON modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin'); +}); +}, 'JSON Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute'); +</script> +<body> +</body> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py new file mode 100644 index 0000000000..cd56c3628a --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/cross-origin.py @@ -0,0 +1,16 @@ +def main(request, response): + + headers = [ + (b"Content-Type", b"application/json"), + (b"Access-Control-Allow-Origin", request.GET.first(b"origin")), + (b"Access-Control-Allow-Credentials", b"true") + ] + + milk = request.cookies.first(b"milk", None) + + if milk is None: + return headers, u'{"requestHadCookies": false}' + elif milk.value == b"1": + return headers, u'{"requestHadCookies": true}' + + return headers, u'{"requestHadCookies": false}' diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html new file mode 100644 index 0000000000..9972c53d1b --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-parse-error-with-cors.sub.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>json-module-import-cross-domain-parse-error-WithCORS</title> + <script src="../module/crossorigin-common.js"></script> +</head> +<body> + <h1>json-module-import-cross-domain-parse-error-WithCORS</h1> + <script type="module" crossorigin> + import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/parse-error.json?pipe=header(Access-Control-Allow-Origin,*)" with { type: "json" }; + // Push an event to the log indicating that the script was executed. + document._log.push(`imported JSON: ${json.answer}`); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html new file mode 100644 index 0000000000..95fd156df2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-with-cors.sub.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>json-module-import-cross-domain-WithCORS</title> + <script src="../module/crossorigin-common.js"></script> +</head> +<body> + <h1>json-module-import-cross-domain-WithCORS</h1> + <script type="module" crossorigin> + import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/data.json?pipe=header(Access-Control-Allow-Origin,*)" with { type: "json" }; + // Push an event to the log indicating that the script was executed. + document._log.push(`imported JSON: ${json.answer}`); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html new file mode 100644 index 0000000000..b9318c8b20 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/crossorigin-import-without-cors.sub.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>json-module-import-cross-domain-NoCORS</title> + <script src="../module/crossorigin-common.js"></script> +</head> +<body> + <h1>json-module-import-cross-domain-NoCORS</h1> + <script type="module" onerror="document._log.push('error');"> + import json from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/data.json" with { type: "json" }; + // Push an event to the log indicating that the script was executed. + document._log.push(`imported JSON: ${json.answer}`); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json new file mode 100644 index 0000000000..14a0526ebb --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/data.json @@ -0,0 +1,3 @@ +{ + "answer": 42 +}
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json new file mode 100644 index 0000000000..c508d5366f --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/false.json @@ -0,0 +1 @@ +false diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js new file mode 100644 index 0000000000..20459c17e3 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-matches.js @@ -0,0 +1,2 @@ +import json from "./data.json" with { type: "json" }; +window.matchesLog.push(`integrity-matches,json:${json.answer}`); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js new file mode 100644 index 0000000000..0406dbcca5 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity-mismatches.js @@ -0,0 +1,2 @@ +import json "./data.json" with { type: "json" }; +window.mismatchesLog.push(`integrity-mismatches,json:${json.answer}`); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html new file mode 100644 index 0000000000..68a794b973 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/integrity.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title><script> integrity=""</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> +window.matchesLog = []; +window.matchesEvents = []; + +window.mismatchesLog = []; +window.mismatchesEvents = []; +</script> +<script type="module" src="integrity-matches.js" integrity="sha384-VmQQfGzBiLKdyzw4FA4kL4ohu4tyujV68ddgW1aN/1v3cBZNNBn2gDFdVQxfL7+a" onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script> +<script type="module" src="integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script> + +<script type="module"> +test(() => { + assert_array_equals(window.matchesLog, ["integrity-matches,json:42"], "The module and its dependency must have executed"); + assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired"); +}, "The integrity attribute must be verified on the top-level of a module loading a JSON module and allow it to execute when it matches"); + +test(() => { + assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed"); + assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired"); +}, "The integrity attribute must be verified on the top-level of a module loading a JSON module and not allow it to execute when there's a mismatch"); +</script> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js new file mode 100644 index 0000000000..4226c3dc03 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js @@ -0,0 +1,17 @@ +// META: global=window,dedicatedworker,sharedworker + +const content_types = [ + "application/json+protobuf", + "application/json+blah", + "text/x-json", + "text/json+blah", + "application/blahjson", + "image/json", +]; +for (const content_type of content_types) { + promise_test(async test => { + await promise_rejects_js(test, TypeError, + import(`./module.json?pipe=header(Content-Type,${content_type})`, { with: { type: "json"} }), + `Import of a JSON module with MIME type ${content_type} should fail`); + }, `Try importing JSON module with MIME type ${content_type}`); +} diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html new file mode 100644 index 0000000000..cc47da1499 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html @@ -0,0 +1,29 @@ +<!doctype html> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script> + promise_test(async (test) => { + const reg = await navigator.serviceWorker.register('./serviceworker.js', { type: 'module' }); + test.add_cleanup(() => reg.unregister()); + assert_not_equals(reg.installing, undefined); + }, "Javascript importing JSON Module should load within the context of a service worker"); + + promise_test(test => { + return promise_rejects_dom(test, "SecurityError", + navigator.serviceWorker.register('./module.json', { type: 'module' }), + "Attempting to load JSON as a service worker should fail"); + }, "Trying to register a service worker with a top-level JSON Module should fail"); + + promise_test(async (test) => { + const reg = await navigator.serviceWorker.register('./serviceworker-dynamic-import.js', { type: 'module' }); + test.add_cleanup(() => reg.unregister()); + assert_not_equals(reg.installing, undefined); + reg.installing.postMessage("PING"); + const msgEvent = await new Promise(resolve => { + navigator.serviceWorker.onmessage = resolve; + }); + assert_equals(msgEvent.data, "FAILED"); + }, "JSON Module dynamic import should not load within the context of a service worker"); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html new file mode 100644 index 0000000000..54c1892540 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<head> +<title>load/error events for JSON modules</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../resources/load-error-events-helpers.js"></script> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block"> +</head> +<script> + "use strict"; + + var test1_load = event_test('inline, 200, parser-inserted', false, false); + var test1_error = event_test('inline, 404, parser-inserted', false, true); + + var test2_load = event_test('src, 200, parser-inserted', true, false); + var test2_error = event_test('src, 404, parser-inserted', false, true); + + var test3_dynamic_load = event_test('src, 200, not parser-inserted', true, false); + var test3_dynamic_error = event_test('src, 404, not parser-inserted', false, true); + + var test4_dynamic_load = event_test('inline, 200, not parser-inserted', false, false); + var test4_dynamic_error = event_test('inline, 404, not parser-inserted', false, true); + + var script3_dynamic_load = document.createElement('script'); + script3_dynamic_load.setAttribute('type', 'module'); + script3_dynamic_load.onload = () => onLoad(test3_dynamic_load); + script3_dynamic_load.onerror = () => onError(test3_dynamic_load); + script3_dynamic_load.src = "./load-error-events.py?test=test3_dynamic_load"; + document.head.appendChild(script3_dynamic_load); + + var script3_dynamic_error = document.createElement('script'); + script3_dynamic_error.setAttribute('type', 'module'); + script3_dynamic_error.onload = () => onLoad(test3_dynamic_error); + script3_dynamic_error.onerror = () => onError(test3_dynamic_error); + script3_dynamic_error.src = "./load-error-events.py?test=test3_dynamic_error"; + document.head.appendChild(script3_dynamic_error); + + var script4_dynamic_load = document.createElement('script'); + script4_dynamic_load.setAttribute('type', 'module'); + script4_dynamic_load.onload = () => onLoad(test4_dynamic_load); + script4_dynamic_load.onerror = () => onError(test4_dynamic_load); + script4_dynamic_load.async = true; + script4_dynamic_load.appendChild(document.createTextNode(` + import "./module.json" with { type: "json" }; + onExecute(test4_dynamic_load);` + )); + document.head.appendChild(script4_dynamic_load); + + var script4_dynamic_error = document.createElement('script'); + script4_dynamic_error.setAttribute('type', 'module'); + script4_dynamic_error.onload = () => onLoad(test4_dynamic_error); + script4_dynamic_error.onerror = () => onError(test4_dynamic_error); + script4_dynamic_error.async = true; + script4_dynamic_error.appendChild(document.createTextNode(`import "./not_found.json" with { type: "json" };`)); + document.head.appendChild(script4_dynamic_error); +</script> +<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module"> + import "./module.json" with { type: "json"}; + onExecute(test1_load); +</script> +<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module"> + import "./not_found.json" with { type: "json"}; + onExecute(test1_error); +</script> +<script src="./load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);" type="module"></script> +<script src="./load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);" type="module"></script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py new file mode 100644 index 0000000000..244552a693 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/load-error-events.py @@ -0,0 +1,14 @@ +import re + +def main(request, response): + headers = [(b"Content-Type", b"text/javascript")] + test = request.GET.first(b'test') + assert(re.match(b'^[a-zA-Z0-9_]+$', test)) + + status = 200 + if test.find(b'_load') >= 0: + content = b'import "./module.json" with { type: "json"}; %s.executed = true;' % test + else: + content = b'import "./not_found.json" with { type: "json"}; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test + + return status, headers, content diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html new file mode 100644 index 0000000000..05fc264f36 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>JSON modules</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +const t = async_test(); +</script> +<script type="module" onerror="t.step(() => assert_unreached(event))"> +import v from "./module.json" with { type: "json" }; +t.step(() => { + assert_equals(typeof v, "object"); + assert_array_equals(Object.keys(v), ["test"]); + assert_equals(v.test, true); + t.done(); +}); +</script> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json new file mode 100644 index 0000000000..f834b2a4e8 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/module.json @@ -0,0 +1,3 @@ +{ + "test": true +} diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js new file mode 100644 index 0000000000..ae78ddf072 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/non-object.any.js @@ -0,0 +1,14 @@ +// META: global=window,dedicatedworker,sharedworker + +for (const value of [null, true, false, "string"]) { + promise_test(async t => { + const result = await import(`./${value}.json`, { with: { type: "json" } }); + assert_equals(result.default, value); + }, `Non-object: ${value}`); +} + +promise_test(async t => { + const result = await import("./array.json", { with: { type: "json" } }); + assert_array_equals(result.default, ["en", "try"]); +}, "Non-object: array"); + diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json new file mode 100644 index 0000000000..19765bd501 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/null.json @@ -0,0 +1 @@ +null diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html new file mode 100644 index 0000000000..88fb23a00d --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>JSON modules: parse error</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +setup({ + allow_uncaught_exception: true, +}); +async_test(t => { + window.addEventListener("error", t.step_func_done(e => { + assert_true(e instanceof ErrorEvent, "ErrorEvent"); + assert_equals(e.filename, new URL("parse-error.json", location).href); + assert_true(e.error instanceof SyntaxError, "SyntaxError"); + })); +}); +</script> +<script type="module"> +import v from "./parse-error.json" with { type: "json" }; +</script> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json new file mode 100644 index 0000000000..98232c64fc --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/parse-error.json @@ -0,0 +1 @@ +{ diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py new file mode 100644 index 0000000000..e9f0f1789b --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py @@ -0,0 +1,6 @@ +def main(request, response): + referrer = request.headers.get(b"referer", b"") + response_headers = [(b"Content-Type", b"application/json"), + (b"Access-Control-Allow-Origin", b"*")] + return (200, response_headers, + b'{"referrer": "' + referrer + b'"}') diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html new file mode 100644 index 0000000000..1509c853e2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/referrer-policies.sub.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html> +<head> +<title>Referrers with JSON module requests</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script type="module"> + // "name" parameter is necessary for bypassing the module map. + import referrerSame from "./referrer-checker.py?name=sameNoReferrerPolicy" with { type: "json"}; + import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteNoReferrerPolicy" with { type: "json"}; + + const origin = (new URL(location.href)).origin + "/"; + const originUrl = location.href; + + test(t => { + assert_equals( + referrerSame.referrer, originUrl, + "Referrer URL should be sent for the same-origin top-level script."); + }, "Importing a same-origin top-level script with the default referrer policy."); + + test(t => { + assert_equals( + referrerRemote.referrer, origin, + "Referrer origin should be sent for the remote-origin top-level script."); + }, "Importing a remote-origin top-level script with the default referrer policy."); +</script> +<script type="module" referrerpolicy="origin"> + import referrerSame from "./referrer-checker.py?name=sameReferrerPolicyOrigin" with { type: "json"}; + import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteReferrerPolicyOrigin" with { type: "json"}; + + const origin = (new URL(location.href)).origin + "/"; + + test(t => { + assert_equals( + referrerSame.referrer, origin, + "Referrer origin should be sent for the same-origin top-level script."); + }, "Importing a same-origin top-level script with the origin policy."); + + test(t => { + assert_equals( + referrerRemote.referrer, origin, + "Referrer origin should be sent for the remote-origin top-level script."); + }, "Importing a remote-origin top-level script with the origin policy."); + +</script> +<script type="module" referrerpolicy="no-referrer"> + import referrerSame from "./referrer-checker.py?name=sameReferrerPolicyNoReferrer" with { type: "json"}; + import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteReferrerPolicyNoReferrer" with { type: "json"}; + + test(t => { + assert_equals( + referrerSame.referrer, "", + "No referrer should be sent for the same-origin top-level script."); + }, "Importing a same-origin top-level script with the no-referrer policy."); + + test(t => { + assert_equals( + referrerRemote.referrer, "", + "No referrer should be sent for the remote-origin top-level script."); + }, "Importing a remote-origin top-level script with the no-referrer policy."); + +</script> +<script type="module" referrerpolicy="unsafe-url"> + import referrerSame from "./referrer-checker.py?name=sameNoReferrerPolicyUnsafeUrl" with { type: "json"}; + import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/json-module/referrer-checker.py?name=remoteNoReferrerPolicyUnsafeUrl" with { type: "json"}; + + const originUrl = location.href; + + test(t => { + assert_equals( + referrerSame.referrer, originUrl, + "Referrer URL should be sent for the same-origin top-level script."); + }, "Importing a same-origin top-level script with the unsafe-url referrer policy."); + + test(t => { + assert_equals( + referrerRemote.referrer, originUrl, + "Referrer URL should be sent for the remote-origin top-level script."); + }, "Importing a remote-origin top-level script with the unsafe-url referrer policy."); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js new file mode 100644 index 0000000000..722251b84d --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.js @@ -0,0 +1,65 @@ +// META: global=window,dedicatedworker,sharedworker +// META: script=/common/utils.js + +promise_test(async test => { + await promise_rejects_js(test, TypeError, + import("./module.json"), + "Dynamic import of a JSON module without a type attribute should fail"); + + // This time the import should succeed because we're using the correct + // import even though the previous attempt with the same specifier failed. + const result = await import("./module.json", { with: { type: "json" } }); + assert_true(result.default.test); +}, "Importing a specifier that previously failed due to an incorrect type attribute can succeed if the correct attribute is later given"); + +promise_test(async test => { + // Append a URL fragment to the specifier so that this is independent + // from the previous test. + const result = await import("./module.json#2", { with: { type: "json" } }); + assert_true(result.default.test); + + await promise_rejects_js(test, TypeError, + import("./module.json#2"), + "Dynamic import should fail with the type attribute missing even if the same specifier previously succeeded"); +}, "Importing a specifier that previously succeeded with the correct type attribute should fail if the incorrect attribute is later given"); + +promise_test(async test => { + const uuid_token = token(); + // serve-json-then-js.py gives us JSON the first time + const result_json = await import(`../serve-json-then-js.py?key=${uuid_token}`, { with: { type: "json" } }); + assert_equals(result_json.default.hello, "world"); + + // Import using the same specifier again; this time we get JS, which + // should succeed since we're not asserting a non-JS type this time. + const result_js = await import(`../serve-json-then-js.py?key=${uuid_token}`); + assert_equals(result_js.default, "hello"); +}, "Two modules of different type with the same specifier can load if the server changes its responses"); + +promise_test(async test => { + const uuid_token = token(); + // serve-json-then-js.py gives us JSON the first time + await promise_rejects_js(test, TypeError, + import(`../serve-json-then-js.py?key=${uuid_token}`), + "Dynamic import of JS with a JSON type attribute should fail"); + + // Import using the same specifier/module type pair again; this time we get JS, + // but the import should still fail because the module map entry for this + // specifier/module type pair already contains a failure. + await promise_rejects_js(test, TypeError, + import(`../serve-json-then-js.py?key=${uuid_token}`), + "import should always fail if the same specifier/type attribute pair failed previously"); +}, "An import should always fail if the same specifier/type attribute pair failed previously"); + +promise_test(async test => { + const uuid_token = token(); + // serve-json-then-js.py gives us JSON the first time + const result_json = await import(`../serve-json-then-js.py?key=${uuid_token}`, { with: { type: "json" } }); + assert_equals(result_json.default.hello, "world"); + + // If this were to do another fetch, the import would fail because + // serve-json-then-js.py would give us JS this time. But, the module map + // entry for this specifier/module type pair already exists, so we + // successfully reuse the entry instead of fetching again. + const result_json_2 = await import(`../serve-json-then-js.py?key=${uuid_token}`, { with: { type: "json" } }); + assert_equals(result_json_2.default.hello, "world"); +}, "If an import previously succeeded for a given specifier/type attribute pair, future uses of that pair should yield the same result"); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html new file mode 100644 index 0000000000..c6d7c9a76e --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/script-element-json-src.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title><script> with JSON src</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + window.log = []; + + const test_load = async_test( + "Test that <script> doesn't load when the src is JSON."); + window.addEventListener("load", test_load.step_func_done(ev => { + assert_array_equals(log, ["error"]); + })); +</script> +<script type="module" src="./module.json" onload="t.unreached_func('JSON src should fail to load')" onerror="log.push('error')"></script> diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js new file mode 100644 index 0000000000..cd39c789cb --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker-dynamic-import.js @@ -0,0 +1,5 @@ +onmessage = e => { + e.waitUntil(import("./module.json", { with: { type: "json" } }) + .then(module => e.source.postMessage("LOADED")) + .catch(error => e.source.postMessage("FAILED"))); + };
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js new file mode 100644 index 0000000000..65210fe3e7 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/serviceworker.js @@ -0,0 +1 @@ +import './module.json' with { type: "json" };
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json new file mode 100644 index 0000000000..ace2d72d9d --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/string.json @@ -0,0 +1 @@ +"string" diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json new file mode 100644 index 0000000000..27ba77ddaf --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/true.json @@ -0,0 +1 @@ +true diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json new file mode 100644 index 0000000000..088d982358 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/utf-8.json @@ -0,0 +1,4 @@ +{ + "data": "śćążź", + "comment": "The data above are five Polish letters, similar to scazz. It can be read correctly only with utf-8 encoding." +} diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html new file mode 100644 index 0000000000..3232b84d27 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>JSON modules: Content-Type</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +function check(t, v) { + t.step(() => { + assert_equals(typeof v, "object"); + assert_array_equals(Object.keys(v), ["test"]); + assert_equals(v.test, true); + t.done(); + }); +} +const t1 = async_test("text/json"); +const t2 = async_test("application/json"); +const t3 = async_test("text/html+json"); +const t4 = async_test("image/svg+json"); +const t5 = async_test("text/json;boundary=something"); +const t6 = async_test("text/json;foo=bar"); +</script> +<script type="module" onerror="t1.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json" with { type: "json"}; +check(t1, v); +</script> +<script type="module" onerror="t2.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=application/json" with { type: "json"}; +check(t2, v); +</script> +<script type="module" onerror="t3.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/html%2Bjson" with { type: "json"}; +check(t3, v); +</script> +<script type="module" onerror="t4.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=image/svg%2Bjson" with { type: "json"}; +check(t4, v); +</script> +<script type="module" onerror="t5.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;boundary=something" with { type: "json"}; +check(t5, v); +</script> +<script type="module" onerror="t6.step(() => assert_unreached(event))"> +import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;foo=bar" with { type: "json"}; +check(t6, v); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json new file mode 100644 index 0000000000..490e752ce9 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/json-module/windows-1250.json @@ -0,0 +1,4 @@ +{ + "data": "�湿�", + "comment": "The data above are five Polish letters, similar to scazz. It can be read correctly only with windows1250 encoding." +} |