Skip to content

Commit 3248b40

Browse files
farrefoolip
authored andcommitted
Part 2: Re-work tests that don't work with #wait-for-all.
The issue is that when there are no intercept handlers, or the handlers provide a result immediately by returning or resolving/rejecting. This will mean that the reactions for committed and finished will run in the same microtask, which is correct according to spec. Differential Revision: https://phabricator.services.mozilla.com/D291776 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=2028907 gecko-commit: 289586a1a04ef5ebb259721340de41f5ecdd92cd gecko-commit-git: ebed8d507ea5c9740c9916d9b5a7aef7f11b3fa1 gecko-reviewers: dom-core, jjaschke
1 parent a6fd897 commit 3248b40

14 files changed

Lines changed: 86 additions & 49 deletions

navigation-api/focus-reset/autofocus.html

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
<!doctype html>
22
<script src="/resources/testharness.js"></script>
33
<script src="/resources/testharnessreport.js"></script>
4+
<meta name="variant" content="?delayed-checkpoint">
5+
<meta name="variant" content="?same-checkpoint">
46

57
<button autofocus id="initialAutofocusTarget">Initial autofocus target</button>
68

79
<script type="module">
10+
11+
const delayed = location.search === "?delayed-checkpoint";
12+
13+
function createExpected(t, decoy, autofocusTarget) {
14+
const handler = delayed ? { handler: () => new Promise(r => t.step_timeout(r, 0)) } : {};
15+
const expectedDecoy = delayed ? decoy : autofocusTarget;
16+
const decoyMessage = delayed ? "Focus moves to the autofocused button after the transition" : "Focus stays on the non-autofocused button after the transition";
17+
const expectedBody = delayed ? document.body : expectedDecoy;
18+
const bodyMessage = delayed ? "Focus gets reset after the transition" : "Focus moves to the autofocused button after the transition";
19+
20+
return { handler, expectedDecoy, decoyMessage, expectedBody, bodyMessage };
21+
}
22+
823
promise_setup(async () => {
924
// Get the overall autofocus processed flag to flip to true, so that
1025
// we only test the navigation API-specific stuff.
@@ -22,14 +37,15 @@
2237
decoy.focus();
2338
assert_equals(document.activeElement, decoy, "focus() worked");
2439

40+
const { handler, expectedDecoy, decoyMessage } = createExpected(t, decoy, autofocusTarget);
2541
navigation.addEventListener("navigate", e => {
26-
e.intercept();
42+
e.intercept(handler);
2743
}, { once: true });
2844

2945
const { committed, finished } = navigation.navigate("#1");
3046

3147
await committed;
32-
assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
48+
assert_equals(document.activeElement, expectedDecoy, decoyMessage);
3349

3450
await finished;
3551
assert_equals(document.activeElement, autofocusTarget, "Focus moves to the autofocused button after the transition");
@@ -43,14 +59,15 @@
4359
decoy.focus();
4460
assert_equals(document.activeElement, decoy, "focus() worked");
4561

62+
const { handler, expectedDecoy, decoyMessage } = createExpected(t, decoy, autofocusTarget);
4663
navigation.addEventListener("navigate", e => {
47-
e.intercept();
64+
e.intercept(handler);
4865
}, { once: true });
4966

5067
const { committed, finished } = navigation.navigate("#1");
5168

5269
await committed;
53-
assert_equals(document.activeElement, decoy, "Focus stays on the initially-focused button during the transition");
70+
assert_equals(document.activeElement, expectedDecoy, decoyMessage);
5471

5572
await finished;
5673
assert_equals(document.activeElement, autofocusTarget, "Focus moves to the first autofocused button after the transition");
@@ -64,19 +81,20 @@
6481
decoy.focus();
6582
assert_equals(document.activeElement, decoy, "focus() worked");
6683

84+
const { handler, expectedDecoy, decoyMessage, expectedBody, bodyMessage } = createExpected(t, decoy, autofocusTarget);
6785
navigation.addEventListener("navigate", e => {
68-
e.intercept();
86+
e.intercept(handler);
6987
}, { once: true });
7088

7189
const { committed, finished } = navigation.navigate("#1");
7290

7391
await committed;
74-
assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
92+
assert_equals(document.activeElement, expectedDecoy, decoyMessage);
7593

7694
autofocusTarget.disabled = true;
7795

7896
await finished;
79-
assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
97+
assert_equals(document.activeElement, expectedBody, bodyMessage);
8098
}, "An element with autofocus, present before navigation but disabled before finished, does not get focused");
8199

