test_suspend.html (5713B)
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 <meta charset="utf-8"> 9 <title>Test for DOM Worker Threads</title> 10 <script src="/tests/SimpleTest/SimpleTest.js"></script> 11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 12 </head> 13 <body> 14 <p id="display"></p> 15 <div id="content" style="display: none"></div> 16 <pre id="test"> 17 <script class="testbody" type="text/javascript"> 18 19 SimpleTest.waitForExplicitFinish(); 20 21 /** 22 * - main page tells subpage to call startWorker() 23 * - subpage starts worker 24 * - worker calls setInterval() and keeps calling postMessage() 25 * - onmessage(), as setup by the subpage, calls messageCallback 26 * - when messageCallback gets called more than 25 times 27 * - subpage gets navigated to blank.html 28 * - blank page posts message to main page, and main page calls suspendCallback() 29 * - suspendCallback() schedules waitInterval() to be fired off every second 30 * - after 5 times, it clears the interval and navigates subpage back 31 * - suspend_window subpage starts receiving messages again and 32 * does a final call to messageCallback() 33 * - finishTest() is called 34 */ 35 36 var lastCount; 37 38 var suspended = false; 39 var resumed = false; 40 var finished = false; 41 var suspendBlankPageCurrentlyShowing = false; 42 43 var interval; 44 var oldMessageCount; 45 var waitCount = 0; 46 47 var bcSuspendWindow, bcSuspendBlank; 48 49 function runTest() { 50 bcSuspendWindow = new BroadcastChannel("suspendWindow"); 51 bcSuspendWindow.onmessage = (msgEvent) => { 52 var msg = msgEvent.data; 53 var command = msg.command; 54 var data = msg.data; 55 if (command == "loaded") { 56 if (finished) { 57 return; 58 } 59 bcSuspendWindow.postMessage({command: "startWorker"}); 60 } else if (command == "messageCallback") { 61 messageCallback(data); 62 } else if (command == "errorCallback") { 63 errorCallback(data); 64 } else if (command == "finished") { 65 SimpleTest.finish(); 66 } 67 } 68 69 bcSuspendBlank = new BroadcastChannel("suspendBlank"); 70 bcSuspendBlank.onmessage = (msgEvent) => { 71 var msg = msgEvent.data; 72 var command = msg.command; 73 if (command == "loaded") { 74 suspendBlankPageCurrentlyShowing = true; 75 if (suspended) { 76 badOnloadCallback(); 77 } else { 78 suspendCallback(); 79 } 80 } else if (command == "pagehide") { 81 suspendBlankPageCurrentlyShowing = false; 82 } 83 } 84 85 // If Fission is disabled, the pref is no-op. 86 SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => { 87 window.open("suspend_window.html", "testWin", "noopener"); 88 }); 89 } 90 91 function finishTest() { 92 if (finished) { 93 return; 94 } 95 finished = true; 96 bcSuspendWindow.postMessage({command: "finish"}); 97 } 98 99 function waitInterval() { 100 if (finished) { 101 return; 102 } 103 ok(suspendBlankPageCurrentlyShowing, "correct page is showing"); 104 is(suspended, true, "Not suspended?"); 105 is(resumed, false, "Already resumed?!"); 106 is(lastCount, oldMessageCount, "Received a message while suspended!"); 107 if (++waitCount == 5) { 108 clearInterval(interval); 109 resumed = true; 110 bcSuspendBlank.postMessage({command: "navigateBack"}); 111 } 112 } 113 114 function badOnloadCallback() { 115 if (finished) { 116 return; 117 } 118 ok(false, "We don't want suspend_window.html to fire a new load event, we want it to come out of the bfcache!"); 119 finishTest(); 120 } 121 122 function suspendCallback() { 123 if (finished) { 124 return; 125 } 126 ok(suspendBlankPageCurrentlyShowing, "correct page is showing"); 127 is(suspended, false, "Already suspended?"); 128 is(resumed, false, "Already resumed?"); 129 suspended = true; 130 oldMessageCount = lastCount; 131 interval = setInterval(waitInterval, 1000); 132 } 133 134 function messageCallback(data) { 135 if (finished) { 136 return; 137 } 138 139 if (!suspended) { 140 ok(lastCount === undefined || lastCount == data - 1, 141 "Got good data, lastCount = " + lastCount + ", data = " + data); 142 lastCount = data; 143 if (lastCount == 25) { 144 bcSuspendWindow.postMessage({command: "navigate"}); 145 } 146 return; 147 } 148 149 ok(!suspendBlankPageCurrentlyShowing, "correct page is showing"); 150 is(resumed, true, "Got message before resumed!"); 151 is(lastCount, data - 1, "Missed a message, suspend failed!"); 152 finishTest(); 153 } 154 155 function errorCallback(data) { 156 if (finished) { 157 return; 158 } 159 ok(false, "testWin had an error: '" + data + "'"); 160 finishTest(); 161 } 162 163 if (isXOrigin) { 164 // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5) 165 // Acquire storage access permission here so that the BroadcastChannel used to 166 // communicate with the opened windows works in xorigin tests. Otherwise, 167 // the iframe containing this page is isolated from first-party storage access, 168 // which isolates BroadcastChannel communication. 169 SpecialPowers.wrap(document).notifyUserGestureActivation(); 170 SpecialPowers.pushPrefEnv({ 171 set: [["privacy.partition.always_partition_third_party_non_cookie_storage", false]], 172 }).then(() => { 173 SpecialPowers.pushPermissions([{'type': 'storageAccessAPI', 'allow': 1, 'context': document}], () =>{ 174 SpecialPowers.wrap(document).requestStorageAccess().then(() => { 175 runTest(); 176 }).then(() => { 177 SpecialPowers.removePermission("3rdPartyStorage^http://mochi.test:8888", "http://mochi.xorigin-test:8888"); 178 }); 179 }); 180 }); 181 } else { 182 runTest(); 183 } 184 185 </script> 186 </pre> 187 </body> 188 </html>