| // META: script=/common/dispatcher/dispatcher.js |
| // META: script=/common/get-host-info.sub.js |
| // META: script=/common/utils.js |
| // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js |
| // META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js |
| // META: script=/fetch/fetch-later/resources/fetch-later-helper.js |
| |
| 'use strict'; |
| |
| // NOTE: Due to the restriction of WPT runner, the following tests are all run |
| // with BackgroundSync off, which is different from some browsers, |
| // e.g. Chrome, default behavior, as the testing infra does not support enabling |
| // it. |
| |
| parallelPromiseTest(async t => { |
| const uuid = token(); |
| const url = generateSetBeaconURL(uuid); |
| // Sets no option to test the default behavior when a document enters BFCache. |
| const helper = new RemoteContextHelper(); |
| // Opens a window with noopener so that BFCache will work. |
| const rc1 = await helper.addWindow( |
| /*config=*/ null, /*options=*/ {features: 'noopener'}); |
| |
| // Creates a fetchLater request with default config in remote, which should |
| // only be sent on page discarded (not on entering BFCache). |
| await rc1.executeScript(url => { |
| fetchLater(url); |
| // Add a pageshow listener to stash the BFCache event. |
| window.addEventListener('pageshow', e => { |
| window.pageshowEvent = e; |
| }); |
| }, [url]); |
| // Navigates away to let page enter BFCache. |
| const rc2 = await rc1.navigateToNew(); |
| // Navigates back. |
| await rc2.historyBack(); |
| // Verifies the page was BFCached. |
| assert_true(await rc1.executeScript(() => { |
| return window.pageshowEvent.persisted; |
| })); |
| |
| // Theoretically, the request should still be pending thus 0 request received. |
| // However, 1 request is sent, as by default the WPT test runner, e.g. |
| // content_shell in Chromium, does not enable BackgroundSync permission, |
| // resulting in forcing request sending on every navigation. |
| await expectBeacon(uuid, {count: 1}); |
| }, `fetchLater() sends on page entering BFCache if BackgroundSync is off.`); |
| |
| parallelPromiseTest(async t => { |
| const uuid = token(); |
| const url = generateSetBeaconURL(uuid); |
| const helper = new RemoteContextHelper(); |
| // Opens a window with noopener so that BFCache will work. |
| const rc1 = await helper.addWindow( |
| /*config=*/ null, /*options=*/ {features: 'noopener'}); |
| |
| // When the remote is put into BFCached, creates a fetchLater request w/ |
| // activateAfter = 0s. It should be sent out immediately. |
| await rc1.executeScript(url => { |
| window.addEventListener('pagehide', e => { |
| if (e.persisted) { |
| fetchLater(url, {activateAfter: 0}); |
| } |
| }); |
| // Add a pageshow listener to stash the BFCache event. |
| window.addEventListener('pageshow', e => { |
| window.pageshowEvent = e; |
| }); |
| }, [url]); |
| // Navigates away to trigger request sending. |
| const rc2 = await rc1.navigateToNew(); |
| // Navigates back. |
| await rc2.historyBack(); |
| // Verifies the page was BFCached. |
| assert_true(await rc1.executeScript(() => { |
| return window.pageshowEvent.persisted; |
| })); |
| |
| // NOTE: In this case, it does not matter if BackgroundSync is on or off. |
| await expectBeacon(uuid, {count: 1}); |
| }, `Call fetchLater() when BFCached with activateAfter=0 sends immediately.`); |
| |
| parallelPromiseTest(async t => { |
| const uuid = token(); |
| const url = generateSetBeaconURL(uuid); |
| // Sets no option to test the default behavior when a document gets discarded |
| // on navigated away. |
| const helper = new RemoteContextHelper(); |
| // Opens a window without BFCache. |
| const rc1 = await helper.addWindow(); |
| |
| // Creates a fetchLater request in remote which should only be sent on |
| // navigating away. |
| await rc1.executeScript(url => { |
| fetchLater(url); |
| // Add a pageshow listener to stash the BFCache event. |
| window.addEventListener('pageshow', e => { |
| window.pageshowEvent = e; |
| }); |
| }, [url]); |
| // Navigates away to trigger request sending. |
| const rc2 = await rc1.navigateToNew(); |
| // Navigates back. |
| await rc2.historyBack(); |
| // Verifies the page was NOT BFCached. |
| assert_equals(undefined, await rc1.executeScript(() => { |
| return window.pageshowEvent; |
| })); |
| |
| // NOTE: In this case, it does not matter if BackgroundSync is on or off. |
| await expectBeacon(uuid, {count: 1}); |
| }, `fetchLater() sends on navigating away a page w/o BFCache.`); |
| |
| parallelPromiseTest(async t => { |
| const uuid = token(); |
| const url = generateSetBeaconURL(uuid); |
| // Sets no option to test the default behavior when a document gets discarded |
| // on navigated away. |
| const helper = new RemoteContextHelper(); |
| // Opens a window without BFCache. |
| const rc1 = await helper.addWindow(); |
| |
| // Creates 2 fetchLater requests in remote, and one of them is aborted |
| // immediately. The other one should only be sent right on navigating away. |
| await rc1.executeScript(url => { |
| const controller = new AbortController(); |
| fetchLater(url, {signal: controller.signal}); |
| fetchLater(url); |
| controller.abort(); |
| // Add a pageshow listener to stash the BFCache event. |
| window.addEventListener('pageshow', e => { |
| window.pageshowEvent = e; |
| }); |
| }, [url]); |
| // Navigates away to trigger request sending. |
| const rc2 = await rc1.navigateToNew(); |
| // Navigates back. |
| await rc2.historyBack(); |
| // Verifies the page was NOT BFCached. |
| assert_equals(undefined, await rc1.executeScript(() => { |
| return window.pageshowEvent; |
| })); |
| |
| // NOTE: In this case, it does not matter if BackgroundSync is on or off. |
| await expectBeacon(uuid, {count: 1}); |
| }, `fetchLater() does not send aborted request on navigating away a page w/o BFCache.`); |
| |
| parallelPromiseTest(async t => { |
| const uuid = token(); |
| const url = generateSetBeaconURL(uuid); |
| const options = {activateAfter: 60000}; |
| const helper = new RemoteContextHelper(); |
| // Opens a window with noopener so that BFCache will work. |
| const rc1 = await helper.addWindow( |
| /*config=*/ null, /*options=*/ {features: 'noopener'}); |
| |
| // Creates a fetchLater request in remote which should only be sent on |
| // navigating away. |
| await rc1.executeScript((url) => { |
| // Sets activateAfter = 1m to indicate the request should NOT be sent out |
| // immediately. |
| fetchLater(url, {activateAfter: 60000}); |
| // Adds a pageshow listener to stash the BFCache event. |
| window.addEventListener('pageshow', e => { |
| window.pageshowEvent = e; |
| }); |
| }, [url]); |
| // Navigates away to trigger request sending. |
| const rc2 = await rc1.navigateToNew(); |
| // Navigates back. |
| await rc2.historyBack(); |
| // Verifies the page was BFCached. |
| assert_true(await rc1.executeScript(() => { |
| return window.pageshowEvent.persisted; |
| })); |
| |
| // Theoretically, the request should still be pending thus 0 request received. |
| // However, 1 request is sent, as by default the WPT test runner, e.g. |
| // content_shell in Chromium, does not enable BackgroundSync permission, |
| // resulting in forcing request sending on every navigation, even if page is |
| // put into BFCache. |
| await expectBeacon(uuid, {count: 1}); |
| }, `fetchLater() with activateAfter=1m sends on page entering BFCache if BackgroundSync is off.`); |