diff --git a/testing/web-platform/tests/app-history/focus-reset/basic.html b/testing/web-platform/tests/app-history/focus-reset/basic.html
new file mode 100644
index 0000000000000..fb57cf864482a
--- /dev/null
+++ b/testing/web-platform/tests/app-history/focus-reset/basic.html
@@ -0,0 +1,64 @@
+
+
+
+
+
diff --git a/testing/web-platform/tests/app-history/focus-reset/multiple-transitionWhile.html b/testing/web-platform/tests/app-history/focus-reset/multiple-transitionWhile.html
new file mode 100644
index 0000000000000..d38df573e5953
--- /dev/null
+++ b/testing/web-platform/tests/app-history/focus-reset/multiple-transitionWhile.html
@@ -0,0 +1,67 @@
+
+
+
+
+
diff --git a/testing/web-platform/tests/app-history/focus-reset/resources/helpers.mjs b/testing/web-platform/tests/app-history/focus-reset/resources/helpers.mjs
new file mode 100644
index 0000000000000..e3012a0b12e61
--- /dev/null
+++ b/testing/web-platform/tests/app-history/focus-reset/resources/helpers.mjs
@@ -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);
+}