protocol-handler-register.https.html (4600B)
1 <!DOCTYPE html> 2 <meta name="timeout" content="long"> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="/resources/testdriver.js"></script> 6 <script src="/resources/testdriver-vendor.js"></script> 7 <script src="/common/utils.js"></script> 8 <script src="/common/dispatcher/dispatcher.js"></script> 9 <script src="../resources/utils.js"></script> 10 <script src="resources/utils.js"></script> 11 <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script> 12 13 <script> 14 function getNextWindowMessageFromFrame(frame) { 15 return new Promise(resolve => { 16 window.addEventListener('message', event => { 17 if (event.source === frame.contentWindow) { 18 resolve(event.data); 19 } 20 }); 21 }); 22 } 23 24 promise_setup(async () => { 25 assertSpeculationRulesIsSupported() 26 await test_driver.set_rph_registration_mode('autoAccept'); 27 await test_driver.bless('handler registration'); 28 }); 29 30 // The overall idea for this test is: 31 // 1. Register a protocol handler for a custom URI scheme to target 1 (initial). 32 // 2. Create a prerendered page that registers the same custom URI scheme to 33 // target 2 (modified). But the registration will defer until after activation. 34 // 3. Navigate an iframe to the custom URI scheme. It should go to target 1, 35 // because the deferred registration hasn't yet been applied. 36 // 4. Activate the prerendered page. This should run the deferred registration. 37 // 5. Navigate the iframe to the custom URI scheme again. It should go to 38 // target 2. 39 promise_test(async t => { 40 const customUrlScheme = 'web+wptrphtest'; 41 function getProtocolHandlerUrlTemplate(id) { 42 return new URL( 43 `resources/protocol-handler.html?id=${id}&s=%s`, location.href).href; 44 } 45 46 const initialUrlTemplate = getProtocolHandlerUrlTemplate('initial'); 47 const modifiedUrlTemplate = getProtocolHandlerUrlTemplate('modified'); 48 49 // To start we register the initial protocol handler. When there is nothing 50 // registered for a custom URI scheme, and we navigate to it, there's no 51 // good event to tell us that the navigation failed. So instead we 52 // have an initial handler so we can tell that the modified protocol handler 53 // hasn't been registered yet. 54 t.add_cleanup(() => { 55 navigator.unregisterProtocolHandler( 56 customUrlScheme, initialUrlTemplate); 57 }); 58 navigator.registerProtocolHandler(customUrlScheme, initialUrlTemplate); 59 60 // Create a prerender page that attempts to register an invalid scheme. 61 const {exec, activate} = await create_prerendered_page(t); 62 63 t.add_cleanup(() => { 64 navigator.unregisterProtocolHandler( 65 customUrlScheme, modifiedUrlTemplate); 66 }); 67 // First register protocol handler during prerender 68 const result = await exec( 69 (customUrlScheme, modifiedUrlTemplate) => { 70 try { 71 navigator.registerProtocolHandler( 72 customUrlScheme, modifiedUrlTemplate); 73 } catch (registerProtocolHandlerException) { 74 return 'registerProtocolHandler failed with \'' 75 + registerProtocolHandlerException.name + '\''; 76 } 77 return 'success'; 78 }, [customUrlScheme, modifiedUrlTemplate]); 79 80 assert_equals(result, 'success', 81 'registerProtocolHandler should succeed.'); 82 83 // Next create the iframe that we will navigate to the custom URI scheme so 84 // we can validate that the prerenderer registration hasn't yet been applied. 85 const frame = await with_iframe('about:blank'); 86 87 // Navigate to the custom URI scheme. Even though the prerendered page 88 // registered a handler, registration shouldn't happen until after activation. 89 // So this navigation should go to the initial handler. 90 const beforeActivationMessagePromise = getNextWindowMessageFromFrame(frame); 91 frame.src = `${customUrlScheme}:1`; 92 assert_equals((await beforeActivationMessagePromise).id, 'initial', 93 'Until activation, the initial handler should be registered.'); 94 95 // Activate the prerendered page. This should run the deferred registration. 96 await activate(); 97 98 // Now we listen for messages and again navigate to the custom URI scheme 99 // and by now the prerenderer registration should have applied and we should 100 // get the modified handler's id. 101 const afterActivationMessagePromise = getNextWindowMessageFromFrame(frame); 102 frame.src = `${customUrlScheme}:2`; 103 assert_equals((await afterActivationMessagePromise).id, 'modified', 104 'After activation, the modified handler should be registered.'); 105 }, 'prerendering page registerProtocolHandler call defers registration until activation.'); 106 107 </script>