client-url-creation-url.https.html (5131B)
1 <!DOCTYPE html> 2 <title>Service Worker: Client.url is Window creation URL tests</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="resources/test-helpers.sub.js"></script> 6 <script> 7 // These tests all validate that the Service Worker's Client.url property is 8 // correct for different types of Window client navigations. 9 // All test cases involve an iframe navigating in some manner and then 10 // the service worker validating that the Client.url property is correct. 11 12 // Waits for and returns the next postMessage from `frame` to this window. 13 function wait_for_message_from_frame(frame) { 14 return new Promise(resolve => { 15 const message_handler = e => { 16 if (e.source === frame.contentWindow) { 17 frame.removeEventListener('message', message_handler); 18 resolve(e.data); 19 } 20 }; 21 window.addEventListener('message', message_handler); 22 }); 23 } 24 25 // Returns a promise to get a client URL under the ServiceWorker's 26 // (client-url-creation-url-sw.js) control. `target` should be an active 27 // ServiceWorker to post message. We expect it to send back the client URL 28 // via the given channel. 29 function post_message_and_wait_for_response( 30 target, data) { 31 return new Promise(resolve => { 32 const channel = new MessageChannel(); 33 channel.port1.onmessage = e => { 34 resolve(e.data); 35 }; 36 target.postMessage( 37 {message: data, port: channel.port2}, 38 [channel.port2]); 39 }); 40 } 41 42 const SCOPE = 'resources/client-url-creation-url'; 43 const IFRAME_URL = SCOPE + '-iframe.html?step=1'; 44 45 // The test helper function implements a test case by 46 // using an iframe to navigate in various ways described by `navigation_kinds` 47 // and then validates the ServiceWorker Client.url property of the iframe 48 // against the provided `expected_client_url`. 49 // `navigation_kinds` is an array of strings each of which is one of the 50 // navigation actions supported by client-url-creation-url-iframe.html. 51 async function test_client_url_helper( 52 t, navigation_kinds, expected_client_url) { 53 const registration = await service_worker_unregister_and_register( 54 t, 'resources/client-url-creation-url-sw.js', SCOPE); 55 t.add_cleanup(_ => registration.unregister()); 56 await wait_for_state(t, registration.installing, 'activated'); 57 58 const frame = await with_iframe(IFRAME_URL); 59 t.add_cleanup(_ => frame.remove()); 60 const message = await wait_for_message_from_frame(frame); 61 assert_equals(message, 'done', 'iframe loaded successfully'); 62 63 for (let navigation_kind_idx = 0; 64 navigation_kind_idx < navigation_kinds.length; 65 ++navigation_kind_idx) { 66 const navigation_kind = navigation_kinds[navigation_kind_idx]; 67 68 frame.contentWindow.postMessage(navigation_kind); 69 const result = await wait_for_message_from_frame(frame); 70 assert_equals(result, 'done', 'iframe navigation successfully completed'); 71 } 72 73 const actual_client_url = await post_message_and_wait_for_response( 74 registration.active, "get_client_url"); 75 76 assert_equals( 77 actual_client_url, expected_client_url, 'Client.url should match'); 78 } 79 80 const EXPECTED_URL_STEP_1 = new URL( 81 './resources/client-url-creation-url-iframe.html?step=1', location).href; 82 const EXPECTED_URL_STEP_2 = new URL( 83 './resources/client-url-creation-url-iframe.html?step=2', location).href; 84 85 // Tests that perform navigations that don't create a new document 86 promise_test(async t => { 87 await test_client_url_helper(t, [], EXPECTED_URL_STEP_1); 88 }, 'No navigation creation URL is same as window URL'); 89 90 promise_test(async t => { 91 await test_client_url_helper(t, ['fragment'], EXPECTED_URL_STEP_1); 92 }, 'Fragment only navigation doesn\'t change creation URL'); 93 94 promise_test(async t => { 95 await test_client_url_helper(t, ['pushstate'], EXPECTED_URL_STEP_1); 96 }, 'Pushstate doesn\'t change creation URL'); 97 98 promise_test(async t => { 99 await test_client_url_helper(t, ['replacestate'], EXPECTED_URL_STEP_1); 100 }, 'Replacestate doesn\'t change creation URL'); 101 102 promise_test(async t => { 103 await test_client_url_helper( 104 t, ['pushstate', 'pushstate', 'back-within-same-document'], EXPECTED_URL_STEP_1); 105 }, 'Going back over pushstate to other pushstate via back'); 106 107 // Tests that perform navigations that create new document(s) 108 promise_test(async t => { 109 await test_client_url_helper(t, ['query'], EXPECTED_URL_STEP_2); 110 }, 'Query navigation changes creation URL'); 111 112 promise_test(async t => { 113 await test_client_url_helper(t, ['reload'], EXPECTED_URL_STEP_1); 114 }, 'Reloading doesn\'t change creation URL'); 115 116 promise_test(async t => { 117 await test_client_url_helper(t, ['pushstate', 'reload'], EXPECTED_URL_STEP_2); 118 }, 'Reloading pushstate URL changes creation URL'); 119 120 promise_test(async t => { 121 await test_client_url_helper( 122 t, ['query', 'pushstate', 'back-within-same-document'], EXPECTED_URL_STEP_2); 123 }, 'Going back over pushstate to creation URL'); 124 125 promise_test(async t => { 126 await test_client_url_helper( 127 t, ['query', 'query', 'back-cross-document'], EXPECTED_URL_STEP_2); 128 }, 'Going back to new document changes creation URL'); 129 </script>