82100
promise_test(async t => {
@@ -87,19 +105,20 @@
87105
decoy.focus();
88106
assert_equals(document.activeElement, decoy, "focus() worked");
89107

108+
const { handler, expectedDecoy, decoyMessage, expectedBody, bodyMessage } = createExpected(t, decoy, autofocusTarget);
90109
navigation.addEventListener("navigate", e => {
91-
e.intercept();
110+
e.intercept(handler);
92111
}, { once: true });
93112

94113
const { committed, finished } = navigation.navigate("#1");
95114

96115
await committed;
97-
assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
116+
assert_equals(document.activeElement, expectedDecoy, decoyMessage);
98117

99118
autofocusTarget.autofocus = false;
100119

101120
await finished;
102-
assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
121+
assert_equals(document.activeElement, expectedBody, bodyMessage);
103122
}, "An element with autofocus, present before navigation but with its autofocus attribute removed before finished, does not get focused");
104123

105124
promise_test(async t => {
@@ -110,8 +129,9 @@
110129
decoy.focus();
111130
assert_equals(document.activeElement, decoy, "focus() worked");
112131

132+
const { handler } = createExpected(t, decoy, autofocusTarget);
113133
navigation.addEventListener("navigate", e => {
114-
e.intercept();
134+
e.intercept(handler);
115135
}, { once: true });
116136

117137
const { committed, finished } = navigation.navigate("#1");
@@ -122,29 +142,45 @@
122142
decoy.disabled = true;
123143

124144
await finished;
125-
assert_equals(document.activeElement, autofocusTarget, "Focus moves to the second autofocused button after the transition");
145+
146+
if (delayed) {
147+
assert_equals(document.activeElement, autofocusTarget, "Focus moves to the second autofocused button after the transition");
148+
} else {
149+
assert_equals(document.activeElement, decoy, "Focus stays on the initially-focused button during the transition");
150+
}
126151
}, "Two elements with autofocus, present before navigation, but the first gets disabled; the second gets focused");
127152

128153
promise_test(async t => {
154+
if (delayed) {
155+
assert_true(delayed, "This is only relevant for non-finished ")
156+
return;
157+
}
129158
const decoy = createAndAppend(t);
130159

131160
assert_equals(document.activeElement, document.body, "Start on body");
132161
decoy.focus();
133162
assert_equals(document.activeElement, decoy, "focus() worked");
134163

164+
const { handler } = createExpected(t, decoy, document.body);
135165
navigation.addEventListener("navigate", e => {
136-
e.intercept();
166+
e.intercept(() => {
167+
t.step_timeout(handler, 0)
168+
});
137169
}, { once: true });
138170

139171
const { committed, finished } = navigation.navigate("#1");
140172

141173
await committed;
142-
assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
174+
assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
143175

144176
const autofocusTarget = createAndAppend(t, { autofocus: true });
145177

146178
await finished;
147-
assert_equals(document.activeElement, autofocusTarget, "Focus moves to the autofocused button after the transition");
179+
assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");
180+
181+
await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)));
182+
assert_equals(document.activeElement, document.body, "Focus stays reset two animation frames after the transition");
183+
148184
}, "An element with autofocus, introduced between committed and finished, gets focused");
149185

