summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/mozilla/tests/html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/mozilla/tests/html')
-rw-r--r--testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/navigating-across-documents/location-hash.sub.html66
-rw-r--r--testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/read-media/sandboxed-video.html24
-rw-r--r--testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-01.html59
-rw-r--r--testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-02.html41
-rw-r--r--testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-03.html46
-rw-r--r--testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-04.html48
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/form-submission-0/non-usv-filenames.window.js95
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/input-radio-key-navigation.html61
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/textfieldselection/selection-value-interactions.html217
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/input-activation-behavior.html103
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01-notref.html3
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01.html13
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02-notref.html9
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02.html14
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03-ref.html7
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03.html15
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04-ref.html7
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04.html14
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/forms/time-enter-keypress.html48
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-circular.html25
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-error.html25
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module.html25
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-circular.html28
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-error.html25
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module.html21
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/circular-module-import-with-syntax-error.html26
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html25
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/inline-module-order.html40
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/mixed-content-import.https.html27
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/module-error-reporting.html89
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/reload-failed-module-script.html41
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module.js11
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_circular.js5
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_error.js5
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module.js14
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_circular.js3
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_error.js4
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module.js12
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_1.js3
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_2.js5
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_3.js8
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_failure.js6
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/bad_local_export.js3
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error1.js2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error2.js1
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error3.js1
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/empty_module.js0
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/evaluation-order-setup.mjs19
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/import_resolve_failure.js2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/indirect_export_resolve_failure.js2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_import.js2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_indirect_export.js2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import.js1
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import2.js1
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module_eval_error.js3
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/README.md7
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-after-template.html10
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-ncr.html10
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript.html10
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/in-svg-in-cdata-after-gt.html10
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-after-template-ref.html9
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ncr-ref.html9
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ref.html9
-rw-r--r--testing/web-platform/mozilla/tests/html/syntax/charset/references/in-svg-in-cdata-after-gt-ref.html10
65 files changed, 1488 insertions, 0 deletions
diff --git a/testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/navigating-across-documents/location-hash.sub.html b/testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/navigating-across-documents/location-hash.sub.html
new file mode 100644
index 0000000000..7590799e1c
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/navigating-across-documents/location-hash.sub.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+
+setup({ single_test: true });
+
+let CROSS_ORIGIN_HOST = "{{hosts[alt][]}}";
+let sameOriginLocation1;
+let crossOriginLocation;
+let sameOriginLocation2;
+
+// Load first a same origin page to an iframe and store its location, then
+// do the same for a cross origin page and then again for a same origin page.
+// Check whether accessing .hash works and what the value is.
+// Then remove the iframe and check .hash accesses again.
+
+function runTest() {
+ let ifr = document.createElement("iframe");
+ ifr.src = "resources/blank.html";
+ ifr.onload = function() {
+ sameOriginLocation1 = ifr.contentWindow.location;
+ let initialHref = sameOriginLocation1.href;
+ assert_equals(sameOriginLocation1.hash, "");
+ sameOriginLocation1.hash = "1";
+ assert_equals(sameOriginLocation1.hash, "#1");
+ let exceptionConstructor = ifr.contentWindow.DOMException;
+ ifr.onload = function() {
+ crossOriginLocation = ifr.contentWindow.location;
+ assert_throws_dom("SecurityError", () => crossOriginLocation.hash,
+ "Accessing cross origin location.hash should throw");
+ assert_throws_dom("SecurityError", exceptionConstructor, () => sameOriginLocation1.hash,
+ "Accessing cross origin location.hash should throw");
+
+ crossOriginLocation.href = initialHref;
+ ifr.onload = function() {
+ sameOriginLocation2 = ifr.contentWindow.location;
+ assert_not_equals(sameOriginLocation1, sameOriginLocation2);
+ assert_equals(sameOriginLocation1.hash, "");
+ assert_equals(sameOriginLocation2.hash, "");
+ assert_throws_dom("SecurityError", () => crossOriginLocation.hash,
+ "Accessing cross origin location.hash should throw");
+ sameOriginLocation2.hash = "2";
+ assert_equals(sameOriginLocation2.hash, "#2");
+ assert_equals(sameOriginLocation1.hash, "#2");
+
+ ifr.remove();
+ assert_throws_dom("SecurityError", () => crossOriginLocation.hash,
+ "Accessing cross origin location.hash should throw");
+ assert_equals(sameOriginLocation2.hash, "");
+ assert_equals(sameOriginLocation1.hash, "");
+ done();
+ }
+ }
+ sameOriginLocation1.host = CROSS_ORIGIN_HOST;
+ }
+ document.body.appendChild(ifr);
+}
+
+window.onload = function() {
+ setTimeout(runTest);
+}
+
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/read-media/sandboxed-video.html b/testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/read-media/sandboxed-video.html
new file mode 100644
index 0000000000..4c58514e66
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/browsers/browsing-the-web/read-media/sandboxed-video.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Test load of media document in sandboxed iframe</title>
+<link rel="motivation" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1783601">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body></body>
+<script>
+promise_test(async () => {
+ const frame = document.createElement('iframe');
+ frame.sandbox = '';
+ frame.src =
+ // 'PartialContent' ensures that the entire video resource does not load
+ // in one fetch.
+ '/service-workers/service-worker/resources/fetch-access-control.py?'
+ + 'VIDEO&PartialContent';
+
+ document.body.appendChild(frame);
+ await new Promise(resolve => frame.onload = resolve);
+
+ const video = SpecialPowers.wrap(frame).contentDocument.body.childNodes[0];
+ video.muted = true; // to allow playback
+ return video.play();
+});
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-01.html b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-01.html
new file mode 100644
index 0000000000..ed59c3ae99
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-01.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=viewport content=width=device-width>
+<title>Snap to a slider's tick marks by clicking near them</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/rendering.html#the-input-element-as-a-range-control">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1803118">
+<link rel=author href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<input type=range list=tickmarks min=-5 max=35>
+<datalist id=tickmarks>
+ <option value=0></option>
+ <option value=3></option>
+</datalist>
+<script>
+ const range = document.querySelector("input[type=range]");
+ const step = 1;
+ promise_test(async function snapToTickMarks() {
+ const assertions = [[-3, "-3"], [-2, "0"], [1, "0"], [2, "3"], [5, "3"], [6, "6"]];
+ const rect = range.getBoundingClientRect();
+ const padding = 10;
+ const left = rect.left + padding;
+ const width = rect.width - 2 * padding;
+ const actions = new test_driver.Actions();
+ const min = parseInt(range.min);
+ const max = parseInt(range.max);
+ for (const assertion of assertions) {
+ const moveTo = (left + width * (assertion[0] - min) / (max - min)) | 0;
+ const expected = assertion[1];
+ await actions
+ .pointerMove(moveTo, rect.top)
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_equals(range.value, expected);
+ }
+ });
+ promise_test(async function domDoesNotSnap() {
+ const startAt = -2;
+ range.value = startAt;
+ for (let expectedValue = startAt + 1; expectedValue <= 6; expectedValue++) {
+ range.stepUp();
+ assert_equals(parseInt(range.value), expectedValue);
+ }
+ });
+ promise_test(async function keyboardDoesNotSnap() {
+ const kArrowRight = "\uE014";
+ range.focus();
+ const startAt = -2;
+ range.value = startAt;
+ for (let expectedValue = startAt + 1; expectedValue <= 6; expectedValue++) {
+ await test_driver.send_keys(range, kArrowRight);
+ assert_equals(parseInt(range.value), expectedValue);
+ }
+ });
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-02.html b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-02.html
new file mode 100644
index 0000000000..061f34b3a7
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-02.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=viewport content=width=device-width>
+<title>Snap to an RTL slider's tick marks by clicking near them</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/rendering.html#the-input-element-as-a-range-control">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1803118">
+<link rel=author href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<input type=range list=tickmarks min=-5 max=35 dir=rtl>
+<datalist id=tickmarks>
+ <option value=0></option>
+ <option value=3></option>
+</datalist>
+<script>
+ const range = document.querySelector("input[type=range]");
+ const step = 1;
+ promise_test(async function snapToRTLTickMarks() {
+ const assertions = [[-3, "-3"], [-2, "0"], [1, "0"], [2, "3"], [5, "3"], [6, "6"]];
+ const rect = range.getBoundingClientRect();
+ const padding = 10;
+ const right = rect.right - padding;
+ const width = rect.width - 2 * padding;
+ const actions = new test_driver.Actions();
+ const min = parseInt(range.min);
+ const max = parseInt(range.max);
+ for (const assertion of assertions) {
+ const moveTo = (right - width * (assertion[0] - min) / (max - min)) | 0;
+ const expected = assertion[1];
+ await actions
+ .pointerMove(moveTo, rect.top)
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_equals(range.value, expected);
+ }
+ });
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-03.html b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-03.html
new file mode 100644
index 0000000000..9397c39e0a
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-03.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=viewport content=width=device-width>
+<title>Snap to a vertical slider's tick marks by clicking near them</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/rendering.html#the-input-element-as-a-range-control">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1803118">
+<link rel=author href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<style>
+ input[type=range] {
+ writing-mode: vertical-lr;
+ direction: rtl; /* so the range progresses upwards, not downwards */
+ }
+</style>
+<input type=range list=tickmarks min=-5 max=35>
+<datalist id=tickmarks>
+ <option value=0></option>
+ <option value=3></option>
+</datalist>
+<script>
+ const range = document.querySelector("input[type=range]");
+ promise_test(async function snapToVerticalTickMarks() {
+ const assertions = [[-3, "-3"], [-2, "0"], [1, "0"], [2, "3"], [5, "3"], [6, "6"]];
+ const rect = range.getBoundingClientRect();
+ const padding = 10;
+ const bottom = rect.bottom - padding;
+ const height = rect.height - 2 * padding;
+ const actions = new test_driver.Actions();
+ const min = parseInt(range.min);
+ const max = parseInt(range.max);
+ for (const assertion of assertions) {
+ const moveTo = (bottom - height * (assertion[0] - min) / (max - min)) | 0;
+ const expected = assertion[1];
+ await actions
+ .pointerMove(rect.left, moveTo)
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_equals(range.value, expected);
+ }
+ });
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-04.html b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-04.html
new file mode 100644
index 0000000000..b6d32a82c4
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/rendering/non-replaced-elements/form-controls/range-snap-to-tick-marks-04.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name=viewport content=width=device-width>
+<title>Snap to a vertical slider's tick marks by clicking near them</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/rendering.html#the-input-element-as-a-range-control">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1803118">
+<link rel=author href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<style>
+ input[type=range] {
+ writing-mode: vertical-lr;
+ }
+</style>
+<input type=range list=tickmarks min=-5 max=35>
+<datalist id=tickmarks>
+ <option value=0></option>
+ <option value=3></option>
+</datalist>
+<script>
+ const range = document.querySelector("input[type=range]");
+ promise_test(async function snapToVerticalTickMarks() {
+ // Same assertions as range-snap-to-tick-marks-03, but without direction:rtl the range
+ // will progress downwards instead of upwards, so the coord calculation is reversed
+ // in the y-direction.
+ const assertions = [[-3, "-3"], [-2, "0"], [1, "0"], [2, "3"], [5, "3"], [6, "6"]];
+ const rect = range.getBoundingClientRect();
+ const padding = 10;
+ const top = rect.top + padding;
+ const height = rect.height - 2 * padding;
+ const actions = new test_driver.Actions();
+ const min = parseInt(range.min);
+ const max = parseInt(range.max);
+ for (const assertion of assertions) {
+ const moveTo = (top + height * (assertion[0] - min) / (max - min)) | 0;
+ const expected = assertion[1];
+ await actions
+ .pointerMove(rect.left, moveTo)
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_equals(range.value, expected);
+ }
+ });
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/form-submission-0/non-usv-filenames.window.js b/testing/web-platform/mozilla/tests/html/semantics/forms/form-submission-0/non-usv-filenames.window.js
new file mode 100644
index 0000000000..9b5aa88abb
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/form-submission-0/non-usv-filenames.window.js
@@ -0,0 +1,95 @@
+// META: script=/html/semantics/forms/form-submission-0/enctypes-helper.js
+
+// This test is built on the same infrastructure as the WPT tests
+// urlencoded2.window.js, multipart-formdata.window.js and text-plain.window.js,
+// except modified because this file only tests the serialization of filenames.
+// See the enctypes-helper.js file in the regular WPT test suite for more info.
+
+// The `urlencoded`, `multipart` and `textPlain` functions take a `file`
+// property rather than `name` and `value` properties, and the value of
+// `expected` is the serialization of the filename in the given encoding.
+
+function formSubmissionTemplate2(enctype, expectedBuilder) {
+ const formTestFn = formSubmissionTemplate(enctype, expectedBuilder);
+ return ({ file, formEncoding, expected, description }) =>
+ formTestFn({ name: "a", value: file, formEncoding, expected, description });
+}
+
+const urlencoded = formSubmissionTemplate2(
+ "application/x-www-form-urlencoded",
+ filename => `a=${filename}`
+);
+const multipart = formSubmissionTemplate2(
+ "multipart/form-data",
+ (filename, serialized) => {
+ const boundary = serialized.split("\r\n")[0];
+ return [
+ boundary,
+ `Content-Disposition: form-data; name="a"; filename="${filename}"`,
+ "Content-Type: text/plain",
+ "",
+ "", // File contents
+ `${boundary}--`,
+ "",
+ ].join("\r\n");
+ }
+);
+const textPlain = formSubmissionTemplate2(
+ "text/plain",
+ filename => `a=${filename}\r\n`
+);
+
+// -----------------------------------------------------------------------------
+
+(async () => {
+ // This creates an empty filesystem file with an arbitrary name and returns it
+ // as a File object with name "a\uD800b".
+ const file = SpecialPowers.unwrap(
+ await SpecialPowers.createFiles(
+ [{ data: "", options: { name: "a\uD800b", type: "text/plain" } }],
+ files => files[0]
+ )
+ );
+
+ urlencoded({
+ file,
+ formEncoding: "UTF-8",
+ expected: "a%EF%BF%BDb",
+ description: "lone surrogate in filename, UTF-8",
+ });
+
+ urlencoded({
+ file,
+ formEncoding: "windows-1252",
+ expected: "a%26%2365533%3Bb",
+ description: "lone surrogate in filename, windows-1252",
+ });
+
+ multipart({
+ file,
+ formEncoding: "UTF-8",
+ expected: "a\xEF\xBF\xBDb",
+ description: "lone surrogate in filename, UTF-8",
+ });
+
+ multipart({
+ file,
+ formEncoding: "windows-1252",
+ expected: "a&#65533;b",
+ description: "lone surrogate in filename, windows-1252",
+ });
+
+ textPlain({
+ file,
+ formEncoding: "UTF-8",
+ expected: "a\xEF\xBF\xBDb",
+ description: "lone surrogate in filename, UTF-8",
+ });
+
+ textPlain({
+ file,
+ formEncoding: "windows-1252",
+ expected: "a&#65533;b",
+ description: "lone surrogate in filename, windows-1252",
+ });
+})();
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/input-radio-key-navigation.html b/testing/web-platform/mozilla/tests/html/semantics/forms/input-radio-key-navigation.html
new file mode 100644
index 0000000000..2eee99ffaf
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/input-radio-key-navigation.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<title>Keyboard navigation on input type=radio</title>
+<meta charset=utf-8>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Ãlvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+
+<form dir="ltr">
+ <input type=radio name=whatever value=1>
+ <input type=radio name=whatever value=2>
+ <input type=radio name=whatever value=3>
+</form>
+<form dir="rtl">
+ <input type=radio name=whatever value=1>
+ <input type=radio name=whatever value=2>
+ <input type=radio name=whatever value=3>
+</form>
+<script>
+const KEYS = {
+ ArrowLeft: '\uE012',
+ ArrowUp: '\uE013',
+ ArrowRight: '\uE014',
+ ArrowDown: '\uE015',
+};
+
+function nextFocusIndex(currentIndex, length, forward) {
+ if (forward) {
+ return (currentIndex + 1) % length;
+ }
+ return (currentIndex == 0 ? length : currentIndex) - 1;
+}
+
+async function testMove(form, keyName, forward) {
+ let radios = form.querySelectorAll("input[type=radio]");
+ assert_equals(radios.length, 3, "Sanity check");
+
+ let focusIndex = 1;
+ radios[focusIndex].focus();
+
+ // Enough to wrap around, and one more to test the last active element too.
+ for (let i = 0; i <= radios.length; ++i) {
+ assert_equals(document.activeElement, radios[focusIndex], `Focused expected radio input (${focusIndex})`);
+ await test_driver.send_keys(document.activeElement, KEYS[keyName]);
+ focusIndex = nextFocusIndex(focusIndex, radios.length, forward);
+ }
+}
+
+promise_test(async t => {
+ for (let form of document.querySelectorAll("form")) {
+ const rtl = form.dir == "rtl";
+ await testMove(form, "ArrowDown", /* forward = */ true);
+ await testMove(form, "ArrowUp", /* forward = */ false);
+ await testMove(form, "ArrowLeft", /* forward = */ rtl);
+ await testMove(form, "ArrowRight", /* forward = */ !rtl);
+ }
+});
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/textfieldselection/selection-value-interactions.html b/testing/web-platform/mozilla/tests/html/semantics/forms/textfieldselection/selection-value-interactions.html
new file mode 100644
index 0000000000..c6ba07f746
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/textfieldselection/selection-value-interactions.html
@@ -0,0 +1,217 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<div id=target></div>
+<script>
+ var target = document.getElementById("target");
+ var sometext = "something";
+ var shorttext = "abc";
+ var elemData = [
+ {
+ desc: "textarea not in body",
+ factory: () => document.createElement("textarea"),
+ },
+ {
+ desc: "input not in body",
+ factory: () => document.createElement("input"),
+ },
+ {
+ desc: "textarea in body",
+ factory: () => document.body.appendChild(document.createElement("textarea")),
+ },
+ {
+ desc: "input in body",
+ factory: () => document.body.appendChild(document.createElement("input")),
+ },
+ {
+ desc: "textarea in body with parsed default value",
+ factory: () => {
+ target.innerHTML = "<textarea>abcdefghij</textarea>"
+ return target.querySelector("textarea");
+ },
+ },
+ {
+ desc: "input in body with parsed default value",
+ factory: () => {
+ target.innerHTML = "<input value='abcdefghij'>"
+ return target.querySelector("input");
+ },
+ },
+ {
+ desc: "focused textarea",
+ factory: () => {
+ var t = document.body.appendChild(document.createElement("textarea"));
+ t.focus();
+ return t;
+ },
+ },
+ {
+ desc: "focused input",
+ factory: () => {
+ var i = document.body.appendChild(document.createElement("input"));
+ i.focus();
+ return i;
+ },
+ },
+ {
+ desc: "focused then blurred textarea",
+ factory: () => {
+ var t = document.body.appendChild(document.createElement("textarea"));
+ t.focus();
+ t.blur();
+ return t;
+ },
+ },
+ {
+ desc: "focused then blurred input",
+ factory: () => {
+ var i = document.body.appendChild(document.createElement("input"));
+ i.focus();
+ i.blur()
+ return i;
+ },
+ },
+ ];
+
+for (var data of elemData) {
+ test(function() {
+ var el = data.factory();
+ this.add_cleanup(() => el.remove());
+ assert_equals(el.selectionStart, 0,
+ `Cursor start should be at beginning of ${data.desc}`);
+ assert_equals(el.selectionEnd, 0,
+ `Cursor end should be at beginning of ${data.desc}`);
+ }, `cursor location for initial value of ${data.desc}`);
+}
+
+for (var data of elemData) {
+ test(function() {
+ var el = data.factory();
+ this.add_cleanup(() => el.remove());
+ el.defaultValue = sometext;
+ // The "focused or has been focused" case behaves differently.
+ if (data.desc.includes("focused")) {
+ assert_equals(el.selectionStart, el.value.length,
+ `Cursor start should be at end of ${data.desc}`);
+ assert_equals(el.selectionEnd, el.value.length,
+ `Cursor end should be at end of ${data.desc}`);
+ } else {
+ assert_equals(el.selectionStart, 0,
+ `Cursor start should be at beginning of ${data.desc}`);
+ assert_equals(el.selectionEnd, 0,
+ `Cursor end should be at beginning of ${data.desc}`);
+ }
+ }, `cursor location after defaultValue set of ${data.desc}`);
+}
+
+for (var data of elemData) {
+ test(function() {
+ var el = data.factory();
+ this.add_cleanup(() => el.remove());
+ el.selectionStart = el.selectionStart;
+ el.defaultValue = sometext;
+ // The focused case behaves differently.
+ if (data.desc.includes("focused")) {
+ assert_equals(el.selectionStart, el.value.length,
+ `Cursor start should be at end of ${data.desc}`);
+ assert_equals(el.selectionEnd, el.value.length,
+ `Cursor end should be at end of ${data.desc}`);
+ } else {
+ assert_equals(el.selectionStart, 0,
+ `Cursor start should be at beginning of ${data.desc}`);
+ assert_equals(el.selectionEnd, 0,
+ `Cursor end should be at beginning of ${data.desc}`);
+ }
+ }, `cursor location after defaultValue set after no-op selectionStart set of ${data.desc}`);
+}
+
+for (var data of elemData) {
+ test(function() {
+ var el = data.factory();
+ this.add_cleanup(() => el.remove());
+ el.value = sometext;
+ assert_equals(el.selectionStart, sometext.length,
+ `Cursor start should be at end of ${data.desc}`);
+ assert_equals(el.selectionEnd, sometext.length,
+ `Cursor end should be at end of ${data.desc}`);
+ }, `cursor location after value set of ${data.desc}`);
+}
+
+for (var data of elemData) {
+ test(function() {
+ var el = data.factory();
+ this.add_cleanup(() => el.remove());
+ assert_true(sometext.length > 8,
+ "sometext too short, test won't work right");
+ el.defaultValue = sometext;
+ el.selectionStart = 1;
+ el.selectionEnd = 8;
+ assert_equals(el.selectionStart, 1, "We just set selectionStart!");
+ assert_equals(el.selectionEnd, 8, "We just set selectionEnd!");
+ assert_true(shorttext.length > 1,
+ "shorttext too short, test won't work right");
+ assert_true(shorttext.length < 8,
+ "shorttext too long, test won't work right");
+ el.defaultValue = shorttext;
+ // The "focused or has been focused" case behaves differently.
+ if (data.desc.includes("focused")) {
+ assert_equals(el.selectionStart, el.value.length,
+ `Cursor start should be at end of ${data.desc}`);
+ assert_equals(el.selectionEnd, el.value.length,
+ `Cursor end should be at end of ${data.desc}`);
+ } else {
+ if (el.tagName.toLowerCase() === "textarea") {
+ assert_equals(el.selectionStart, 0,
+ "Selection should be collapsed to the beginning");
+ assert_equals(el.selectionEnd, 0,
+ "Selection should be collapsed to the beginning");
+ } else {
+ assert_equals(el.selectionStart, 1,
+ "Shouldn't have moved selection start");
+ assert_equals(el.selectionEnd, shorttext.length,
+ "Should have adjusted selection end");
+ }
+ }
+ }, `selection location after defaultValue set to shorter than selectionEnd of ${data.desc}`);
+}
+
+for (var data of elemData) {
+ test(function() {
+ var el = data.factory();
+ this.add_cleanup(() => el.remove());
+ assert_true(sometext.length > 8,
+ "sometext too short, test won't work right");
+ el.defaultValue = sometext;
+ el.selectionStart = 5;
+ el.selectionEnd = 8;
+ assert_equals(el.selectionStart, 5, "We just set selectionStart!");
+ assert_equals(el.selectionEnd, 8, "We just set selectionEnd!");
+ assert_true(shorttext.length < 5,
+ "shorttext too long, test won't work right");
+ el.defaultValue = shorttext;
+ // The "focused or has been focused" case behaves differently.
+ if (data.desc.includes("focused")) {
+ assert_equals(el.selectionStart, el.value.length,
+ `Cursor start should be at end of ${data.desc}`);
+ assert_equals(el.selectionEnd, el.value.length,
+ `Cursor end should be at end of ${data.desc}`);
+ } else {
+ if (el.tagName.toLowerCase() === "textarea") {
+ assert_equals(el.selectionStart,0,
+ "Selection should be collapsed to the beginning");
+ assert_equals(el.selectionEnd, 0,
+ "Selection should be collapsed to the beginning");
+ } else {
+ assert_equals(el.selectionStart, shorttext.length,
+ "Should have adjusted selection start");
+ assert_equals(el.selectionEnd, shorttext.length,
+ "Should have adjusted selection end");
+ }
+ }
+ }, `selection location after defaultValue set to shorter than selectionStart of ${data.desc}`);
+}
+
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/input-activation-behavior.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/input-activation-behavior.html
new file mode 100644
index 0000000000..d0ff8fd666
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/input-activation-behavior.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Activation behavior of input</title>
+<link rel="help" href="https://dom.spec.whatwg.org/#eventtarget-activation-behavior">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
+<link rel="help" href="https://html.spec.whatwg.org/#the-input-element">
+<link rel="help" href="https://github.com/whatwg/html/issues/1568">
+<link rel="help" href="https://github.com/whatwg/html/issues/1576">
+<link rel="help" href="https://github.com/whatwg/html/issues/10032">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+
+<div id=test_container>
+ <a href="javascript:activated(document.querySelector('a'))" class="target"></a>
+ <area href="javascript:activated(document.querySelector('area'))" class="target">
+</div>
+
+<script>
+let activations = [];
+function activated(e) {
+ activations.push(e);
+}
+
+function testActivation(inputType, hasFormOwner, followTheParentLink) {
+ const elements = document.getElementsByClassName("target");
+ for (const anchor of elements) {
+ promise_test(async t => {
+ const input = document.createElement("input");
+ input.type = inputType;
+ input.oninput = function (e) {
+ activated(this);
+ };
+
+ if (hasFormOwner) {
+ const form = document.createElement("form");
+ form.onsubmit = function (e) {
+ activated(this.firstElementChild);
+ e.preventDefault();
+ return false;
+ };
+ form.onreset = function (e) {
+ activated(this.firstElementChild);
+ };
+ form.appendChild(input);
+ anchor.appendChild(form);
+ t.add_cleanup(function() {
+ form.remove();
+ activations = [];
+ });
+ } else {
+ anchor.appendChild(input);
+ t.add_cleanup(function() {
+ input.remove();
+ activations = [];
+ });
+ }
+
+ input.click();
+
+ // This is for a/area where JavaScript is executed in a queued task.
+ await new Promise(resolve => {
+ t.step_timeout(() => {
+ t.step_timeout(() => {
+ // All browser doesn't follow the spec for input button, see
+ // https://github.com/whatwg/html/issues/1576.
+ assert_array_equals(activations, [followTheParentLink ? anchor : input]);
+ if (inputType == "checkbox" || inputType == "radio") {
+ assert_equals(input.checked, true, "check input.checked");
+ }
+ resolve();
+ }, 0);
+ }, 0);
+ });
+ }, `Click child input ${inputType} ${hasFormOwner ? "with" : "without"} form owner ` +
+ `of parent ${anchor.tagName}, activation target should be ${followTheParentLink ? anchor.tagName : "input"}`);
+ }
+}
+
+// Click input types without form owner should not follow the parent link.
+const TypesWithoutFormOwnerNotFollowParentLink = ["checkbox", "radio"];
+for (const type of TypesWithoutFormOwnerNotFollowParentLink) {
+ testActivation(type, false /* hasFormOwner */, false /* followTheParentLink */);
+}
+
+// Click input types without form owner should follow the parent link.
+const TypesWithoutFormOwnerFollowParentLink = ["button", "reset", "submit"];
+for (const type of TypesWithoutFormOwnerFollowParentLink) {
+ testActivation(type, false /* hasFormOwner */, true /* followTheParentLink */);
+}
+
+// Click input types with form owner should not follow the parent link.
+const TypesWithFormOwnerNotFollowParentLink = ["submit", "reset", "checkbox", "radio"];
+for (const type of TypesWithFormOwnerNotFollowParentLink) {
+ testActivation(type, true /* hasFormOwner */, false /* followTheParentLink */);
+}
+
+// Click input types with form owner should follow the parent link.
+const TypesWithFormOwnerFollowParentLink = ["button"];
+for (const type of TypesWithFormOwnerFollowParentLink) {
+ testActivation(type, true /* hasFormOwner */, true /* followTheParentLink */);
+}
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01-notref.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01-notref.html
new file mode 100644
index 0000000000..67591468cf
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01-notref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>vertical range input with datalist reference</title>
+<input type="range" orient="vertical" min="-100" max="100" value="0" step="10" name="power" list="powers">
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01.html
new file mode 100644
index 0000000000..f1bd96f391
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-01.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>vertical range input with datalist</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841942">
+<link rel="author" href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<link rel="mismatch" href="range-tick-marks-01-notref.html">
+<input type="range" orient="vertical" min="-100" max="100" value="0" step="10" name="power" list="powers">
+<datalist id="powers">
+ <option value="0">
+ <option value="-30">
+ <option value="30">
+ <option value="50">
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02-notref.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02-notref.html
new file mode 100644
index 0000000000..59acde1482
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02-notref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>max and min attributes applied to vertical range input with datalist reference</title>
+<input type="range" orient="vertical" min="-100" max="100" value="0" step="10" name="power" list="powers">
+<datalist id="powers">
+ <option value="0">
+ <option value="-30">
+ <option value="30">
+ <option value="50">
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02.html
new file mode 100644
index 0000000000..bd45631d4a
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-02.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>max and min attributes applied to vertical range input with datalist</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/input.html#the-min-and-max-attributes">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841942">
+<link rel="author" href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<link rel="mismatch" href="range-tick-marks-02-notref.html">
+<input type="range" orient="vertical" min="-40" max="40" value="0" step="10" name="power" list="powers">
+<datalist id="powers">
+ <option value="0">
+ <option value="-30">
+ <option value="30">
+ <option value="50">
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03-ref.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03-ref.html
new file mode 100644
index 0000000000..df473920ec
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>no vertical range tick marks for disabled datalist elements reference</title>
+<input type="range" orient="vertical" min="-100" max="100" value="0" step="10" name="power" list="powers">
+<datalist id="powers">
+ <option value="-30">
+ <option value="50">
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03.html
new file mode 100644
index 0000000000..83b5c2eb66
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-03.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>no vertical range tick marks for disabled datalist elements</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/form-elements.html#htmldatalistelement">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/form-elements.html#concept-option-disabled">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=841942">
+<link rel="author" href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<link rel="match" href="range-tick-marks-03-ref.html">
+<input type="range" orient="vertical" min="-100" max="100" value="0" step="10" name="power" list="powers">
+<datalist id="powers">
+ <option value="0" disabled>
+ <option value="-30">
+ <option value="30" disabled>
+ <option value="50">
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04-ref.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04-ref.html
new file mode 100644
index 0000000000..c2bf59e52b
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>no range tick marks for vertical range tick marks that are step mismatches reference</title>
+<input type=range step=3 value=1 min=-5 max=5 list=degrees>
+<datalist id=degrees>
+ <option value=-2>
+ <option value=4>
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04.html b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04.html
new file mode 100644
index 0000000000..a47334b411
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/the-input-element/range-tick-marks-04.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>no range tick marks for vertical range tick marks that are step mismatches</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1803303">
+<link rel=author href="mailto:zach@zrhoffman.net" title="Zach Hoffman">
+<link rel=match href=range-tick-marks-04-ref.html>
+<input type=range step=3 value=1 min=-5 max=5 list=degrees>
+<datalist id=degrees>
+ <option value=-4>
+ <option value=-2>
+ <option value=0>
+ <option value=2>
+ <option value=4>
+</datalist>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/forms/time-enter-keypress.html b/testing/web-platform/mozilla/tests/html/semantics/forms/time-enter-keypress.html
new file mode 100644
index 0000000000..2ffeb22cb4
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/forms/time-enter-keypress.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<title>Enter submits on time input</title>
+<meta charset=utf-8>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Ãlvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<form>
+ <input type="time" name="time">
+ <input type=submit>
+</form>
+<form>
+ <input type="date" name="date">
+ <input type=submit>
+</form>
+<form>
+ <input type="datetime-local" name="datetime-local">
+ <input type=submit>
+</form>
+<script>
+async function testEnterOnInput(form) {
+ const submitted = new Promise(resolve => {
+ form.addEventListener("submit", function(e) {
+ e.preventDefault();
+ resolve();
+ }, { once: true });
+ });
+ const input = form.querySelector("input");
+ input.focus();
+
+ const ENTER = "\uE007";
+ await new test_driver.Actions()
+ .keyDown(ENTER)
+ .keyUp(ENTER)
+ .send()
+ await submitted;
+ assert_true(true, "Form was submitted on enter for input " + input.type);
+}
+
+promise_test(async t => {
+ for (let form of document.querySelectorAll("form")) {
+ await testEnterOnInput(form, t);
+ }
+});
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-circular.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-circular.html
new file mode 100644
index 0000000000..c99893a786
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-circular.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load dynamically imported async modules circular</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load async dynamic module")
+ window.addEventListener("error", scriptError);
+ function scriptError(e) {
+ // An error is expected
+ test.step(() => assert_true(e.message !== "FAIL"));
+ }
+ function scriptLoaded() {
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/async_dynamic_module_circular.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-error.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-error.html
new file mode 100644
index 0000000000..ff2ac06222
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module-error.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load dynamically imported async modules which errors</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load dynamically imported async modules with error")
+ window.addEventListener("error", scriptError);
+ function scriptError(e) {
+ // An error is expected
+ test.step(() => assert_true(e.message !== "FAIL"));
+ }
+ function scriptLoaded() {
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/async_dynamic_module_error.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module.html
new file mode 100644
index 0000000000..2e1b267492
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-dynamic-module.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load dynamically imported async modules</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load async dynamic module")
+ window.addEventListener("error", scriptError);
+ function scriptError(e) {
+ // An error is expected
+ test.step(() => assert_true(e.message !== "FAIL"));
+ }
+ function scriptLoaded() {
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/async_dynamic_module.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-circular.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-circular.html
new file mode 100644
index 0000000000..7540ebb5ec
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-circular.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load async modules circular</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load async module")
+ window.addEventListener("error", scriptError);
+ function scriptError(e) {
+ // An error is expected
+ test.step(() => assert_true(e.message !== "FAIL"));
+ test.done();
+ }
+ function scriptLoaded() {
+ test.step(() => assert_unreached("Should not load before error"));
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/async_module_circular.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()">
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-error.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-error.html
new file mode 100644
index 0000000000..c720611080
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module-error.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load an async module</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load dynamic async module with syntax error")
+ window.addEventListener("error", scriptError);
+ function scriptError(e) {
+ // An error is expected
+ test.step(() => assert_true(e.message !== "FAIL"));
+ }
+ function scriptLoaded() {
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/async_module_error.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module.html
new file mode 100644
index 0000000000..566e2a379d
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/async-module.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load dynamically imported async modules</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load async dynamic module")
+ function scriptLoaded() {
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/async_module.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()">
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/circular-module-import-with-syntax-error.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/circular-module-import-with-syntax-error.html
new file mode 100644
index 0000000000..e472656e34
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/circular-module-import-with-syntax-error.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load a module with circular imports and syntax error</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Load module with circular imports and syntax error")
+ window.addEventListener("error", scriptError);
+ function scriptError() {
+ // An error is expected
+ test.done();
+ }
+ function scriptLoaded() {
+ test.step(() => assert_unreached("Should not load"));
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ src="./support/circular_error1.js"
+ onerror="testNoError()"
+ onload="scriptLoaded()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html
new file mode 100644
index 0000000000..44337a0217
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Insert non-async module script</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var test = async_test("Create module script")
+ var moduleRan = false;
+ function loadModule() {
+ var script = document.createElement("script");
+ script.onerror = function() {
+ test.step(() => assert_unreached("Should not get an error"));
+ test.done();
+ };
+ script.onload = function() {
+ test.step(() => assert_equals(moduleRan, true));
+ test.done();
+ };
+ script.type = "module";
+ script.src = "support/module.js";
+ script.async = false;
+ document.documentElement.appendChild(script);
+ }
+</script>
+<body onload='loadModule()'></body>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/inline-module-order.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/inline-module-order.html
new file mode 100644
index 0000000000..3df7624187
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/inline-module-order.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Execution order of non-parser created inline module scripts</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<!-- Ensure imported module is already in the module map -->
+<script type="module" src="./support/empty_module.js"></script>
+
+<div id="parent"></div>
+
+<script>
+ let result = [];
+
+ function createInlineModuleScript(source) {
+ let parent = document.getElementById("parent");
+ let script = document.createElement("script");
+ script.type = "module";
+ script.textContent = source;
+ parent.appendChild(script);
+ }
+
+ promise_test(async test => {
+ await new Promise(resolve => window.onload = resolve);
+
+ createInlineModuleScript(`
+ import {} from "./support/empty_module.js";
+ result.push(1);
+ `);
+
+ createInlineModuleScript(`
+ result.push(2);
+ `);
+
+ await test.step_wait(() => result.length == 2, "Wait for both scripts to be executed", 1000);
+ test.step(() => assert_array_equals(result, [2, 1],
+ "Check expected execution order"));
+ test.done();
+ }, "Execution order of non-parser created inline module scripts");
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/mixed-content-import.https.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/mixed-content-import.https.html
new file mode 100644
index 0000000000..5342bd525c
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/mixed-content-import.https.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Attempt to load a mixed content module graph</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+ var test = async_test("Attempt to load a mixed content module graph")
+ window.addEventListener("error", testNoError);
+ function scriptError() {
+ // An error is expected
+ test.done();
+ }
+ function scriptLoaded() {
+ test.step(() => assert_unreached("Should not load"));
+ test.done();
+ }
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+</script>
+<script type="module"
+ onerror="scriptError()"
+ onload="scriptLoaded()"
+ src="./support/mixed_import.js">
+</script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/module-error-reporting.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/module-error-reporting.html
new file mode 100644
index 0000000000..5d059b898a
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/module-error-reporting.html
@@ -0,0 +1,89 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Insert non-async module script</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ const test = async_test("Test error event properties");
+
+ let errorCount = 0;
+ let eventCount = 0;
+ window.addEventListener("error", handleError);
+ window.addEventListener("load", handleLoaded);
+
+ function handleEvent(event) {
+ eventCount++;
+ test.step(() => assert_equals(typeof event, "object"));
+ test.step(() => assert_true(event instanceof Event));
+ }
+
+ function handleError(event) {
+ errorCount++;
+ test.step(() => assert_equals(typeof event, "object"));
+ test.step(() => assert_true(event instanceof ErrorEvent));
+ switch (errorCount) {
+ case 1:
+ test.step(() => assert_true(event.error instanceof SyntaxError));
+ test.step(() => assert_true(event.filename.endsWith("/bad_local_export.js")));
+ test.step(() => assert_equals(event.lineno, 3));
+ test.step(() => assert_equals(event.colno, 8));
+ break;
+ case 2:
+ test.step(() => assert_true(event.error instanceof TypeError));
+ test.step(() => assert_true(event.filename.endsWith("/import_resolve_failure.js")));
+ test.step(() => assert_equals(event.lineno, 2));
+ test.step(() => assert_equals(event.colno, 17));
+ break;
+ case 3:
+ test.step(() => assert_true(event.error instanceof TypeError));
+ test.step(() => assert_true(event.filename.endsWith("/indirect_export_resolve_failure.js")));
+ test.step(() => assert_equals(event.lineno, 2));
+ test.step(() => assert_equals(event.colno, 20));
+ break;
+ case 4:
+ test.step(() => assert_true(event.error instanceof SyntaxError));
+ test.step(() => assert_true(event.filename.endsWith("/missing_import.js")));
+ test.step(() => assert_equals(event.lineno, 2));
+ test.step(() => assert_equals(event.colno, 9));
+ break;
+ case 5:
+ test.step(() => assert_true(event.error instanceof SyntaxError));
+ test.step(() => assert_true(event.filename.endsWith("/missing_indirect_export.js")));
+ test.step(() => assert_equals(event.lineno, 2));
+ test.step(() => assert_equals(event.colno, 12));
+ break;
+ case 6:
+ test.step(() => assert_true(event.error instanceof SyntaxError));
+ test.step(() => assert_true(event.filename.endsWith("/module_eval_error.js")));
+ test.step(() => assert_equals(event.lineno, 3));
+ test.step(() => assert_equals(event.colno, 1));
+ break;
+ }
+ }
+
+ function testNoError() {
+ test.step(() => assert_unreached("No event expected here"));
+ test.done();
+ }
+
+ function handleLoaded() {
+ test.step(() => assert_equals(eventCount, 2));
+ test.step(() => assert_equals(errorCount, 6));
+ test.done();
+ }
+
+</script>
+
+<!-- Errors that fire an event on the script element -->
+<script type="module" src="" onerror="handleEvent(event)"></script>
+<script type="module" src="./does_not_exist" onerror="handleEvent(event)"></script>
+
+<!-- Errors that fire an error event on the global -->
+<script type="module" src="./support/bad_local_export.js" onerror="handleEvent(event)"></script>
+<script type="module" src="./support/import_resolve_failure.js" onerror="testNoError()"></script>
+<script type="module" src="./support/indirect_export_resolve_failure.js" onerror="testNoError()"></script>
+<script type="module" src="./support/missing_import.js" onerror="testNoError()"></script>
+<script type="module" src="./support/missing_indirect_export.js" --onerror="testNoError()"></script>
+<script type="module" src="./support/module_eval_error.js" onerror="testNoError()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/reload-failed-module-script.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/reload-failed-module-script.html
new file mode 100644
index 0000000000..b95d3fe330
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/reload-failed-module-script.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Insert non-async module script</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ setup({allow_uncaught_exception: true});
+
+ var test = async_test("Reload failed module script");
+
+ var errorCount = 0;
+ window.addEventListener("error", handleError);
+
+ function handleError() {
+ errorCount++;
+
+ if (errorCount == 1) {
+ reloadModule();
+ return;
+ }
+
+ test.step(() => assert_equals(errorCount, 2));
+ test.done();
+ }
+
+ function reloadModule() {
+ var script = document.createElement("script");
+ script.onerror = testNoError;
+ script.type = "module";
+ script.src = "support/missing_import.js";
+ script.async = false;
+ document.documentElement.appendChild(script);
+ }
+
+ function testNoError() {
+ test.step(() => assert_unreached("No event expect here"));
+ test.done();
+ }
+
+</script>
+<script type="module" src="support/missing_import.js" onerror="testNoError()"></script>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module.js
new file mode 100644
index 0000000000..238dc11402
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module.js
@@ -0,0 +1,11 @@
+var ns = await import('./async_test_module.js');
+if (ns.default !== 42) {
+ throw new Error("FAIL");
+}
+if (ns.x !== "named") {
+ throw new Error("FAIL");
+}
+if (ns.y !== 39) {
+ throw new Error("FAIL");
+}
+
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_circular.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_circular.js
new file mode 100644
index 0000000000..93bfc3aca8
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_circular.js
@@ -0,0 +1,5 @@
+try {
+ var ns = await import('./async_test_module_circular_1.js');
+} catch(ns) {
+ throw Error("Fails as expected");
+};
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_error.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_error.js
new file mode 100644
index 0000000000..3832960108
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_dynamic_module_error.js
@@ -0,0 +1,5 @@
+try {
+ await import('./bad_local_export.js');
+} catch(ns) {
+ throw Error("Fails as expected");
+};
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module.js
new file mode 100644
index 0000000000..34a590bcfc
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module.js
@@ -0,0 +1,14 @@
+import nsPromise from './async_test_module.js';
+
+console.log("hi");
+let ns = await nsPromise;
+
+if (ns.default !== 42) {
+ throw new Error("FAIL");
+}
+if (ns.x !== "named") {
+ throw new Error("FAIL");
+}
+if (ns.y !== 39) {
+ throw new Error("FAIL");
+}
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_circular.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_circular.js
new file mode 100644
index 0000000000..a9dff71b17
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_circular.js
@@ -0,0 +1,3 @@
+import module from './async_test_module_circular_1.js';
+
+throw new Error("FAIL");
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_error.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_error.js
new file mode 100644
index 0000000000..3fa6991768
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_module_error.js
@@ -0,0 +1,4 @@
+import ns from "./async_test_module_failure.js";
+
+throw Error("FAIL");
+
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module.js
new file mode 100644
index 0000000000..201c76eedf
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module.js
@@ -0,0 +1,12 @@
+await 1;
+await 2;
+export default await Promise.resolve(42);
+
+export const y = await 39;
+export const x = await 'named';
+
+// Bonus: this rejection is not unwrapped
+if (false) {
+ await Promise.reject(42);
+}
+
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_1.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_1.js
new file mode 100644
index 0000000000..2fdf67baca
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_1.js
@@ -0,0 +1,3 @@
+import module from './async_test_module_circular_2.js';
+
+export default {};
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_2.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_2.js
new file mode 100644
index 0000000000..0a09aacc39
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_2.js
@@ -0,0 +1,5 @@
+import module from './async_test_module_circular_3.js';
+
+await module.test();
+
+export default {};
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_3.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_3.js
new file mode 100644
index 0000000000..d815bc00e4
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_circular_3.js
@@ -0,0 +1,8 @@
+import module from './async_test_module_circular_1.js';
+
+export default {
+ async test() {
+ throw new Error("error thrown");
+ return Promise.resolve()
+ }
+};
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_failure.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_failure.js
new file mode 100644
index 0000000000..6f823f3003
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/async_test_module_failure.js
@@ -0,0 +1,6 @@
+export default 42;
+
+export const named = 'named';
+
+var rejection = Promise.reject(TypeError('I reject this!'));
+await rejection;
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/bad_local_export.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/bad_local_export.js
new file mode 100644
index 0000000000..0b3df8de32
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/bad_local_export.js
@@ -0,0 +1,3 @@
+// Attempt to export something that doesn't exist.
+
+export missing;
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error1.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error1.js
new file mode 100644
index 0000000000..f0310fe0b1
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error1.js
@@ -0,0 +1,2 @@
+import { test2 } from "./circular_error2.js";
+import "./circular_error3.js";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error2.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error2.js
new file mode 100644
index 0000000000..5b163eab93
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error2.js
@@ -0,0 +1 @@
+import "./circular_error3.js";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error3.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error3.js
new file mode 100644
index 0000000000..2589defac8
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/circular_error3.js
@@ -0,0 +1 @@
+import "./circular_error1.js";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/empty_module.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/empty_module.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/empty_module.js
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/evaluation-order-setup.mjs b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/evaluation-order-setup.mjs
new file mode 100644
index 0000000000..d3f22e9ee0
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/evaluation-order-setup.mjs
@@ -0,0 +1,19 @@
+globalThis.setup({allow_uncaught_exception: true});
+
+globalThis.log = [];
+
+globalThis.addEventListener("error",
+ event => globalThis.log.push("global-error", event.error.message));
+globalThis.addEventListener("onunhandledrejection",
+ event => globalThis.log.push('unhandled-promise-rejection'));
+globalThis.addEventListener("load",
+ event => globalThis.log.push("global-load"));
+
+globalThis.unreachable = function() {
+ globalThis.log.push("unreachable");
+}
+
+globalThis.test_load = async_test("Test evaluation order of modules");
+globalThis.testDone = globalThis.test_load.step_func_done(() => {
+ assert_array_equals(globalThis.log, globalThis.expectedLog);
+});
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/import_resolve_failure.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/import_resolve_failure.js
new file mode 100644
index 0000000000..a2e2875f20
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/import_resolve_failure.js
@@ -0,0 +1,2 @@
+// Import from an unresolvable module specifier.
+import {x} from "unresolvable";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/indirect_export_resolve_failure.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/indirect_export_resolve_failure.js
new file mode 100644
index 0000000000..282fd2ed62
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/indirect_export_resolve_failure.js
@@ -0,0 +1,2 @@
+// Export from an unresolvable module specifier.
+export {x, y} from "unresolvable";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_import.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_import.js
new file mode 100644
index 0000000000..885db02dde
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_import.js
@@ -0,0 +1,2 @@
+// Import a non-existent export to trigger instantiation failure.
+import {not_found} from "./module.js";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_indirect_export.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_indirect_export.js
new file mode 100644
index 0000000000..8494031b09
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/missing_indirect_export.js
@@ -0,0 +1,2 @@
+// Import a non-existent export to trigger instantiation failure.
+export {x, not_found} from "./module.js";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import.js
new file mode 100644
index 0000000000..371018f1f4
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import.js
@@ -0,0 +1 @@
+export * from "http://web-platform.test:8000/_mozilla/html/semantics/scripting-1/the-script-element/support/mixed_import2.js"
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import2.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import2.js
new file mode 100644
index 0000000000..60c6c8d8b0
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/mixed_import2.js
@@ -0,0 +1 @@
+export default "foo";
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js
new file mode 100644
index 0000000000..1269686475
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js
@@ -0,0 +1,2 @@
+export let x = 42;
+moduleRan = true;
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module_eval_error.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module_eval_error.js
new file mode 100644
index 0000000000..3bd872b2e6
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module_eval_error.js
@@ -0,0 +1,3 @@
+// A module that throws when evaluated.
+
+this = 0;
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/README.md b/testing/web-platform/mozilla/tests/html/syntax/charset/README.md
new file mode 100644
index 0000000000..0558ae1cd5
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/README.md
@@ -0,0 +1,7 @@
+The tests in this directory intentionally differ from WebKit and Blink.
+
+These are case where using the real tree builder (with `noscript`) parsing
+as in the scripting enabled mode and with CDATA sections parsing with
+awareness of foreign content differs from WebKit's and Blink's behavior
+that works as if there was a pre-foreign content, pre-template tree builder
+running in the scripting disabled mode.
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-after-template.html b/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-after-template.html
new file mode 100644
index 0000000000..71ef9144e0
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-after-template.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+<link rel="mismatch" href="references/in-noscript-after-template-ref.html">
+<noscript><template></template><meta charset="windows-1251"></noscript>
+</head>
+<body>
+<p>Meta in <code>noscript</code> after <code>template</code> (which is also inside the <code>noscript</code>).</p>
+<p>Test: æ</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-ncr.html b/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-ncr.html
new file mode 100644
index 0000000000..645f151b26
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript-ncr.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+<link rel="mismatch" href="references/in-noscript-ncr-ref.html">
+<noscript><meta charset="&#119;indows-1251"></noscript>
+</head>
+<body>
+<p>Meta with NCR in the encoding label in <code>noscript</code>.</p>
+<p>Test: æ</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript.html b/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript.html
new file mode 100644
index 0000000000..e76054d618
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/in-noscript.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+<link rel="mismatch" href="references/in-noscript-ref.html">
+<noscript><meta charset="windows-1251"></noscript>
+</head>
+<body>
+<p>Meta in <code>noscript</code>.</p>
+<p>Test: æ</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/in-svg-in-cdata-after-gt.html b/testing/web-platform/mozilla/tests/html/syntax/charset/in-svg-in-cdata-after-gt.html
new file mode 100644
index 0000000000..56783b7afc
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/in-svg-in-cdata-after-gt.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+<link rel="mismatch" href="references/in-svg-in-cdata-after-gt-ref.html">
+</head>
+<body>
+<svg><![CDATA[><meta charset="windows-1251">]]></svg>
+<p>In SVG in CDATA after greater-than sign in the CDATA (after head).</p>
+<p>Test: æ</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-after-template-ref.html b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-after-template-ref.html
new file mode 100644
index 0000000000..27defe54c0
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-after-template-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+<p>Meta in <code>noscript</code> after <code>template</code> (which is also inside the <code>noscript</code>).</p>
+<p>Test: ж</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ncr-ref.html b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ncr-ref.html
new file mode 100644
index 0000000000..3581ab68db
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ncr-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+<p>Meta with NCR in the encoding label in <code>noscript</code>.</p>
+<p>Test: ж</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ref.html b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ref.html
new file mode 100644
index 0000000000..9bb9f24b88
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-noscript-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+<p>Meta in <code>noscript</code>.</p>
+<p>Test: ж</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>
diff --git a/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-svg-in-cdata-after-gt-ref.html b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-svg-in-cdata-after-gt-ref.html
new file mode 100644
index 0000000000..2868f47fc2
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/charset/references/in-svg-in-cdata-after-gt-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+<svg></svg>
+<p>In SVG in CDATA after greater-than sign in the CDATA (after head).</p>
+<p>Test: ж</p>
+<p>If &#x0436;, meta takes effect</p>
+</body>