mixedContentTest.js (6162B)
1 "use strict"; 2 3 /** 4 * Helper script for mixed content testing. It opens a new top-level window 5 * from a secure origin and '?runtest' query. That tells us to run the test 6 * body, function runTest(). Then we wait for call of finish(). On its first 7 * call it loads helper page 'backward.html' that immediately navigates 8 * back to the test secure test. This checks the bfcache. We got second call 9 * to onload and this time we call afterNavigationTest() function to let the 10 * test check security state after re-navigation back. Then we again wait for 11 * finish() call, that this time finishes completelly the test. 12 */ 13 14 // Tells the framework if to load the test in an insecure page (http://) 15 var loadAsInsecure = false; 16 // Set true to bypass the navigation forward/back test 17 var bypassNavigationTest = false; 18 // Set true to do forward/back navigation over an http:// page, test state leaks 19 var navigateToInsecure = false; 20 // Open the test in two separate windows, test requests sharing among windows 21 var openTwoWindows = false; 22 // Override the name of the test page to load, useful e.g. to prevent load 23 // of images or other content before the test starts; this is actually 24 // a 'redirect' to a different test page. 25 var testPage = ""; 26 // Assign a function to this variable to have a clean up at the end 27 var testCleanUp = null; 28 // Contains mixed active content that needs to load to run the test 29 var hasMixedActiveContent = false; 30 31 // Internal variables 32 var _windowCount = 0; 33 34 window.onload = async function onLoad() { 35 if (location.search == "?runtest") { 36 try { 37 if (history.length == 1) { 38 // Each test that includes this helper file is supposed to define 39 // runTest(). See the top level comment. 40 await runTest(); // eslint-disable-line no-undef 41 } else { 42 // Each test that includes this helper file is supposed to define 43 // afterNavigationTest(). See the top level comment. 44 await afterNavigationTest(); // eslint-disable-line no-undef 45 } 46 } catch (ex) { 47 ok(false, "Exception thrown during test: " + ex); 48 finish(); 49 } 50 } else { 51 window.addEventListener("message", onMessageReceived); 52 53 let secureTestLocation = loadAsInsecure 54 ? "http://example.com" 55 : "https://example.com"; 56 secureTestLocation += location.pathname; 57 if (testPage != "") { 58 let array = secureTestLocation.split("/"); 59 array.pop(); 60 array.push(testPage); 61 secureTestLocation = array.join("/"); 62 } 63 secureTestLocation += "?runtest"; 64 65 if (hasMixedActiveContent) { 66 SpecialPowers.pushPrefEnv( 67 { set: [["security.mixed_content.block_active_content", false]] }, 68 null 69 ); 70 } 71 if (openTwoWindows) { 72 _windowCount = 2; 73 window.open(secureTestLocation, "_new1", ""); 74 window.open(secureTestLocation, "_new2", ""); 75 } else { 76 _windowCount = 1; 77 window.open(secureTestLocation); 78 } 79 } 80 }; 81 82 function onMessageReceived(event) { 83 switch (event.data) { 84 // Indication of all test parts finish (from any of the frames) 85 case "done": 86 if (--_windowCount == 0) { 87 if (testCleanUp) { 88 testCleanUp(); 89 } 90 if (hasMixedActiveContent) { 91 SpecialPowers.popPrefEnv(null); 92 } 93 94 SimpleTest.finish(); 95 } 96 break; 97 98 // Any other message is an error or success message of a test. 99 default: 100 SimpleTest.ok(!event.data.match(/^FAILURE/), event.data); 101 break; 102 } 103 } 104 105 function postMsg(message) { 106 opener.postMessage(message, "http://mochi.test:8888"); 107 } 108 109 function finish() { 110 if (history.length == 1 && !bypassNavigationTest) { 111 window.setTimeout(() => { 112 window.location.assign( 113 navigateToInsecure 114 ? "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" 115 : "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" 116 ); 117 }, 0); 118 } else { 119 postMsg("done"); 120 window.close(); 121 } 122 } 123 124 function ok(a, message) { 125 if (!a) { 126 postMsg("FAILURE: " + message); 127 } else { 128 postMsg(message); 129 } 130 } 131 132 function is(a, b, message) { 133 if (a != b) { 134 postMsg(`FAILURE: ${message}, expected ${b} got ${a}`); 135 } else { 136 postMsg(`${message}, expected ${b} got ${a}`); 137 } 138 } 139 140 async function isSecurityState(expectedState, message, test) { 141 if (!test) { 142 test = ok; 143 } 144 145 let state = await SpecialPowers.getSecurityState(window); 146 147 let isInsecure = 148 state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_INSECURE; 149 let isBroken = 150 state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_BROKEN; 151 let isEV = 152 state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL; 153 154 let gotState = "secure"; 155 if (isInsecure) { 156 gotState = "insecure"; 157 } else if (isBroken) { 158 gotState = "broken"; 159 } else if (isEV) { 160 gotState = "EV"; 161 } 162 163 test( 164 gotState == expectedState, 165 (message || "") + ", expected " + expectedState + " got " + gotState 166 ); 167 168 switch (expectedState) { 169 case "insecure": 170 test( 171 isInsecure && !isBroken && !isEV, 172 "for 'insecure' excpected flags [1,0,0], " + (message || "") 173 ); 174 break; 175 case "broken": 176 test( 177 !isInsecure && isBroken && !isEV, 178 "for 'broken' expected flags [0,1,0], " + (message || "") 179 ); 180 break; 181 case "secure": 182 test( 183 !isInsecure && !isBroken && !isEV, 184 "for 'secure' expected flags [0,0,0], " + (message || "") 185 ); 186 break; 187 case "EV": 188 test( 189 !isInsecure && !isBroken && isEV, 190 "for 'EV' expected flags [0,0,1], " + (message || "") 191 ); 192 break; 193 default: 194 throw new Error("Invalid isSecurityState state"); 195 } 196 } 197 198 function waitForSecurityState(expectedState, callback) { 199 let roundsLeft = 200; // Wait for 20 seconds (=200*100ms) 200 let interval = window.setInterval(async () => { 201 await isSecurityState(expectedState, "", isok => { 202 if (isok) { 203 roundsLeft = 0; 204 } 205 }); 206 if (!roundsLeft--) { 207 window.clearInterval(interval); 208 callback(); 209 } 210 }, 100); 211 }