Skip to content

Adding WebDriver BiDi API to prefetching tests #54177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 82 additions & 2 deletions resources/testdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,74 @@
/**
* `bluetooth <https://webbluetoothcg.github.io/web-bluetooth>`_ module.
*/
/*# RFC N: Add test-only APIs to improve the speculation rules prefetch tests
(*Note: N should be replaced by the PR number*)

## Summary

Add testdriver.js support for the [Prefetch Status Updated command].
This will allow tests to subscribe to the `speculation.prefetch_status_updated`
event and verify that the prefetch status is updated correctly.
[Prefetch Status Updated command]: *https://w3c.github.io/webdriver-bidi/#command-speculation-prefetch-status-updated* (not real yet)
*/
speculation: {
prefetch_status_updated: {
/**
* @typedef {object} PrefetchStatusUpdated
* `speculation.PrefetchStatusUpdateParameters <https://w3c.github.io --->
*/

/**
* Subscribes to the event. Events will be emitted only if
* there is a subscription for the event. This method does
* not add actual listeners. To listen to the event, use the
* `on` or `once` methods. The buffered events will be
* emitted before the command promise is resolved.
*
* @param {object} [params] Parameters for the subscription.
* @param {null|Array.<(Context)>} [params.contexts] The
* optional contexts parameter specifies which browsing
* contexts to subscribe to the event on. It should be
* either an array of Context objects, or null. If null, the
* event will be subscribed to globally. If omitted, the
* event will be subscribed to on the current browsing
* context.
* @returns {Promise<void>} Resolves when the subscription
* is successfully done.
*/
subscribe: async function(params = {}) {
assertBidiIsEnabled();
return window.test_driver_internal.bidi.speculation
.prefetch_status_updated.subscribe(params);
},
/**
* Adds an event listener for the event.
*
* @param {function(PrefetchStatusUpdate): void} callback The
* callback to be called when the event is emitted. The
* callback is called with the event object as a parameter.
* @returns {function(): void} A function that removes the
* added event listener when called.
*/
on: function(callback) {
assertBidiIsEnabled();
return window.test_driver_internal.bidi.speculation
.prefetch_status_updated.on(callback);
},

once: function() {
assertBidiIsEnabled();
return new Promise(resolve => {
const remove_handler =
window.test_driver_internal.bidi.speculation
.prefetch_status_updated.on(event => {
resolve(event);
remove_handler();
});
});
},
}
},
bluetooth: {
/**
* Handle a bluetooth device prompt with the given params. Matches the
Expand Down Expand Up @@ -665,7 +733,7 @@
*/
subscribe: async function(params = {}) {
assertBidiIsEnabled();
return window.test_driver_internal.bidi.bluetooth
return window.test_driver.bidi.bluetooth
.characteristic_event_generated.subscribe(params);
},
/**
Expand All @@ -679,7 +747,7 @@
*/
on: function(callback) {
assertBidiIsEnabled();
return window.test_driver_internal.bidi.bluetooth
return window.test_driver.bidi.bluetooth
.characteristic_event_generated.on(callback);
},
/**
Expand Down Expand Up @@ -2182,6 +2250,18 @@
in_automation: false,

bidi: {
speculation: {
prefetch_status_updated: {
async subscribe() {
throw new Error(
'bidi.speculation.prefetch_status_updated.subscribe is not implemented by testdriver-vendor.js');
},
on() {
throw new Error(
'bidi.speculation.prefetch_status_updated.on is not implemented by testdriver-vendor.js');
}
},
},
bluetooth: {
handle_request_device_prompt: function() {
throw new Error(
Expand Down
10 changes: 10 additions & 0 deletions speculation-rules/prefetch/anonymous-client.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@
<script src="/common/utils.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.sub.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>
<script>
setup(() => assertSpeculationRulesIsSupported());

promise_test(async t => {
let agent = await spawnWindow(t);
let nextUrl = agent.getExecutorURL({ hostname: CROSS_ORIGIN_HOST_THAT_WORKS_WITH_ACIWCO, page: 2 });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});

await agent.forceSinglePrefetch(nextUrl, { requires: ["anonymous-client-ip-when-cross-origin"] });
await agent.navigate(nextUrl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
<script src="/common/utils.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.sub.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>
<script>
setup(() => assertSpeculationRulesIsSupported());

// Test that Clear-Site-Data header value "prefetchCache" clears prefetch cache
promise_test(async t => {
let agent = await spawnWindow(t, { protocol: 'https' });
let nextUrl = agent.getExecutorURL({protocol: 'https', page: 2 });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});

await agent.forceSinglePrefetch(nextUrl);
await statusPromise;

// Open new window with url to clear cache data through Clear-Site-Data header.
// Ensure that the cache is cleared before the navigation.
Expand All @@ -37,7 +48,16 @@
promise_test(async t => {
let agent = await spawnWindow(t, { protocol: 'https' });
let nextUrl = agent.getExecutorURL({protocol: 'https', page: 2 });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});

await agent.forceSinglePrefetch(nextUrl);
await statusPromise;

// Open new window with url to clear cache data through Clear-Site-Data header.
// Ensure that the cache is cleared before the navigation.
Expand Down
12 changes: 11 additions & 1 deletion speculation-rules/prefetch/cookie-indices.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/subset-tests-by-key.js"></script>
<script src="/common/utils.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.sub.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>
<meta name="variant" content="?include=unchanged">
<meta name="variant" content="?include=changed">
<meta name="variant" content="?include=unchangedWithRedirect">
Expand All @@ -25,7 +26,16 @@
let agent = await spawnWindow(t);

let nextUrl = agent.getExecutorURL({ executor: "cookies.py", cookieindices: "1" });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});
await agent.forceSinglePrefetch(nextUrl);
await statusPromise; // Wait for prefetch status update

await agent.navigate(nextUrl);

assert_prefetched(await agent.getRequestHeaders());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/utils.js"></script>
Expand All @@ -24,8 +25,17 @@
assert_equals(response_cookies["type"], "navigate");

let nextUrl = agent.getExecutorURL({ executor, hostname: CROSS_ORIGIN_HOST_THAT_WORKS_WITH_ACIWCO, page: 2 });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});

await agent.forceSinglePrefetch(nextUrl, { requires: ["anonymous-client-ip-when-cross-origin"] });
await agent.forceSinglePrefetch(nextUrl);
await statusPromise; // Wait for prefetch status update
await agent.navigate(nextUrl);

response_cookies = await agent.getResponseCookies();
Expand Down
12 changes: 11 additions & 1 deletion speculation-rules/prefetch/cross-origin-cookies.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/utils.js"></script>
Expand All @@ -25,7 +26,16 @@
assert_equals(response_cookies["type"], "navigate");

let nextUrl = agent.getExecutorURL({ executor, hostname: get_host_info().NOTSAMESITE_HOST, page: 2 });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});

await agent.forceSinglePrefetch(nextUrl);
await statusPromise; // Wait for prefetch status update
await agent.navigate(nextUrl);

response_cookies = await agent.getResponseCookies();
Expand Down
11 changes: 10 additions & 1 deletion speculation-rules/prefetch/different-initiators-2.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="../resources/utils.js"></script>
Expand All @@ -22,8 +25,14 @@
// The Documents #2 and #4 are different, but the same RenderFrameHost is
// used before https://crbug.com/936696 is done.

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});
await win.forceSinglePrefetch(nextUrl);

await statusPromise; // Wait for prefetch status update
// Register a SW for `nextUrl` -- this is a trick to make the prefetched
// result to put in `PrefetchService::prefetches_ready_to_serve_` in
// Chromium implementation but actually not used by this navigation.
Expand Down
11 changes: 11 additions & 0 deletions speculation-rules/prefetch/different-initiators.sub.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<script src="../resources/utils.js"></script>
<script src="resources/utils.sub.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-extra.js"></script>

<meta name="variant" content="?cross-site-1">
<meta name="variant" content="?cross-site-2">
Expand All @@ -29,7 +31,16 @@

// Start speculation rules prefetch from `initiator1`.
const nextUrl = initiator1.getExecutorURL({ protocol: 'https', page: 2 });

await test_driver.bidi.speculation.prefetch_status_updated.subscribe();
let statusPromise = new Promise(resolve => {
test_driver.bidi.speculation.prefetch_status_updated.on(event => {
if (event && event.status !== undefined) resolve(event.status);
});
});

await initiator1.forceSinglePrefetch(nextUrl);
await statusPromise; // Wait for prefetch status update

// Register a SW for `nextUrl` -- this is a trick to make the prefetched
// result to put in `PrefetchService::prefetches_ready_to_serve_` in
Expand Down
Loading
Loading