browser_aboutNetError_trr.js (5493B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // See bug 1831731. This test should not actually try to create a connection to 7 // the real DoH endpoint. But that may happen when clearing the proxy type, and 8 // sometimes even in the next test. 9 // To prevent that we override the IP to a local address. 10 Cc["@mozilla.org/network/native-dns-override;1"] 11 .getService(Ci.nsINativeDNSResolverOverride) 12 .addIPOverride("mozilla.cloudflare-dns.com", "127.0.0.1"); 13 14 let oldProxyType = Services.prefs.getIntPref("network.proxy.type"); 15 function resetPrefs() { 16 Services.prefs.clearUserPref("network.trr.mode"); 17 Services.prefs.clearUserPref("network.dns.native-is-localhost"); 18 Services.prefs.setIntPref("network.proxy.type", oldProxyType); 19 } 20 21 async function loadErrorPage() { 22 Services.prefs.setBoolPref("network.dns.native-is-localhost", true); 23 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY); 24 // We need to disable proxy, otherwise TRR isn't used for name resolution. 25 Services.prefs.setIntPref("network.proxy.type", 0); 26 registerCleanupFunction(resetPrefs); 27 28 let browser; 29 let pageLoaded; 30 await BrowserTestUtils.openNewForegroundTab( 31 gBrowser, 32 () => { 33 gBrowser.selectedTab = BrowserTestUtils.addTab( 34 gBrowser, 35 "https://does-not-exist.test" 36 ); 37 browser = gBrowser.selectedBrowser; 38 pageLoaded = BrowserTestUtils.waitForErrorPage(browser); 39 }, 40 false 41 ); 42 43 info("Loading and waiting for the net error"); 44 await pageLoaded; 45 return browser; 46 } 47 48 // This test makes sure that the Add exception button only shows up 49 // when the skipReason indicates that the domain could not be resolved. 50 // If instead there is a problem with the TRR connection, then we don't 51 // show the exception button. 52 add_task(async function exceptionButtonTRROnly() { 53 let browser = await loadErrorPage(); 54 55 await SpecialPowers.spawn(browser, [], function () { 56 const doc = content.document; 57 ok( 58 doc.documentURI.startsWith("about:neterror"), 59 "Should be showing error page" 60 ); 61 62 const titleEl = doc.querySelector(".title-text"); 63 const actualDataL10nID = titleEl.getAttribute("data-l10n-id"); 64 is( 65 actualDataL10nID, 66 "dnsNotFound-title", 67 "Correct error page title is set" 68 ); 69 70 let trrExceptionButton = doc.getElementById("trrExceptionButton"); 71 Assert.equal( 72 trrExceptionButton.hidden, 73 true, 74 "Exception button should be hidden for TRR service failures" 75 ); 76 }); 77 78 BrowserTestUtils.removeTab(gBrowser.selectedTab); 79 resetPrefs(); 80 }); 81 82 add_task(async function TRROnlyExceptionButtonTelemetry() { 83 // Clear everything. 84 Services.telemetry.clearEvents(); 85 await TestUtils.waitForCondition(() => { 86 let events = Services.telemetry.snapshotEvents( 87 Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, 88 true 89 ).content; 90 return !events || !events.length; 91 }); 92 93 let browser = await loadErrorPage(); 94 95 await SpecialPowers.spawn(browser, [], function () { 96 const doc = content.document; 97 ok( 98 doc.documentURI.startsWith("about:neterror"), 99 "Should be showing error page" 100 ); 101 }); 102 103 let loadEvent = await TestUtils.waitForCondition(() => { 104 let events = Services.telemetry.snapshotEvents( 105 Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, 106 true 107 ).content; 108 return events?.find(e => e[1] == "security.doh.neterror" && e[2] == "load"); 109 }, "recorded telemetry for the load"); 110 111 loadEvent.shift(); 112 Assert.deepEqual(loadEvent, [ 113 "security.doh.neterror", 114 "load", 115 "dohwarning", 116 "TRROnlyFailure", 117 { 118 mode: "3", 119 provider_key: "mozilla.cloudflare-dns.com", 120 skip_reason: "TRR_UNKNOWN_CHANNEL_FAILURE", 121 }, 122 ]); 123 124 await SpecialPowers.spawn(browser, [], function () { 125 const doc = content.document; 126 let buttons = ["neterrorTryAgainButton", "trrSettingsButton"]; 127 for (let buttonId of buttons) { 128 let button = doc.getElementById(buttonId); 129 button.click(); 130 } 131 }); 132 133 // Since we click TryAgain, make sure the error page is loaded again. 134 await BrowserTestUtils.waitForErrorPage(browser); 135 136 is( 137 gBrowser.tabs.length, 138 3, 139 "Should open about:preferences#privacy-doh in another tab" 140 ); 141 142 let clickEvents = await TestUtils.waitForCondition( 143 () => { 144 let events = Services.telemetry.snapshotEvents( 145 Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, 146 true 147 ).content; 148 return events?.filter( 149 e => e[1] == "security.doh.neterror" && e[2] == "click" 150 ); 151 }, 152 "recorded telemetry for clicking buttons", 153 500, 154 100 155 ); 156 157 let firstEvent = clickEvents[0]; 158 firstEvent.shift(); // remove timestamp 159 Assert.deepEqual(firstEvent, [ 160 "security.doh.neterror", 161 "click", 162 "try_again_button", 163 "TRROnlyFailure", 164 { 165 mode: "3", 166 provider_key: "mozilla.cloudflare-dns.com", 167 skip_reason: "TRR_UNKNOWN_CHANNEL_FAILURE", 168 }, 169 ]); 170 171 let secondEvent = clickEvents[1]; 172 secondEvent.shift(); // remove timestamp 173 Assert.deepEqual(secondEvent, [ 174 "security.doh.neterror", 175 "click", 176 "settings_button", 177 "TRROnlyFailure", 178 { 179 mode: "3", 180 provider_key: "mozilla.cloudflare-dns.com", 181 skip_reason: "TRR_UNKNOWN_CHANNEL_FAILURE", 182 }, 183 ]); 184 185 BrowserTestUtils.removeTab(gBrowser.tabs[2]); 186 BrowserTestUtils.removeTab(gBrowser.tabs[1]); 187 resetPrefs(); 188 });