150186
promise_test(async t => {
@@ -154,14 +190,15 @@
154190
decoy.focus();
155191
assert_equals(document.activeElement, decoy, "focus() worked");
156192

193+
const { handler } = createExpected(t, decoy, document.body);
157194
navigation.addEventListener("navigate", e => {
158-
e.intercept();
195+
e.intercept(handler);
159196
}, { once: true });
160197

161198
const { committed, finished } = navigation.navigate("#1");
162199

163200
await committed;
164-
assert_equals(document.activeElement, decoy, "Focus stays on the non-autofocused button during the transition");
201+
assert_equals(document.activeElement, delayed ? decoy : document.body, delayed ? "Focus stays on the non-autofocused button during the transition" : "Focus gets reset after the transition");
165202

166203
await finished;
167204
assert_equals(document.activeElement, document.body, "Focus gets reset after the transition");

navigation-api/focus-reset/basic.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727

2828
testFocusWasReset(t => {
2929
navigation.addEventListener("navigate", e => {
30-
e.intercept();
30+
e.intercept({ handler: () => new Promise(r => t.step_timeout(r, 0)) });
3131
}, { once: true });
3232
}, "Resets the focus when no focusReset option is provided");
3333

3434
testFocusWasReset(t => {
3535
navigation.addEventListener("navigate", e => {
36-
e.intercept();
36+
e.intercept({ handler: () => new Promise(r => t.step_timeout(r, 0)) });
3737
}, { once: true });
3838
}, "Resets the focus when focusReset is explicitly set to undefined");
3939

@@ -45,13 +45,13 @@
4545

4646
testFocusWasReset(t => {
4747
navigation.addEventListener("navigate", e => {
48-
e.intercept({ handler: () => Promise.reject() });
48+
e.intercept({ handler: () => new Promise((_, r) => t.step_timeout(r, 0)) });
4949
}, { once: true });
5050
}, "Resets the focus when no focusReset option is provided (rejected promise)");
5151

5252
testFocusWasReset(t => {
5353
navigation.addEventListener("navigate", e => {
54-
e.intercept({ focusReset: "after-transition" });
54+
e.intercept({ handler: () => new Promise(r => t.step_timeout(r, 0)), focusReset: "after-transition" });
5555
}, { once: true });
5656
}, "Resets the focus when focusReset is explicitly set to 'after-transition'");
5757

navigation-api/focus-reset/multiple-intercept.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
testFocusWasReset(t => {
1111
navigation.addEventListener("navigate", e => {
12-
e.intercept();
12+
e.intercept({ handler: () => new Promise(r => t.step_timeout(r, 0)) });
1313
}, { once: true });
1414

1515
navigation.addEventListener("navigate", e => {
@@ -43,13 +43,13 @@
4343
}, { once: true });
4444

4545
navigation.addEventListener("navigate", e => {
46-
e.intercept();
46+
e.intercept({ handler: () => new Promise(r => t.step_timeout(r, 0)) });
4747
}, { once: true });
4848
}, "after-transition + (not provided)");
4949

5050
testFocusWasReset(t => {
5151
navigation.addEventListener("navigate", e => {
52-
e.intercept({ focusReset: "manual" });
52+
e.intercept({ handler: () => new Promise(r => t.step_timeout(r, 0)), focusReset: "manual" });
5353
}, { once: true });
5454

5555
navigation.addEventListener("navigate", e => {

navigation-api/ordering-and-transition/anchor-download-intercept-reject.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
["navigate", "", null],
4545
["currententrychange", "#1", { from, navigationType: "push" }],
4646
["handler run", "#1", { from, navigationType: "push" }],
47-
["promise microtask", "#1", { from, navigationType: "push" }],
4847
["AbortSignal abort", "#1", { from, navigationType: "push" }],
4948
["navigateerror", "#1", { from, navigationType: "push" }],
49+
["promise microtask", "#1", null],
5050
["transition.finished rejected", "#1", null],
5151
]);
5252

navigation-api/ordering-and-transition/anchor-download-intercept.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
["navigate", "", null],
4141
["currententrychange", "#1", { from, navigationType: "push" }],
4242
["handler run", "#1", { from, navigationType: "push" }],
43-
["promise microtask", "#1", { from, navigationType: "push" }],
4443
["navigatesuccess", "#1", { from, navigationType: "push" }],
44+
["promise microtask", "#1", null],
4545
["transition.finished fulfilled", "#1", null],
4646
]);
4747
}, "event and promise ordering for <a download> intercepted by intercept()");

navigation-api/ordering-and-transition/location-href-intercept-reject.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
["navigate", "", null],
4141
["currententrychange", "#1", { from, navigationType: "push" }],
4242
["handler run", "#1", { from, navigationType: "push" }],
43-
["promise microtask", "#1", { from, navigationType: "push" }],
4443
["AbortSignal abort", "#1", { from, navigationType: "push" }],
4544
["navigateerror", "#1", { from, navigationType: "push" }],
45+
["promise microtask", "#1", null],
4646
["transition.finished rejected", "#1", null],
4747
]);
4848

