browser_net_security-state.js (3762B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Test that correct security state indicator appears depending on the security 8 * state. 9 */ 10 11 add_task(async function () { 12 // This test explicitly asserts some insecure domains. 13 await pushPref("dom.security.https_first", false); 14 15 const EXPECTED_SECURITY_STATES = { 16 "test1.example.com": "security-state-insecure", 17 "example.com": "security-state-secure", 18 "nocert.example.com": "security-state-broken", 19 localhost: "security-state-secure", 20 notlocalhost: "security-state-insecure", 21 }; 22 23 const { tab, monitor } = await initNetMonitor(CUSTOM_GET_URL, { 24 requestCount: 1, 25 }); 26 const { document, store, windowRequire } = monitor.panelWin; 27 const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); 28 29 store.dispatch(Actions.batchEnable(false)); 30 31 await performRequests(); 32 33 for (const subitemNode of Array.from( 34 document.querySelectorAll(".requests-list-column.requests-list-domain") 35 )) { 36 // Skip header 37 const icon = subitemNode.querySelector(".requests-security-state-icon"); 38 if (!icon) { 39 continue; 40 } 41 42 const domain = subitemNode.textContent; 43 info("Found a request to " + domain); 44 45 const classes = icon.classList; 46 const expectedClass = EXPECTED_SECURITY_STATES[domain]; 47 48 info("Classes of security state icon are: " + classes); 49 info("Security state icon is expected to contain class: " + expectedClass); 50 ok( 51 classes.contains(expectedClass), 52 "Icon contained the correct class name." 53 ); 54 } 55 56 return teardown(monitor); 57 58 /** 59 * A helper that performs requests to 60 * - https://nocert.example.com (broken) 61 * - https://example.com (secure) 62 * - http://test1.example.com (insecure) 63 * - http://localhost (local) 64 * and waits until NetworkMonitor has handled all packets sent by the server. 65 */ 66 async function performRequests() { 67 function executeRequests(count, url) { 68 return SpecialPowers.spawn( 69 tab.linkedBrowser, 70 [{ count, url }], 71 async function (args) { 72 content.wrappedJSObject.performRequests(args.count, args.url); 73 } 74 ); 75 } 76 77 let done = waitForNetworkEvents(monitor, 1); 78 info("Requesting a resource that has a certificate problem."); 79 await executeRequests(1, "https://nocert.example.com"); 80 81 // Wait for the request to complete before firing another request. Otherwise 82 // the request with security issues interfere with waitForNetworkEvents. 83 info("Waiting for request to complete."); 84 await done; 85 86 // Next perform a request over HTTP. If done the other way around the latter 87 // occasionally hangs waiting for event timings that don't seem to appear... 88 done = waitForNetworkEvents(monitor, 1); 89 info("Requesting a resource over HTTP."); 90 await executeRequests(1, "http://test1.example.com" + CORS_SJS_PATH); 91 await done; 92 93 done = waitForNetworkEvents(monitor, 1); 94 info("Requesting a resource over HTTPS."); 95 await executeRequests(1, "https://example.com" + CORS_SJS_PATH); 96 await done; 97 98 done = waitForNetworkEvents(monitor, 1); 99 info("Requesting a resource over HTTP to localhost."); 100 await executeRequests(1, "http://localhost" + CORS_SJS_PATH); 101 await done; 102 103 done = waitForNetworkEvents(monitor, 1); 104 info("Requesting a resource over HTTP to notlocalhost."); 105 await executeRequests(1, "http://notlocalhost" + CORS_SJS_PATH); 106 await done; 107 108 const expectedCount = Object.keys(EXPECTED_SECURITY_STATES).length; 109 is( 110 store.getState().requests.requests.length, 111 expectedCount, 112 expectedCount + " events logged." 113 ); 114 } 115 });