test_multi_sharedWorker_lifetimes_bfcache.html (6083B)
1 <!-- 2 Any copyright is dedicated to the Public Domain. 3 http://creativecommons.org/publicdomain/zero/1.0/ 4 --> 5 <!DOCTYPE HTML> 6 <html> 7 <head> 8 <title>Test for SharedWorker</title> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> 11 <script class="testbody" type="text/javascript"> 12 "use strict"; 13 const windowRelativeURL = "multi_sharedWorker_frame_bfcache.html"; 14 // This suffix will be used as a search query parameter when we are 15 // navigating from navigate.html to the multi_sharedWorker_frame_bfcache 16 // page again. Since we are not using history.back() we are not loading 17 // that page from bfcache, but instead loading it anew, while the page 18 // we loaded initially stays in bfcache. In order to not kick out the 19 // page that is currently in the bfcache, we need to use a different 20 // BroadcastChannel. So we use search query param as part of 21 // BroadcastChannel's name. 22 const suffix = "?3"; 23 const storedData = "0123456789abcdefghijklmnopqrstuvwxyz"; 24 var bc, bc2, bc3; 25 SimpleTest.waitForExplicitFinish(); 26 27 28 function postToWorker(aBc, workerMessage) { 29 aBc.postMessage({command: "postToWorker", workerMessage}); 30 } 31 32 let testGenerator = (function*() { 33 34 bc = new BroadcastChannel("bugSharedWorkerLiftetime"); 35 bc3 = new BroadcastChannel("bugSharedWorkerLiftetime" + suffix); 36 bc.onmessage = (event) => { 37 var msg = event.data; 38 var command = msg.command; 39 if (command == "debug") { 40 info(msg.message); 41 } else if (command == "fromWorker" || command == "loaded") { 42 sendToGenerator(msg.workerMessage); 43 } 44 } 45 bc3.onmessage = (event) => { 46 var msg = event.data; 47 var command = msg.command; 48 if (command == "finished") { 49 bc.close(); 50 bc3.close(); 51 bc2.close(); 52 SimpleTest.finish(); 53 } else if (command == "debug") { 54 info(msg.message); 55 } else if (command == "fromWorker" || command == "loaded") { 56 sendToGenerator(msg.workerMessage); 57 } 58 } 59 bc2 = new BroadcastChannel("navigate"); 60 bc2.onmessage = (event) => { 61 if (event.data.command == "loaded") { 62 sendToGenerator(); 63 } 64 } 65 66 // Open the window 67 window.open(windowRelativeURL, "testWin", "noopener"); 68 yield undefined; 69 70 postToWorker(bc, { command: "retrieve" }); 71 72 var msg = yield undefined; 73 is(msg.type, "result", "Got a result message"); 74 is(msg.data, undefined, "No data stored"); 75 76 postToWorker(bc, { command: "store", data: storedData }); 77 postToWorker(bc, { command: "retrieve" }); 78 79 msg = yield undefined; 80 is(msg.type, "result", "Got a result message"); 81 is(msg.data, storedData, "Got stored data"); 82 83 84 // Navigate when the bfcache is enabled. 85 info("Navigating to a different page"); 86 bc.postMessage({command: "navigate", location: "navigate.html"}); 87 yield undefined; 88 89 for (let i = 0; i < 3; i++) { 90 info("Running GC"); 91 SpecialPowers.exactGC(sendToGenerator); 92 yield undefined; 93 94 // It seems using SpecialPowers.executeSoon() would make the 95 // entryGlobal being the BrowserChildGlobal (and that would make the 96 // baseURI in the location assignment below being incorrect); 97 // setTimeout on the otherhand ensures the entryGlobal is this 98 // window. 99 info("Waiting the event queue to clear"); 100 setTimeout(sendToGenerator, 0); 101 yield undefined; 102 } 103 104 info("Navigating to " + windowRelativeURL); 105 bc2.postMessage({command: "navigate", location: windowRelativeURL + suffix}); 106 yield undefined; 107 108 postToWorker(bc3, { command: "retrieve" }); 109 110 msg = yield undefined; 111 is(msg.type, "result", "Got a result message"); 112 is(msg.data, storedData, "Still have data stored"); 113 114 bc3.postMessage({command: "finish"}); 115 })(); 116 117 let sendToGenerator = testGenerator.next.bind(testGenerator); 118 119 function runTest() { 120 if (isXOrigin) { 121 // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5) 122 // Acquire storage access permission here so that the BroadcastChannel used to 123 // communicate with the opened windows works in xorigin tests. Otherwise, 124 // the iframe containing this page is isolated from first-party storage access, 125 // which isolates BroadcastChannel communication. 126 SpecialPowers.wrap(document).notifyUserGestureActivation(); 127 SpecialPowers.pushPermissions([{'type': 'storageAccessAPI', 'allow': 1, 'context': document}], () =>{ 128 SpecialPowers.wrap(document).requestStorageAccess().then(() => { 129 // If Fission is disabled, the pref is no-op. 130 SpecialPowers.pushPrefEnv({set: [ 131 ["fission.bfcacheInParent", true], 132 ["privacy.partition.always_partition_third_party_non_cookie_storage", false], 133 ]}, () => { 134 testGenerator.next(); 135 }); 136 }).then(() => { 137 SpecialPowers.removePermission("3rdPartyStorage^http://mochi.test:8888", "http://mochi.xorigin-test:8888"); 138 }); 139 }); 140 } else { 141 // If Fission is disabled, the pref is no-op. 142 SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => { 143 testGenerator.next(); 144 }); 145 } 146 } 147 </script> 148 </head> 149 <body onload="runTest()"> 150 </body> 151 </html>