Skip to content

Commit

Permalink
Make navigation-api/navigate-event/ resilient to starting with extra …
Browse files Browse the repository at this point in the history
…NavigationHistoryEntries

When WPT are run in-browser or via wptrunner, there may be additional
session history entries when the test starts, so the tests shouldn't
assume that they start with navigation.entries().length == 1 or
navigation.currentEntry.index == 0.

This is a workaround for #33590.

Change-Id: I978d492d5d31d110716d6a1d84732aff792aca14
  • Loading branch information
natechapin authored and chromium-wpt-export-bot committed Oct 3, 2023
1 parent 3ae2cb8 commit 2cd3809
Show file tree
Hide file tree
Showing 15 changed files with 89 additions and 50 deletions.
11 changes: 7 additions & 4 deletions navigation-api/navigate-event/intercept-and-navigate.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(r => window.onload = () => t.step_timeout(r, 0));
Expand All @@ -12,16 +15,16 @@
navigation.oncurrententrychange = e => {
if (e.navigationType == "traverse") {
assert_equals(location.hash, "");
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(navigation.entries().length, start_length + 1);
navigation.navigate("#2");
}
};
let back_result = navigation.back();
await back_result.committed;
assert_equals(location.hash, "#2");
await promise_rejects_dom(t, "AbortError", back_result.finished);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(navigation.entries().length, start_length + 1);
}, "Using intercept() then navigate() in the ensuing currententrychange should abort the finished promise (but not the committed promise)");
</script>
7 changes: 5 additions & 2 deletions navigation-api/navigate-event/intercept-navigation-back.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
<script src="/resources/testharnessreport.js"></script>
<script>
async_test(t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
window.onload = () => t.step_timeout(() => {
navigation.navigate("#foo").committed.then(() => {
assert_true(navigation.canGoBack);
navigation.onnavigate = t.step_func(e => e.intercept());
navigation.back().committed.then(t.step_func_done(() => {
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.currentEntry, navigation.entries()[0]);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(navigation.currentEntry, navigation.entries()[start_index]);
}));
});
}, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<script src="/resources/testharnessreport.js"></script>
<script>
async_test(t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
window.onload = () => t.step_timeout(() => {
Expand All @@ -15,13 +18,13 @@
navigation.onnavigatesuccess = t.step_func(e => {
onnavigatesuccess_calls++;
if (onnavigatesuccess_calls == 3) {
assert_equals(navigation.entries().length, 3);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.entries().length, start_length + 2);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(onnavigate_calls, 3);
history.back();
} else if (onnavigatesuccess_calls == 4) {
assert_equals(navigation.entries().length, 3);
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.entries().length, start_length + 2);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(onnavigate_calls, 4);
t.done();
}
Expand All @@ -30,8 +33,8 @@
navigation.navigate("?foo").finished
.then(t.step_func(() => navigation.navigate("?bar").finished))
.then(t.step_func(() => {
assert_equals(navigation.entries().length, 3);
assert_equals(navigation.currentEntry.index, 2);
assert_equals(navigation.entries().length, start_length + 2);
assert_equals(navigation.currentEntry.index, start_index + 2);
assert_equals(onnavigate_calls, 2);
history.back();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<script src="../navigation-methods/return-value/resources/helpers.js"></script>
<script>
promise_test(async t => {
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
Expand All @@ -12,7 +14,7 @@
let back_destination;
navigation.addEventListener("navigate", t.step_func(e => {
back_destination = e.destination;
assert_equals(back_destination.index, 0);
assert_equals(back_destination.index, start_index);
}), { once: true });
await navigation.back().finished;

Expand All @@ -23,7 +25,7 @@
assert_equals(back_destination.index, -1);

navigation.addEventListener("navigate", t.step_func(e => {
assert_equals(e.destination.index, 1);
assert_equals(e.destination.index, start_index + 1);

// Dispose the destination entry and destination.index should update.
navigation.navigate("#clobber_forward");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
async_test(t => {
window.onload = () => t.step_timeout(() => {
let start_length = history.length;
let start_index = navigation.currentEntry.index;
let target_key = navigation.currentEntry.key;
let target_id = navigation.currentEntry.id;
location.hash = "#1";
Expand All @@ -21,7 +22,7 @@
assert_true(e.destination.sameDocument);
assert_equals(e.destination.key, target_key);
assert_equals(e.destination.id, target_id);
assert_equals(e.destination.index, 0);
assert_equals(e.destination.index, start_index);
assert_equals(e.formData, null);
assert_equals(e.sourceElement, null);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
<script>
async_test(t => {
window.onload = () => t.step_timeout(() => {
let start_length = history.length;
let start_history_length = history.length;
let start_index = navigation.currentEntry.index;
let target_key = navigation.currentEntry.key;
let target_id = navigation.currentEntry.id;
history.pushState(1, "", "pushState.html");
assert_equals(history.length, start_length + 1);
assert_equals(history.length, start_history_length + 1);

navigation.onnavigate = t.step_func_done(e => {
assert_equals(e.navigationType, "traverse");
Expand All @@ -21,7 +22,7 @@
assert_true(e.destination.sameDocument);
assert_equals(e.destination.key, target_key);
assert_equals(e.destination.id, target_id);
assert_equals(e.destination.index, 0);
assert_equals(e.destination.index, start_index);
assert_equals(e.formData, null);
assert_equals(e.sourceElement, null);
});
Expand Down
16 changes: 10 additions & 6 deletions navigation-api/navigate-event/navigate-history-back-noop.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;
let start_history_length = history.length;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));

await i.contentWindow.navigation.navigate("#").finished;
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.currentEntry.index, 0);
assert_equals(history.length, 2);
assert_equals(navigation.entries().length, start_length);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(history.length, start_history_length + 1);

i.remove();
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.currentEntry.index, 0);
assert_equals(history.length, 2);
assert_equals(navigation.entries().length, start_length);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(history.length, start_history_length + 1);

// back() here should do nothing. The iframe that would have navigated has
// been removed. No navigate event should be fired.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
window.onload = () => t.step_timeout(() => {
let target_key = navigation.currentEntry.key;
let target_id = navigation.currentEntry.id;
let target_index = navigation.currentEntry.index;
navigation.navigate("#foo").committed.then(t.step_func(() => {
navigation.onnavigate = t.step_func_done(e => {
assert_equals(e.navigationType, "traverse");
Expand All @@ -20,7 +21,7 @@
assert_true(e.destination.sameDocument);
assert_equals(e.destination.key, target_key);
assert_equals(e.destination.id, target_id);
assert_equals(e.destination.index, 0);
assert_equals(e.destination.index, target_index);
assert_equals(e.formData, null);
assert_equals(e.info, "hi");
assert_not_equals(e.hasUAVisualTransition, undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
<script src="../navigation-methods/return-value/resources/helpers.js"></script>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));

await navigation.navigate("#").finished;
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(navigation.currentEntry.index, start_index + 1);

navigation.onnavigate = e => e.preventDefault();

Expand All @@ -20,7 +23,7 @@
navigateerror_called = true;
});
await assertBothRejectDOM(t, navigation.back(), "AbortError");
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_true(navigateerror_called);
}, "navigation.back() same-document preventDefault");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
Expand All @@ -13,9 +16,9 @@
// to its initial entry, the top window navigates as well.
await i.contentWindow.navigation.navigate("#").finished;
await navigation.navigate("#").finished;
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);

// Ensure the top window, which is allowed to cancel the traversal, does so.
Expand All @@ -37,7 +40,7 @@
const iDOMException = iWindow.DOMException;
await assertBothRejectDOM(t, i.contentWindow.navigation.traverseTo(i.contentWindow.navigation.entries()[0].key), "AbortError", iWindow, iDOMException);
assert_true(top_navigateerror_fired);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);
}, "navigation.traverseTo() in an iframe with same-document preventDefault in its parent");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<iframe id="i2" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
Expand All @@ -13,10 +16,10 @@
i2.contentWindow.navigation.navigate("?");
await new Promise(resolve => i2.onload = () => t.step_timeout(resolve, 0));

assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(i1.contentWindow.navigation.entries().length, 2);
assert_equals(i2.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(i1.contentWindow.navigation.currentEntry.index, 1);
assert_equals(i2.contentWindow.navigation.currentEntry.index, 1);

Expand All @@ -37,12 +40,12 @@
assert_false(e.cancelable);
});

await navigation.traverseTo(navigation.entries()[0].key).finished;
await navigation.traverseTo(navigation.entries()[start_index].key).finished;
// The top window will finish quickly, becuase it is same-document traversal.
// i2 will be slower because it is cross-document, so wait for its onload.
await new Promise(resolve => i2.onload = () => t.step_timeout(resolve, 0));
assert_equals(navigate_event_count, 3);
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.currentEntry.index, start_index);
assert_equals(i1.contentWindow.navigation.currentEntry.index, 0);
assert_equals(i2.contentWindow.navigation.currentEntry.index, 0);
}, "navigation.traverseTo() can navigate 3 frames of different types with correct navigate event cancelable values");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
await navigation.navigate("#").finished;
await i.contentWindow.navigation.navigate("#").finished;
assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);

navigation.onnavigate = e => e.preventDefault();
i.contentWindow.navigation.onnavigate = t.unreached_func("navigate event should not fire in the iframe, because the traversal was cancelled in the top window");
await promise_rejects_dom(t, "AbortError", navigation.traverseTo(navigation.entries()[0].key).finished);
assert_equals(navigation.currentEntry.index, 1);
await promise_rejects_dom(t, "AbortError", navigation.traverseTo(navigation.entries()[start_index].key).finished);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);
}, "navigation.traverseTo() - if a top window cancels the traversal, any iframes should not fire navigate");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
<iframe id="i" src="/common/blank.html"></iframe>
<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that the navigation doesn't get converted
// into a replace navigation.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
await navigation.navigate("#").finished;
i.contentWindow.navigation.navigate("?");
await new Promise(resolve => i.onload = () => t.step_timeout(resolve, 0));

assert_equals(navigation.entries().length, 2);
assert_equals(navigation.entries().length, start_length + 1);
assert_equals(i.contentWindow.navigation.entries().length, 2);
assert_equals(navigation.currentEntry.index, 1);
assert_equals(navigation.currentEntry.index, start_index + 1);
assert_equals(i.contentWindow.navigation.currentEntry.index, 1);

navigation.onnavigate = t.step_func(e => e.preventDefault());
i.contentWindow.navigation.onnavigate = t.unreached_func("navigation should be cancelled before iframe fires navigate event");
await assertBothRejectDOM(t, navigation.traverseTo(navigation.entries()[0].key), "AbortError");
await assertBothRejectDOM(t, navigation.traverseTo(navigation.entries()[start_index].key), "AbortError");
// Give the iframe time to navigate in case it was incorrectly permitted.
await new Promise(resolve => t.step_timeout(resolve, 50));
}, "navigate.traverseTo() cancelled by top frame cancels cross-document iframe");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@

<script>
promise_test(async t => {
let start_length = navigation.entries().length;
let start_index = navigation.currentEntry.index;

// Wait for after the load event so that we are definitely testing the
// same URL as the cause of the rejections.
await new Promise(resolve => window.onload = () => t.step_timeout(resolve, 0));
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.entries().length, start_length);

navigation.onnavigate = t.step_func(e => {
e.intercept();
Expand All @@ -17,7 +20,7 @@
navigation.onnavigateerror = t.unreached_func("onnavigateerror should not be called");

await navigation.navigate(location.href).finished;
assert_equals(navigation.entries().length, 1);
assert_equals(navigation.currentEntry.index, 0);
assert_equals(navigation.entries().length, start_length);
assert_equals(navigation.currentEntry.index, start_index);
}, "navigate() to the current URL cross document should replace");
</script>
Loading

0 comments on commit 2cd3809

Please sign in to comment.