Skip to content

Commit

Permalink
Bug 1754222 [wpt PR 32750] - App history: basic focusReset support, a…
Browse files Browse the repository at this point in the history
…=testonly

Automatic update from web-platform-tests
App history: basic focusReset support

Based on the draft at WICG/navigation-api#201.

This includes handling multiple conflicting focusReset options, with a console warning if necessary.

Limitations, to be addressed in future commits:

* This does not take into account autofocus="" elements.

* This will reset focus even if the user has moved focus in the meantime.

Bug: 1183545
Change-Id: I1eae4fc58af653fa7e463a1346a9bebc9536a59f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3441109
Reviewed-by: Nate Chapin <japhet@chromium.org>
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Cr-Commit-Position: refs/heads/main@{#970838}

--

wpt-commits: e6bbf057e52677c2f90fc22925673e3ca72bcd69
wpt-pr: 32750
  • Loading branch information
domenic authored and moz-wptsync-bot committed Mar 7, 2022
1 parent 75db144 commit 6c56f60
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
64 changes: 64 additions & 0 deletions testing/web-platform/tests/app-history/focus-reset/basic.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script type="module">
import { testFocusWasReset, testFocusWasNotReset } from "./resources/helpers.mjs";

test(() => {
let throwAssertionHappened = false;

appHistory.addEventListener("navigate", e => {
assert_throws_js(TypeError, () => {
e.transitionWhile(Promise.resolve(), { focusReset: "invalid" });
});
throwAssertionHappened = true;
}, { once: true });

appHistory.navigate("#1");
assert_true(throwAssertionHappened);
}, "Invalid values for focusReset throw");

testFocusWasNotReset(() => {
// Intentionally left blank.
}, "Does not reset the focus when no navigate handler is present");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve());
}, { once: true });
}, "Resets the focus when no focusReset option is provided");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve());
}, { once: true });
}, "Resets the focus when focusReset is explicitly set to undefined");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(new Promise(r => t.step_timeout(r, 5)));
}, { once: true });
}, "Resets the focus when no focusReset option is provided (nontrivial fulfilled promise)");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.reject());
}, { once: true });
}, "Resets the focus when no focusReset option is provided (rejected promise)");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(
Promise.resolve(),
{ focusReset: "after-transition" }
);
}, { once: true });
}, "Resets the focus when focusReset is explicitly set to 'after-transition'");

testFocusWasNotReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "manual" });
});
}, "Does not reset the focus when focusReset is set to 'manual'");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script type="module">
import { testFocusWasReset, testFocusWasNotReset } from "./resources/helpers.mjs";

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve());
}, { once: true });

appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "after-transition" });
}, { once: true });
}, "(not provided) + after-transition");

testFocusWasNotReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve());
}, { once: true });

appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "manual" });
}, { once: true });
}, "(not provided) + manual");

testFocusWasNotReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "after-transition" });
}, { once: true });

appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "manual" });
}, { once: true });
}, "after-transition + manual");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "after-transition" });
}, { once: true });

appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve());
}, { once: true });
}, "after-transition + (not provided)");

testFocusWasReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "manual" });
}, { once: true });

appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "after-transition" });
}, { once: true });
}, "manual + after-transition");

testFocusWasNotReset(t => {
appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve(), { focusReset: "manual" });
}, { once: true });

appHistory.addEventListener("navigate", e => {
e.transitionWhile(Promise.resolve());
}, { once: true });
}, "manual + (not provided)");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Usage note: if you use these more than once in a given file, be sure to
// clean up any navigate event listeners, e.g. by using { once: true }, between
// tests.

export function testFocusWasReset(setupFunc, description) {
promise_test(async t => {
setupFunc(t);

const button = document.body.appendChild(document.createElement("button"));
t.add_cleanup(() => { button.remove(); });

assert_equals(document.activeElement, document.body, "Start on body");
button.focus();
assert_equals(document.activeElement, button, "focus() worked");

const { committed, finished } = appHistory.navigate("#" + location.hash.substring(1) + "1");

await committed;
assert_equals(document.activeElement, button, "Focus stays on the button during the transition");

await finished.catch(() => {});
assert_equals(document.activeElement, document.body, "Focus reset after the transition");
}, description);
}

export function testFocusWasNotReset(setupFunc, description) {
promise_test(async t => {
setupFunc(t);

const button = document.body.appendChild(document.createElement("button"));
t.add_cleanup(() => { button.remove(); });

assert_equals(document.activeElement, document.body, "Start on body");
button.focus();
assert_equals(document.activeElement, button, "focus() worked");

const { committed, finished } = appHistory.navigate("#" + location.hash.substring(1) + "1");

await committed;
assert_equals(document.activeElement, button, "Focus stays on the button during the transition");

await finished.catch(() => {});
assert_equals(document.activeElement, button, "Focus stays on the button after the transition");
}, description);
}

0 comments on commit 6c56f60

Please sign in to comment.