browser_searchDefaultEngine.js (9647B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 const { SearchTestUtils } = ChromeUtils.importESModule( 5 "resource://testing-common/SearchTestUtils.sys.mjs" 6 ); 7 8 SearchTestUtils.init(this); 9 10 add_setup(async function () { 11 await SearchTestUtils.installSearchExtension({ 12 name: "engine1", 13 search_url: "https://example.com/engine1", 14 search_url_get_params: "search={searchTerms}", 15 }); 16 await SearchTestUtils.installSearchExtension({ 17 name: "engine2", 18 search_url: "https://example.com/engine2", 19 search_url_get_params: "search={searchTerms}", 20 }); 21 22 const defaultEngine = await Services.search.getDefault(); 23 const defaultPrivateEngine = await Services.search.getDefaultPrivate(); 24 25 registerCleanupFunction(async () => { 26 await Services.search.setDefault( 27 defaultEngine, 28 Ci.nsISearchService.CHANGE_REASON_UNKNOWN 29 ); 30 await Services.search.setDefaultPrivate( 31 defaultPrivateEngine, 32 Ci.nsISearchService.CHANGE_REASON_UNKNOWN 33 ); 34 }); 35 }); 36 37 add_task(async function test_openWithPrivateDefaultNotEnabledFirst() { 38 await SpecialPowers.pushPrefEnv({ 39 set: [ 40 ["browser.search.separatePrivateDefault.ui.enabled", false], 41 ["browser.search.separatePrivateDefault", false], 42 ], 43 }); 44 45 await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true }); 46 47 const doc = gBrowser.selectedBrowser.contentDocument; 48 const separateEngineCheckbox = doc.getElementById( 49 "browserSeparateDefaultEngine" 50 ).parentElement; 51 const privateDefaultDropdown = doc.getElementById("defaultPrivateEngine"); 52 53 Assert.ok( 54 separateEngineCheckbox.hidden, 55 "Should have hidden the separate search engine checkbox" 56 ); 57 Assert.ok( 58 separateEngineCheckbox.hidden && 59 separateEngineCheckbox.contains(privateDefaultDropdown), 60 "Should have hidden the private engine selection box" 61 ); 62 63 await SpecialPowers.pushPrefEnv({ 64 set: [["browser.search.separatePrivateDefault.ui.enabled", true]], 65 }); 66 67 Assert.ok( 68 !separateEngineCheckbox.hidden, 69 "Should have displayed the separate search engine checkbox" 70 ); 71 Assert.ok( 72 BrowserTestUtils.isVisible(privateDefaultDropdown), 73 "Private engine selection box should be visible" 74 ); 75 76 await SpecialPowers.pushPrefEnv({ 77 set: [["browser.search.separatePrivateDefault", true]], 78 }); 79 80 Assert.ok( 81 !separateEngineCheckbox.hidden, 82 "Should still be displaying the separate search engine checkbox" 83 ); 84 Assert.ok( 85 !privateDefaultDropdown.disabled, 86 "Private engine selection box should be enabled" 87 ); 88 89 gBrowser.removeCurrentTab(); 90 }); 91 92 add_task(async function test_openWithPrivateDefaultEnabledFirst() { 93 await SpecialPowers.pushPrefEnv({ 94 set: [ 95 ["browser.search.separatePrivateDefault.ui.enabled", true], 96 ["browser.search.separatePrivateDefault", true], 97 ], 98 }); 99 100 await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true }); 101 102 const doc = gBrowser.selectedBrowser.contentDocument; 103 const separateEngineCheckbox = doc.getElementById( 104 "browserSeparateDefaultEngine" 105 ).parentElement; 106 const privateDefaultDropdown = doc.getElementById("defaultPrivateEngine"); 107 108 Assert.ok( 109 !separateEngineCheckbox.hidden, 110 "Should not have hidden the separate search engine checkbox" 111 ); 112 Assert.ok( 113 !privateDefaultDropdown.shadowRoot.getElementById("input").disabled, 114 "Private engine selection box should be enabled" 115 ); 116 117 await SpecialPowers.pushPrefEnv({ 118 set: [["browser.search.separatePrivateDefault", false]], 119 }); 120 121 Assert.ok( 122 !separateEngineCheckbox.hidden, 123 "Should not have hidden the separate search engine checkbox" 124 ); 125 Assert.ok( 126 BrowserTestUtils.isVisible(privateDefaultDropdown), 127 "Private engine selection box should be visible" 128 ); 129 130 await SpecialPowers.pushPrefEnv({ 131 set: [["browser.search.separatePrivateDefault.ui.enabled", false]], 132 }); 133 134 Assert.ok( 135 separateEngineCheckbox.hidden, 136 "Should have hidden the separate private engine checkbox" 137 ); 138 Assert.ok( 139 separateEngineCheckbox.hidden && 140 separateEngineCheckbox.contains(privateDefaultDropdown), 141 "Should have hidden the private engine selection box" 142 ); 143 144 gBrowser.removeCurrentTab(); 145 }); 146 147 add_task(async function test_separatePrivateDefault() { 148 await SpecialPowers.pushPrefEnv({ 149 set: [ 150 ["browser.search.separatePrivateDefault.ui.enabled", true], 151 ["browser.search.separatePrivateDefault", false], 152 ], 153 }); 154 155 await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true }); 156 157 const doc = gBrowser.selectedBrowser.contentDocument; 158 const separateEngineCheckbox = doc.getElementById( 159 "browserSeparateDefaultEngine" 160 ); 161 const privateDefaultDropdown = doc.getElementById("defaultPrivateEngine"); 162 163 Assert.ok( 164 BrowserTestUtils.isVisible(privateDefaultDropdown), 165 "Private engine selection box should be visible" 166 ); 167 168 separateEngineCheckbox.click(); 169 await separateEngineCheckbox.parentElement.updateComplete; 170 171 Assert.ok( 172 Services.prefs.getBoolPref("browser.search.separatePrivateDefault"), 173 "Should have correctly set the pref" 174 ); 175 Assert.ok( 176 !privateDefaultDropdown.shadowRoot.getElementById("input").disabled, 177 "Private engine selection box should be enabled" 178 ); 179 180 separateEngineCheckbox.click(); 181 await separateEngineCheckbox.parentElement.updateComplete; 182 183 Assert.ok( 184 !Services.prefs.getBoolPref("browser.search.separatePrivateDefault"), 185 "Should have correctly turned the pref off" 186 ); 187 Assert.ok( 188 BrowserTestUtils.isVisible(privateDefaultDropdown), 189 "Private engine selection box should be visible" 190 ); 191 192 gBrowser.removeCurrentTab(); 193 }); 194 195 async function setDefaultEngine( 196 testPrivate, 197 currentEngineName, 198 expectedEngineName 199 ) { 200 await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true }); 201 202 const doc = gBrowser.selectedBrowser.contentDocument; 203 const input = doc.getElementById( 204 testPrivate ? "defaultPrivateEngine" : "defaultEngineNormal" 205 ); 206 const defaultEngineSelector = input.inputEl; 207 const defaultEngineTrigger = input.shadowRoot.querySelector(".panel-trigger"); 208 209 Assert.ok( 210 defaultEngineSelector.value.startsWith(currentEngineName), 211 "Should have the correct engine as default on first open" 212 ); 213 214 const popupShown = BrowserTestUtils.waitForEvent( 215 defaultEngineSelector, 216 "shown" 217 ); 218 EventUtils.synthesizeMouseAtCenter( 219 defaultEngineTrigger, 220 {}, 221 defaultEngineTrigger.ownerGlobal 222 ); 223 await popupShown; 224 225 const items = Array.from(defaultEngineSelector.children); 226 const engine2Item = items.find(item => 227 item.textContent.includes(expectedEngineName) 228 ); 229 230 const defaultChanged = SearchTestUtils.promiseSearchNotification( 231 testPrivate ? "engine-default-private" : "engine-default", 232 "browser-search-engine-modified" 233 ); 234 // Waiting for popupHiding here seemed to cause a race condition, however 235 // as we're really just interested in the notification, we'll just use 236 // that here. 237 EventUtils.synthesizeMouseAtCenter(engine2Item, {}, engine2Item.ownerGlobal); 238 await defaultChanged; 239 240 const newDefault = testPrivate 241 ? await Services.search.getDefaultPrivate() 242 : await Services.search.getDefault(); 243 Assert.equal( 244 newDefault.name, 245 expectedEngineName, 246 "Should have changed the default engine to engine2" 247 ); 248 } 249 250 add_task(async function test_setDefaultEngine() { 251 const engine1 = Services.search.getEngineByName("engine1"); 252 253 // Set an initial default so we have a known engine. 254 await Services.search.setDefault( 255 engine1, 256 Ci.nsISearchService.CHANGE_REASON_UNKNOWN 257 ); 258 259 Services.telemetry.clearEvents(); 260 Services.fog.testResetFOG(); 261 262 await setDefaultEngine(false, "engine1", "engine2"); 263 264 let snapshot = Glean.searchEngineDefault.changed.testGetValue(); 265 delete snapshot[0].timestamp; 266 Assert.deepEqual( 267 snapshot[0], 268 { 269 category: "search.engine.default", 270 name: "changed", 271 extra: { 272 change_reason: "user", 273 previous_engine_id: engine1.telemetryId, 274 new_engine_id: "other-engine2", 275 new_display_name: "engine2", 276 new_load_path: "[addon]engine2@tests.mozilla.org", 277 new_submission_url: "", 278 }, 279 }, 280 "Should have received the correct event details" 281 ); 282 283 gBrowser.removeCurrentTab(); 284 }); 285 286 add_task(async function test_setPrivateDefaultEngine() { 287 Services.telemetry.clearEvents(); 288 Services.fog.testResetFOG(); 289 290 await SpecialPowers.pushPrefEnv({ 291 set: [ 292 ["browser.search.separatePrivateDefault.ui.enabled", true], 293 ["browser.search.separatePrivateDefault", true], 294 ], 295 }); 296 297 const engine2 = Services.search.getEngineByName("engine2"); 298 299 // Set an initial default so we have a known engine. 300 await Services.search.setDefaultPrivate( 301 engine2, 302 Ci.nsISearchService.CHANGE_REASON_UNKNOWN 303 ); 304 305 Services.telemetry.clearEvents(); 306 Services.fog.testResetFOG(); 307 308 await setDefaultEngine(true, "engine2", "engine1"); 309 310 let snapshot = Glean.searchEnginePrivate.changed.testGetValue(); 311 delete snapshot[0].timestamp; 312 console.log(snapshot); 313 Assert.deepEqual( 314 snapshot[0], 315 { 316 category: "search.engine.private", 317 name: "changed", 318 extra: { 319 change_reason: "user", 320 previous_engine_id: engine2.telemetryId, 321 new_engine_id: "other-engine1", 322 new_display_name: "engine1", 323 new_load_path: "[addon]engine1@tests.mozilla.org", 324 new_submission_url: "", 325 }, 326 }, 327 "Should have received the correct event details" 328 ); 329 330 gBrowser.removeCurrentTab(); 331 });