summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/navigation-api/focus-reset/autofocus.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/navigation-api/focus-reset/autofocus.html')
-rw-r--r--testing/web-platform/tests/navigation-api/focus-reset/autofocus.html185
1 files changed, 185 insertions, 0 deletions
diff --git a/testing/web-platform/tests/navigation-api/focus-reset/autofocus.html b/testing/web-platform/tests/navigation-api/focus-reset/autofocus.html
new file mode 100644
index 0000000000..6044447367
--- /dev/null
+++ b/testing/web-platform/tests/navigation-api/focus-reset/autofocus.html
@@ -0,0 +1,185 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<button autofocus id="initialAutofocusTarget">Initial autofocus target</button>
+
+<script type="module">
+promise_setup(async () => {
+ // Get the overall autofocus processed flag to flip to true, so that
+ // we only test the navigation API-specific stuff.
+ await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)));
+ assert_equals(document.activeElement, initialAutofocusTarget, "Non-navigation API autofocus was processed");
+ initialAutofocusTarget.remove();
+ assert_equals(document.activeElement, document.body);
+});
+
+promise_test(async t => {
+ const decoy = createAndAppend(t);
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
+
+ await finished;
+ assert_equals(document.activeElement, autofocusTarget, "Focus moves to the autofocused button after the transition");
+}, "An element with autofocus, present before navigation, gets focused");
+
+promise_test(async t => {
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+ const decoy = createAndAppend(t, { autofocus: true });
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the initially-focused button during the transition");
+
+ await finished;
+ assert_equals(document.activeElement, autofocusTarget, "Focus moves to the first autofocused button after the transition");
+}, "Two elements with autofocus, present before navigation; the first gets focused");
+
+promise_test(async t => {
+ const decoy = createAndAppend(t);
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
+
+ autofocusTarget.disabled = true;
+
+ await finished;
+ assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
+}, "An element with autofocus, present before navigation but disabled before finished, does not get focused");
+
+promise_test(async t => {
+ const decoy = createAndAppend(t);
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
+
+ autofocusTarget.autofocus = false;
+
+ await finished;
+ assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
+}, "An element with autofocus, present before navigation but with its autofocus attribute removed before finished, does not get focused");
+
+promise_test(async t => {
+ const decoy = createAndAppend(t, { autofocus: true });
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the initially-focused button during the transition");
+
+ decoy.disabled = true;
+ assert_equals(document.activeElement, document.body, "Disabling the initially-focused button temporarily resets focus to the body");
+
+ await finished;
+ assert_equals(document.activeElement, autofocusTarget, "Focus moves to the second autofocused button after the transition");
+}, "Two elements with autofocus, present before navigation, but the first gets disabled; the second gets focused");
+
+promise_test(async t => {
+ const decoy = createAndAppend(t);
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
+
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+
+ await finished;
+ assert_equals(document.activeElement, autofocusTarget, "Focus moves to the autofocused button after the transition");
+}, "An element with autofocus, introduced between committed and finished, gets focused");
+
+promise_test(async t => {
+ const decoy = createAndAppend(t);
+
+ assert_equals(document.activeElement, document.body, "Start on body");
+ decoy.focus();
+ assert_equals(document.activeElement, decoy, "focus() worked");
+
+ navigation.addEventListener("navigate", e => {
+ e.intercept();
+ }, { once: true });
+
+ const { committed, finished } = navigation.navigate("#1");
+
+ await committed;
+ assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
+
+ await finished;
+ assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
+
+ const autofocusTarget = createAndAppend(t, { autofocus: true });
+
+ await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)));
+ assert_equals(document.activeElement, document.body, "Focus stays reset two animation frames after the transition");
+}, "An element with autofocus, introduced after finished, does not get focused");
+
+function createAndAppend(t, props) {
+ const element = document.createElement("button");
+ Object.assign(element, props);
+
+ document.body.append(element);
+ t.add_cleanup(() => { element.remove(); });
+
+ return element;
+}
+</script>