navigation-api/ordering-and-transition/location-href-intercept.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
["navigate", "", null],
3737
["currententrychange", "#1", { from, navigationType: "push" }],
3838
["handler run", "#1", { from, navigationType: "push" }],
39-
["promise microtask", "#1", { from, navigationType: "push" }],
4039
["navigatesuccess", "#1", { from, navigationType: "push" }],
40+
["promise microtask", "#1", null],
4141
["transition.finished fulfilled", "#1", null],
4242
]);
4343
}, "event and promise ordering for location.href setter intercepted by intercept()");

navigation-api/ordering-and-transition/navigate-in-transition-finished.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,19 @@
5151
["navigate", "", null],
5252
["currententrychange", "#1", { from: fromStart, navigationType: "push" }],
5353
["handler run", "#1", { from: fromStart, navigationType: "push" }],
54-
["committed fulfilled 1", "#1", { from: fromStart, navigationType: "push" }],
55-
["transition.committed fulfilled 1", "#1", { from: fromStart, navigationType: "push" }],
56-
["promise microtask", "#1", { from: fromStart, navigationType: "push" }],
5754
["navigatesuccess", "#1", { from: fromStart, navigationType: "push" }],
55+
["committed fulfilled 1", "#1", null],
56+
["transition.committed fulfilled 1", "#1", null],
57+
["promise microtask", "#1", null],
5858
["finished fulfilled 1", "#1", null],
5959
["transition.finished fulfilled", "#1", null],
6060

6161
["navigate", "#1", null],
6262
["currententrychange", "#2", { from: fromHash1, navigationType: "push" }],
6363
["handler run", "#2", { from: fromHash1, navigationType: "push" }],
64-
["committed fulfilled 2", "#2", { from: fromHash1, navigationType: "push" }],
65-
["transition.committed fulfilled 2", "#2", { from: fromHash1, navigationType: "push" }],
6664
["navigatesuccess", "#2", { from: fromHash1, navigationType: "push" }],
65+
["committed fulfilled 2", "#2", null],
66+
["transition.committed fulfilled 2", "#2", null],
6767
["finished fulfilled 2", "#2", null],
6868
["transition.finished fulfilled", "#2", null]
6969
]);

navigation-api/ordering-and-transition/navigate-intercept.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
["navigate", "", null],
3838
["currententrychange", "#1", { from, navigationType: "push" }],
3939
["handler run", "#1", { from, navigationType: "push" }],
40-
["committed fulfilled", "#1", { from, navigationType: "push" }],
41-
["transition.committed fulfilled", "#1", { from, navigationType: "push" }],
42-
["promise microtask", "#1", { from, navigationType: "push" }],
4340
["navigatesuccess", "#1", { from, navigationType: "push" }],
41+
["committed fulfilled", "#1", null],
42+
["transition.committed fulfilled", "#1", null],
43+
["promise microtask", "#1", null],
4444
["finished fulfilled", "#1", null],
4545
["transition.finished fulfilled", "#1", null],
4646
]);

navigation-api/ordering-and-transition/navigate-same-document-intercept-reject.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@
4141
["navigate", "", null],
4242
["currententrychange", "#1", { from, navigationType: "push" }],
4343
["handler run", "#1", { from, navigationType: "push" }],
44-
["committed fulfilled", "#1", { from, navigationType: "push" }],
45-
["transition.committed fulfilled", "#1", { from, navigationType: "push" }],
46-
["promise microtask", "#1", { from, navigationType: "push" }],
4744
["AbortSignal abort", "#1", { from, navigationType: "push" }],
4845
["navigateerror", "#1", { from, navigationType: "push" }],
46+
["committed fulfilled", "#1", null],
47+
["transition.committed fulfilled", "#1", null],
48+
["promise microtask", "#1", null],
4949
["finished rejected", "#1", null],
5050
["transition.finished rejected", "#1", null],
5151
]);

0 commit comments

Comments
 (0)