Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 1 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /speculation-rules/prerender/protocol-handler-register.https.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<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/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>
function getNextWindowMessageFromFrame(frame) {
return new Promise(resolve => {
window.addEventListener('message', event => {
if (event.source === frame.contentWindow) {
resolve(event.data);
}
});
});
}
promise_setup(async () => {
assertSpeculationRulesIsSupported()
await test_driver.set_rph_registration_mode('autoAccept');
await test_driver.bless('handler registration');
});
// The overall idea for this test is:
// 1. Register a protocol handler for a custom URI scheme to target 1 (initial).
// 2. Create a prerendered page that registers the same custom URI scheme to
// target 2 (modified). But the registration will defer until after activation.
// 3. Navigate an iframe to the custom URI scheme. It should go to target 1,
// because the deferred registration hasn't yet been applied.
// 4. Activate the prerendered page. This should run the deferred registration.
// 5. Navigate the iframe to the custom URI scheme again. It should go to
// target 2.
promise_test(async t => {
const customUrlScheme = 'web+wptrphtest';
function getProtocolHandlerUrlTemplate(id) {
return new URL(
`resources/protocol-handler.html?id=${id}&s=%s`, location.href).href;
}
const initialUrlTemplate = getProtocolHandlerUrlTemplate('initial');
const modifiedUrlTemplate = getProtocolHandlerUrlTemplate('modified');
// To start we register the initial protocol handler. When there is nothing
// registered for a custom URI scheme, and we navigate to it, there's no
// good event to tell us that the navigation failed. So instead we
// have an initial handler so we can tell that the modified protocol handler
// hasn't been registered yet.
t.add_cleanup(() => {
navigator.unregisterProtocolHandler(
customUrlScheme, initialUrlTemplate);
});
navigator.registerProtocolHandler(customUrlScheme, initialUrlTemplate);
// Create a prerender page that attempts to register an invalid scheme.
const {exec, activate} = await create_prerendered_page(t);
t.add_cleanup(() => {
navigator.unregisterProtocolHandler(
customUrlScheme, modifiedUrlTemplate);
});
// First register protocol handler during prerender
const result = await exec(
(customUrlScheme, modifiedUrlTemplate) => {
try {
navigator.registerProtocolHandler(
customUrlScheme, modifiedUrlTemplate);
} catch (registerProtocolHandlerException) {
return 'registerProtocolHandler failed with \''
+ registerProtocolHandlerException.name + '\'';
}
return 'success';
}, [customUrlScheme, modifiedUrlTemplate]);
assert_equals(result, 'success',
'registerProtocolHandler should succeed.');
// Next create the iframe that we will navigate to the custom URI scheme so
// we can validate that the prerenderer registration hasn't yet been applied.
const frame = await with_iframe('about:blank');
// Navigate to the custom URI scheme. Even though the prerendered page
// registered a handler, registration shouldn't happen until after activation.
// So this navigation should go to the initial handler.
const beforeActivationMessagePromise = getNextWindowMessageFromFrame(frame);
frame.src = `${customUrlScheme}:1`;
assert_equals((await beforeActivationMessagePromise).id, 'initial',
'Until activation, the initial handler should be registered.');
// Activate the prerendered page. This should run the deferred registration.
await activate();
// Now we listen for messages and again navigate to the custom URI scheme
// and by now the prerenderer registration should have applied and we should
// get the modified handler's id.
const afterActivationMessagePromise = getNextWindowMessageFromFrame(frame);
frame.src = `${customUrlScheme}:2`;
assert_equals((await afterActivationMessagePromise).id, 'modified',
'After activation, the modified handler should be registered.');
}, 'prerendering page registerProtocolHandler call defers registration until activation.');
</script>