Skip to content

Commit

Permalink
Prerender: restore main frame navigation test case for unload
Browse files Browse the repository at this point in the history
This patch also fixes timeout root cause, handling optional
result caused an infinite loop.

Bug: 1233716
Change-Id: I8fa88ab4081aaf025cf43b7155457a04113193f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3061772
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Takashi Toyoshima <toyoshim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#908784}
  • Loading branch information
toyoshim authored and Chromium LUCI CQ committed Aug 5, 2021
1 parent 7fb328a commit 13f34cf
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<script src="/common/get-host-info.sub.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="unload-utils.js"></script>
<script src="utils.js"></script>
<body>
<script type="module">
const params = new URLSearchParams(location.search);
const state = params.get('state') || 'start';

const bc = openChannel();

// Test steps:
// 1. `start` page starts prerendering `prerendering` page.
// 2. `prerendering` page navigates to `another-page`.
// 3. `prerendering` page asks the `start` page to navigate.
// 4. ``pagehide` and unload` may not be handled as the prerendering is
// cancelled.
// 5. `start` does a fallback navigation as the prerendering is cancelled.
// 6. `prerendering` page loads again with document.prerendering == false.
// 7. `prerendering` page navigates to `another-page` again.
// 8. `pagehide`, `visibilitychange`, and `unload` are handled this time.
// 9. `another-page` finishes the test.
bc.postMessage('load ' + state +
(document.prerendering ? ' in prerendering' : ''));
if (state === 'start') {
const url = createTestUrl('prerendering');
startPrerendering(url);

// Wait for a message from `prerendering` to navigate that results in
// fallback network navigation as the prerendering is cancelled.
await waitChannelMessage('request fallback');

// Navigate.
document.location = url;
} else if (state === 'prerendering') {
// unload handler may not be triggered for cancellation.
addEventListeners('main-frame');

// Trigger a main frame navigation that will cancel the prerendering.
// This navigates successfully if the page isn't prerendered.
document.location = createTestUrl('another-page');

// Ask the `start` page to navigate if on prerendering. Otherwise, finish
// the test.
if (document.prerendering)
bc.postMessage('request fallback');
} else if (state === 'another-page') {
// Reach here after the prerendering is cancelled and fallback request loads
// the `prerendering` page with document.prerendering == false. The main
// frame navigation will succeed this time.
bc.postMessage('Done');
}

bc.close();
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<!--
This file cannot be upstreamed to WPT until:
* The test changes to use a method to trigger cancellation of prerendering that
is guaranteed by the specification. Currently the test cancels prerendering
by performing a main frame navigation after the initial prerendering
navigation.
* `unload` event handling matches what the specification expects. The current
specification expects that the unload event handler is never fired, and the
test passes whether or not it is fired.
* `pageshow` and `pagehide` behaviors during prerendering is clearly defined
in the specification. This test just checks current behaviors.
(https://crbug.com/1222551)
-->
<title>unload event handlers</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/unload-utils.js"></script>
<script>
promise_test(async t => {
const gotMessages = waitChannelMessage('Done');
const url = 'resources/unload-on-prerender-main-frame-navigation.html';
window.open(url, '_blank', 'noopener');
const result = await gotMessages;

const expected = [
// If `optional` is specified as true, that entry may not appear.
{ message: 'load start' },
{ message: 'load prerendering in prerendering' },
{ message: 'request fallback' },
// TODO(https://crbug.com/1200241): `pagehide` and `unload` may not run
// sometimes for unknown reason. Clarify the reason and fix it.
{ message: 'pagehide main-frame in prerendering', optional: true },
{ message: 'unload main-frame in prerendering', optional: true },
{ message: 'load prerendering' },
{ message: 'pagehide main-frame' },
{ message: 'visibilitychange main-frame' },
{ message: 'unload main-frame' },
{ message: 'load another-page' },
{ message: 'Done' },
];
let offset = 0;
assert_less_than_equal(result.length, expected.length);
for (let i = 0; i < expected.length; ++i) {
assert_less_than(offset, result.length);
if (expected[i].optional && expected[i].message != result[offset])
continue;
assert_equals(result[offset], expected[i].message, `messages${offset}`);
offset++;
}
assert_equals(offset, result.length);
}, 'unload on main frame navigation to cancel prerendering');
</script>

0 comments on commit 13f34cf

Please sign in to comment.