driver.js (5122B)
1 // Any copyright is dedicated to the Public Domain. 2 // http://creativecommons.org/publicdomain/zero/1.0/ 3 // 4 // This helper script exposes a runTests function that takes the name of a 5 // test script as its input argument and runs the test in three different 6 // contexts: 7 // 1. Regular Worker context 8 // 2. Service Worker context 9 // 3. Window context 10 // The function returns a promise which will get resolved once all tests 11 // finish. The testFile argument is the name of the test file to be run 12 // in the different contexts, and the optional order argument can be set 13 // to either "parallel" or "sequential" depending on how the caller wants 14 // the tests to be run. If this argument is not provided, the default is 15 // "both", which runs the tests in both modes. 16 // The caller of this function is responsible to call SimpleTest.finish 17 // when the returned promise is resolved. 18 19 function runTests(testFile, order) { 20 async function setupPrefs() { 21 // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5) 22 // Acquire storage access permission here so that the Cache API is avaialable 23 return SpecialPowers.pushPrefEnv({ 24 set: [ 25 ["dom.caches.testing.enabled", true], 26 ["dom.serviceWorkers.enabled", true], 27 ["dom.serviceWorkers.testing.enabled", true], 28 ["dom.serviceWorkers.exemptFromPerDomainMax", true], 29 ], 30 }); 31 } 32 33 // adapted from dom/indexedDB/test/helpers.js 34 function clearStorage() { 35 var clearUnpartitionedStorage = new Promise(function (resolve) { 36 var qms = SpecialPowers.Services.qms; 37 var principal = SpecialPowers.wrap(document).nodePrincipal; 38 var request = qms.clearStoragesForPrincipal(principal); 39 var cb = SpecialPowers.wrapCallback(resolve); 40 request.callback = cb; 41 }); 42 var clearPartitionedStorage = new Promise(function (resolve) { 43 var qms = SpecialPowers.Services.qms; 44 var principal = SpecialPowers.wrap(document).partitionedPrincipal; 45 var request = qms.clearStoragesForPrincipal(principal); 46 var cb = SpecialPowers.wrapCallback(resolve); 47 request.callback = cb; 48 }); 49 return Promise.all([clearUnpartitionedStorage, clearPartitionedStorage]); 50 } 51 52 function loadScript(script) { 53 return new Promise(function (resolve, reject) { 54 var s = document.createElement("script"); 55 s.src = script; 56 s.onerror = reject; 57 s.onload = resolve; 58 document.body.appendChild(s); 59 }); 60 } 61 62 function importDrivers() { 63 /* import-globals-from worker_driver.js */ 64 /* import-globals-from serviceworker_driver.js */ 65 return Promise.all([ 66 loadScript("worker_driver.js"), 67 loadScript("serviceworker_driver.js"), 68 ]); 69 } 70 71 function runWorkerTest() { 72 return workerTestExec(testFile); 73 } 74 75 function runServiceWorkerTest() { 76 if ( 77 navigator.serviceWorker == null && 78 SpecialPowers.getBoolPref("dom.cache.privateBrowsing.enabled") 79 ) { 80 return new Promise(function (resolve) { 81 resolve(true); 82 }); 83 } 84 85 return serviceWorkerTestExec(testFile); 86 } 87 88 function runFrameTest() { 89 return new Promise(function (resolve) { 90 var iframe = document.createElement("iframe"); 91 iframe.src = "frame.html"; 92 iframe.onload = function () { 93 var doc = iframe.contentDocument; 94 var s = doc.createElement("script"); 95 s.src = testFile; 96 window.addEventListener("message", function onMessage(event) { 97 if (event.data.context != "Window") { 98 return; 99 } 100 if (event.data.type == "finish") { 101 window.removeEventListener("message", onMessage); 102 resolve(); 103 } else if (event.data.type == "status") { 104 ok(event.data.status, event.data.context + ": " + event.data.msg); 105 } 106 }); 107 doc.body.appendChild(s); 108 }; 109 document.body.appendChild(iframe); 110 }); 111 } 112 113 SimpleTest.waitForExplicitFinish(); 114 115 if (typeof order == "undefined") { 116 order = "sequential"; // sequential by default, see bug 1143222. 117 // TODO: Make this "both" again. 118 } 119 120 ok( 121 order == "parallel" || order == "sequential" || order == "both", 122 "order argument should be valid" 123 ); 124 125 if (order == "both") { 126 info("Running tests in both modes; first: sequential"); 127 return runTests(testFile, "sequential").then(function () { 128 info("Running tests in parallel mode"); 129 return runTests(testFile, "parallel"); 130 }); 131 } 132 if (order == "sequential") { 133 return setupPrefs() 134 .then(importDrivers) 135 .then(runWorkerTest) 136 .then(clearStorage) 137 .then(runServiceWorkerTest) 138 .then(clearStorage) 139 .then(runFrameTest) 140 .then(clearStorage) 141 .catch(function (e) { 142 ok(false, "A promise was rejected during test execution: " + e); 143 }); 144 } 145 return setupPrefs() 146 .then(importDrivers) 147 .then(() => 148 Promise.all([runWorkerTest(), runServiceWorkerTest(), runFrameTest()]) 149 ) 150 .then(clearStorage) 151 .catch(function (e) { 152 ok(false, "A promise was rejected during test execution: " + e); 153 }); 154 }