browser_privatebrowsing_about.js (9627B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 ChromeUtils.defineESModuleGetters(this, { 6 UrlbarUtils: "moz-src:///browser/components/urlbar/UrlbarUtils.sys.mjs", 7 }); 8 9 ChromeUtils.defineLazyGetter(this, "UrlbarTestUtils", () => { 10 const { UrlbarTestUtils: module } = ChromeUtils.importESModule( 11 "resource://testing-common/UrlbarTestUtils.sys.mjs" 12 ); 13 module.init(this); 14 return module; 15 }); 16 17 /** 18 * Clicks the given link and checks this opens the given URI in the new tab. 19 * 20 * This function does not return to the previous page. 21 */ 22 async function testLinkOpensUrl({ win, tab, elementId, expectedUrl }) { 23 let loadedPromise = BrowserTestUtils.waitForNewTab(win.gBrowser, url => 24 url.startsWith(expectedUrl) 25 ); 26 await SpecialPowers.spawn(tab, [elementId], async function (elemId) { 27 content.document.getElementById(elemId).click(); 28 }); 29 await loadedPromise; 30 is( 31 win.gBrowser.selectedBrowser.currentURI.spec, 32 expectedUrl, 33 `Clicking ${elementId} opened ${expectedUrl} in the same tab.` 34 ); 35 } 36 37 let expectedEngineAlias; 38 let expectedIconURL; 39 40 add_setup(async function () { 41 await SpecialPowers.pushPrefEnv({ 42 set: [ 43 ["browser.search.separatePrivateDefault", true], 44 // Enable suggestions in this test. Otherwise, the behaviour of the 45 // content search box changes. 46 ["browser.search.suggest.enabled", true], 47 ], 48 }); 49 50 const originalPrivateDefault = await Services.search.getDefaultPrivate(); 51 // We have to use a built-in engine as we are currently hard-coding the aliases. 52 const privateEngine = await Services.search.getEngineByName("DuckDuckGo"); 53 await Services.search.setDefaultPrivate( 54 privateEngine, 55 Ci.nsISearchService.CHANGE_REASON_UNKNOWN 56 ); 57 expectedEngineAlias = privateEngine.aliases[0]; 58 expectedIconURL = await privateEngine.getIconURL(); 59 60 registerCleanupFunction(async () => { 61 await Services.search.setDefaultPrivate( 62 originalPrivateDefault, 63 Ci.nsISearchService.CHANGE_REASON_UNKNOWN 64 ); 65 }); 66 }); 67 68 /** 69 * Tests the private-browsing-myths link in "about:privatebrowsing". 70 */ 71 add_task(async function test_myths_link() { 72 Services.prefs.setCharPref("app.support.baseURL", "https://example.com/"); 73 registerCleanupFunction(function () { 74 Services.prefs.clearUserPref("app.support.baseURL"); 75 }); 76 77 let { win, tab } = await openAboutPrivateBrowsing(); 78 79 await testLinkOpensUrl({ 80 win, 81 tab, 82 elementId: "private-browsing-myths", 83 expectedUrl: "https://example.com/private-browsing-myths", 84 }); 85 86 await BrowserTestUtils.closeWindow(win); 87 }); 88 89 async function urlBarHasHiddenFocus(win) { 90 return TestUtils.waitForCondition(() => { 91 return win.gURLBar.focused && !win.gURLBar.hasAttribute("focused"); 92 }, "Urlbar has hidden focus"); 93 } 94 95 function urlBarHasNormalFocus(win) { 96 return win.gURLBar.hasAttribute("focused"); 97 } 98 99 /** 100 * Tests that we have the correct icon displayed. 101 */ 102 add_task(async function test_search_icon() { 103 let { win, tab } = await openAboutPrivateBrowsing(); 104 105 await SpecialPowers.spawn(tab, [expectedIconURL], async function (iconURL) { 106 let computedStyle = content.window.getComputedStyle(content.document.body); 107 await ContentTaskUtils.waitForCondition( 108 () => 109 computedStyle 110 .getPropertyValue("--newtab-search-icon") 111 .startsWith("url"), 112 "Search Icon should get set." 113 ); 114 115 if (iconURL.startsWith("blob:")) { 116 // We don't check the data here as `browser_contentSearch.js` performs 117 // those checks. 118 Assert.ok( 119 computedStyle 120 .getPropertyValue("--newtab-search-icon") 121 .startsWith("url(blob:"), 122 "Should have a blob URL for the logo" 123 ); 124 } else { 125 Assert.equal( 126 computedStyle.getPropertyValue("--newtab-search-icon"), 127 `url(${iconURL})`, 128 "Should have the correct icon URL for the logo" 129 ); 130 } 131 }); 132 133 await BrowserTestUtils.closeWindow(win); 134 }); 135 136 /** 137 * Tests the search hand-off on character keydown in "about:privatebrowsing". 138 */ 139 add_task(async function test_search_handoff_on_keydown() { 140 let { win, tab } = await openAboutPrivateBrowsing(); 141 142 await SpecialPowers.spawn(tab, [], async function () { 143 let handoffUI = content.document.querySelector("content-search-handoff-ui"); 144 let btn = handoffUI.shadowRoot.querySelector(".search-handoff-button"); 145 btn.click(); 146 await handoffUI.updateComplete; 147 ok( 148 handoffUI.hasAttribute("fakefocus"), 149 "in-content search has focus styles" 150 ); 151 }); 152 await urlBarHasHiddenFocus(win); 153 154 // Expect two searches, one to enter search mode and then another in search 155 // mode. 156 let searchPromise = UrlbarTestUtils.promiseSearchComplete(win); 157 158 await new Promise(r => EventUtils.synthesizeKey("f", {}, win, r)); 159 await SpecialPowers.spawn(tab, [], async function () { 160 ok( 161 content.document 162 .querySelector("content-search-handoff-ui") 163 .hasAttribute("disabled"), 164 "in-content search is disabled" 165 ); 166 }); 167 await searchPromise; 168 ok(urlBarHasNormalFocus(win), "Urlbar has normal focus"); 169 is(win.gURLBar.value, "f", "url bar has search text"); 170 171 // Close the popup. 172 await UrlbarTestUtils.promisePopupClose(win); 173 174 // Hitting ESC should reshow the in-content search 175 await new Promise(r => EventUtils.synthesizeKey("KEY_Escape", {}, win, r)); 176 await SpecialPowers.spawn(tab, [], async function () { 177 ok( 178 !content.document 179 .querySelector("content-search-handoff-ui") 180 .hasAttribute("disabled"), 181 "in-content search is not disabled" 182 ); 183 }); 184 185 await BrowserTestUtils.closeWindow(win); 186 }); 187 188 /** 189 * Tests the search hand-off on composition start in "about:privatebrowsing". 190 */ 191 add_task(async function test_search_handoff_on_composition_start() { 192 let { win, tab } = await openAboutPrivateBrowsing(); 193 194 await SpecialPowers.spawn(tab, [], async function () { 195 let btn = content.document 196 .querySelector("content-search-handoff-ui") 197 .shadowRoot.querySelector(".search-handoff-button"); 198 btn.click(); 199 }); 200 await urlBarHasHiddenFocus(win); 201 await new Promise(r => 202 EventUtils.synthesizeComposition({ type: "compositionstart" }, win, r) 203 ); 204 ok(urlBarHasNormalFocus(win), "Urlbar has normal focus"); 205 206 await BrowserTestUtils.closeWindow(win); 207 }); 208 209 /** 210 * Tests the search hand-off on paste in "about:privatebrowsing". 211 */ 212 add_task(async function test_search_handoff_on_paste() { 213 let { win, tab } = await openAboutPrivateBrowsing(); 214 215 await SpecialPowers.spawn(tab, [], async function () { 216 content.document 217 .querySelector("content-search-handoff-ui") 218 .shadowRoot.querySelector(".search-handoff-button") 219 .click(); 220 }); 221 await urlBarHasHiddenFocus(win); 222 var helper = SpecialPowers.Cc[ 223 "@mozilla.org/widget/clipboardhelper;1" 224 ].getService(SpecialPowers.Ci.nsIClipboardHelper); 225 helper.copyString("words"); 226 227 // Expect two searches, one to enter search mode and then another in search 228 // mode. 229 let searchPromise = UrlbarTestUtils.promiseSearchComplete(win); 230 231 await new Promise(r => 232 EventUtils.synthesizeKey("v", { accelKey: true }, win, r) 233 ); 234 235 await searchPromise; 236 237 ok(urlBarHasNormalFocus(win), "Urlbar has normal focus"); 238 is(win.gURLBar.value, "words", "Urlbar has search text"); 239 240 await BrowserTestUtils.closeWindow(win); 241 }); 242 243 /** 244 * Tests that handoff enters search mode when suggestions are disabled. 245 */ 246 add_task(async function test_search_handoff_search_mode() { 247 await SpecialPowers.pushPrefEnv({ 248 set: [["browser.urlbar.suggest.searches", false]], 249 }); 250 251 let { win, tab } = await openAboutPrivateBrowsing(); 252 253 await SpecialPowers.spawn(tab, [], async function () { 254 let handoffUI = content.document.querySelector("content-search-handoff-ui"); 255 let btn = handoffUI.shadowRoot.querySelector(".search-handoff-button"); 256 btn.click(); 257 await handoffUI.updateComplete; 258 ok( 259 handoffUI.hasAttribute("fakefocus"), 260 "in-content search has focus styles" 261 ); 262 }); 263 await urlBarHasHiddenFocus(win); 264 265 // Expect two searches, one to enter search mode and then another in search 266 // mode. 267 let searchPromise = UrlbarTestUtils.promiseSearchComplete(win); 268 269 await new Promise(r => EventUtils.synthesizeKey("f", {}, win, r)); 270 await SpecialPowers.spawn(tab, [], async function () { 271 await ContentTaskUtils.waitForCondition(() => { 272 return content.document 273 .querySelector("content-search-handoff-ui") 274 .hasAttribute("disabled"); 275 }, "in-content search is disabled"); 276 }); 277 await searchPromise; 278 ok(urlBarHasNormalFocus(win), "Urlbar has normal focus"); 279 await UrlbarTestUtils.assertSearchMode(win, { 280 engineName: "DuckDuckGo", 281 source: UrlbarUtils.RESULT_SOURCE.SEARCH, 282 entry: "handoff", 283 }); 284 is(win.gURLBar.value, "f", "url bar has search text"); 285 286 // Close the popup. 287 await UrlbarTestUtils.exitSearchMode(win); 288 await UrlbarTestUtils.promisePopupClose(win); 289 290 // Hitting ESC should reshow the in-content search 291 await new Promise(r => EventUtils.synthesizeKey("KEY_Escape", {}, win, r)); 292 await SpecialPowers.spawn(tab, [], async function () { 293 ok( 294 !content.document 295 .querySelector("content-search-handoff-ui") 296 .shadowRoot.querySelector(".search-handoff-button") 297 .hasAttribute("disabled"), 298 "in-content search is not disabled" 299 ); 300 }); 301 302 await BrowserTestUtils.closeWindow(win); 303 await SpecialPowers.popPrefEnv(); 304 });