forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			309 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* Any copyright is dedicated to the Public Domain.
 | |
|  * http://creativecommons.org/publicdomain/zero/1.0/ */
 | |
| 
 | |
| /**
 | |
|  * Checks the local shortcut rows in the engines list of the search pane.
 | |
|  */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| ChromeUtils.defineESModuleGetters(this, {
 | |
|   UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
 | |
|   UrlbarUtils: "resource:///modules/UrlbarUtils.sys.mjs",
 | |
| });
 | |
| 
 | |
| let gTree;
 | |
| 
 | |
| add_setup(async function () {
 | |
|   let prefs = await openPreferencesViaOpenPreferencesAPI("search", {
 | |
|     leaveOpen: true,
 | |
|   });
 | |
|   registerCleanupFunction(() => {
 | |
|     BrowserTestUtils.removeTab(gBrowser.selectedTab);
 | |
|   });
 | |
| 
 | |
|   Assert.equal(
 | |
|     prefs.selectedPane,
 | |
|     "paneSearch",
 | |
|     "Sanity check: Search pane is selected by default"
 | |
|   );
 | |
| 
 | |
|   gTree = gBrowser.contentDocument.querySelector("#engineList");
 | |
|   gTree.scrollIntoView();
 | |
|   gTree.focus();
 | |
| });
 | |
| 
 | |
| // The rows should be visible and checked by default.
 | |
| add_task(async function visible() {
 | |
|   await checkRowVisibility(true);
 | |
|   await forEachLocalShortcutRow(async row => {
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, gTree.columns.getNamedColumn("engineShown")),
 | |
|       "true",
 | |
|       "Row is checked initially"
 | |
|     );
 | |
|   });
 | |
| });
 | |
| 
 | |
| // Toggling the browser.urlbar.shortcuts.* prefs should toggle the corresponding
 | |
| // checkboxes in the rows.
 | |
| add_task(async function syncFromPrefs() {
 | |
|   let col = gTree.columns.getNamedColumn("engineShown");
 | |
|   await forEachLocalShortcutRow(async (row, shortcut) => {
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "true",
 | |
|       "Row is checked initially"
 | |
|     );
 | |
|     await SpecialPowers.pushPrefEnv({
 | |
|       set: [[getUrlbarPrefName(shortcut.pref), false]],
 | |
|     });
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "false",
 | |
|       "Row is unchecked after disabling pref"
 | |
|     );
 | |
|     await SpecialPowers.popPrefEnv();
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "true",
 | |
|       "Row is checked after re-enabling pref"
 | |
|     );
 | |
|   });
 | |
| });
 | |
| 
 | |
| // Pressing the space key while a row is selected should toggle its checkbox
 | |
| // and pref.
 | |
| add_task(async function syncToPrefs_spaceKey() {
 | |
|   let col = gTree.columns.getNamedColumn("engineShown");
 | |
|   await forEachLocalShortcutRow(async (row, shortcut) => {
 | |
|     Assert.ok(
 | |
|       UrlbarPrefs.get(shortcut.pref),
 | |
|       "Sanity check: Pref is enabled initially"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "true",
 | |
|       "Row is checked initially"
 | |
|     );
 | |
|     gTree.view.selection.select(row);
 | |
|     EventUtils.synthesizeKey(" ", {}, gTree.ownerGlobal);
 | |
|     Assert.ok(
 | |
|       !UrlbarPrefs.get(shortcut.pref),
 | |
|       "Pref is disabled after pressing space key"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "false",
 | |
|       "Row is unchecked after pressing space key"
 | |
|     );
 | |
|     Services.prefs.clearUserPref(getUrlbarPrefName(shortcut.pref));
 | |
|   });
 | |
| });
 | |
| 
 | |
| // Clicking the checkbox in a local shortcut row should toggle the checkbox and
 | |
| // pref.
 | |
| add_task(async function syncToPrefs_click() {
 | |
|   let col = gTree.columns.getNamedColumn("engineShown");
 | |
|   await forEachLocalShortcutRow(async (row, shortcut) => {
 | |
|     Assert.ok(
 | |
|       UrlbarPrefs.get(shortcut.pref),
 | |
|       "Sanity check: Pref is enabled initially"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "true",
 | |
|       "Row is checked initially"
 | |
|     );
 | |
| 
 | |
|     let rect = gTree.getCoordsForCellItem(row, col, "cell");
 | |
|     let x = rect.x + rect.width / 2;
 | |
|     let y = rect.y + rect.height / 2;
 | |
|     EventUtils.synthesizeMouse(gTree.body, x, y, {}, gTree.ownerGlobal);
 | |
| 
 | |
|     Assert.ok(
 | |
|       !UrlbarPrefs.get(shortcut.pref),
 | |
|       "Pref is disabled after clicking checkbox"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellValue(row, col),
 | |
|       "false",
 | |
|       "Row is unchecked after clicking checkbox"
 | |
|     );
 | |
|     Services.prefs.clearUserPref(getUrlbarPrefName(shortcut.pref));
 | |
|   });
 | |
| });
 | |
| 
 | |
| // The keyword column should not be editable according to isEditable().
 | |
| add_task(async function keywordNotEditable_isEditable() {
 | |
|   await forEachLocalShortcutRow(async row => {
 | |
|     Assert.ok(
 | |
|       !gTree.view.isEditable(
 | |
|         row,
 | |
|         gTree.columns.getNamedColumn("engineKeyword")
 | |
|       ),
 | |
|       "Keyword column is not editable"
 | |
|     );
 | |
|   });
 | |
| });
 | |
| 
 | |
| // Pressing the enter key while a row is selected shouldn't allow the keyword to
 | |
| // be edited.
 | |
| add_task(async function keywordNotEditable_enterKey() {
 | |
|   let col = gTree.columns.getNamedColumn("engineKeyword");
 | |
|   await forEachLocalShortcutRow(async (row, shortcut) => {
 | |
|     Assert.ok(
 | |
|       shortcut.restrict,
 | |
|       "Sanity check: Shortcut restriction char is non-empty"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellText(row, col),
 | |
|       shortcut.restrict,
 | |
|       "Sanity check: Keyword column has correct restriction char initially"
 | |
|     );
 | |
| 
 | |
|     gTree.view.selection.select(row);
 | |
|     EventUtils.synthesizeKey("KEY_Enter", {}, gTree.ownerGlobal);
 | |
|     EventUtils.sendString("newkeyword");
 | |
|     EventUtils.synthesizeKey("KEY_Enter", {}, gTree.ownerGlobal);
 | |
| 
 | |
|     // Wait a moment to allow for any possible asynchronicity.
 | |
|     // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
 | |
|     await new Promise(r => setTimeout(r, 500));
 | |
| 
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellText(row, col),
 | |
|       shortcut.restrict,
 | |
|       "Keyword column is still restriction char"
 | |
|     );
 | |
|   });
 | |
| });
 | |
| 
 | |
| // Double-clicking the keyword column shouldn't allow the keyword to be edited.
 | |
| add_task(async function keywordNotEditable_click() {
 | |
|   let col = gTree.columns.getNamedColumn("engineKeyword");
 | |
|   await forEachLocalShortcutRow(async (row, shortcut) => {
 | |
|     Assert.ok(
 | |
|       shortcut.restrict,
 | |
|       "Sanity check: Shortcut restriction char is non-empty"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellText(row, col),
 | |
|       shortcut.restrict,
 | |
|       "Sanity check: Keyword column has correct restriction char initially"
 | |
|     );
 | |
| 
 | |
|     let rect = gTree.getCoordsForCellItem(row, col, "text");
 | |
|     let x = rect.x + rect.width / 2;
 | |
|     let y = rect.y + rect.height / 2;
 | |
| 
 | |
|     let promise = BrowserTestUtils.waitForEvent(gTree, "dblclick");
 | |
| 
 | |
|     // Click once to select the row.
 | |
|     EventUtils.synthesizeMouse(
 | |
|       gTree.body,
 | |
|       x,
 | |
|       y,
 | |
|       { clickCount: 1 },
 | |
|       gTree.ownerGlobal
 | |
|     );
 | |
| 
 | |
|     // Now double-click the keyword column.
 | |
|     EventUtils.synthesizeMouse(
 | |
|       gTree.body,
 | |
|       x,
 | |
|       y,
 | |
|       { clickCount: 2 },
 | |
|       gTree.ownerGlobal
 | |
|     );
 | |
| 
 | |
|     await promise;
 | |
| 
 | |
|     EventUtils.sendString("newkeyword");
 | |
|     EventUtils.synthesizeKey("KEY_Enter", {}, gTree.ownerGlobal);
 | |
| 
 | |
|     // Wait a moment to allow for any possible asynchronicity.
 | |
|     // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
 | |
|     await new Promise(r => setTimeout(r, 500));
 | |
| 
 | |
|     Assert.equal(
 | |
|       gTree.view.getCellText(row, col),
 | |
|       shortcut.restrict,
 | |
|       "Keyword column is still restriction char"
 | |
|     );
 | |
|   });
 | |
| });
 | |
| 
 | |
| /**
 | |
|  * Asserts that the engine and local shortcut rows are present in the tree.
 | |
|  */
 | |
| async function checkRowVisibility() {
 | |
|   let engines = await Services.search.getVisibleEngines();
 | |
| 
 | |
|   Assert.equal(
 | |
|     gTree.view.rowCount,
 | |
|     engines.length + UrlbarUtils.LOCAL_SEARCH_MODES.length,
 | |
|     "Expected number of tree rows"
 | |
|   );
 | |
| 
 | |
|   // Check the engine rows.
 | |
|   for (let row = 0; row < engines.length; row++) {
 | |
|     let engine = engines[row];
 | |
|     let text = gTree.view.getCellText(
 | |
|       row,
 | |
|       gTree.columns.getNamedColumn("engineName")
 | |
|     );
 | |
|     Assert.equal(
 | |
|       text,
 | |
|       engine.name,
 | |
|       `Sanity check: Tree row ${row} has expected engine name`
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   // Check the shortcut rows.
 | |
|   await forEachLocalShortcutRow(async (row, shortcut) => {
 | |
|     let text = gTree.view.getCellText(
 | |
|       row,
 | |
|       gTree.columns.getNamedColumn("engineName")
 | |
|     );
 | |
|     let name = UrlbarUtils.getResultSourceName(shortcut.source);
 | |
|     let l10nName = await gTree.ownerDocument.l10n.formatValue(
 | |
|       `urlbar-search-mode-${name}`
 | |
|     );
 | |
|     Assert.ok(l10nName, "Sanity check: l10n name is non-empty");
 | |
|     Assert.equal(text, l10nName, `Tree row ${row} has expected shortcut name`);
 | |
|   });
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Calls a callback for each local shortcut row in the tree.
 | |
|  *
 | |
|  * @param {function} callback
 | |
|  *   Called for each local shortcut row like: callback(rowIndex, shortcutObject)
 | |
|  */
 | |
| async function forEachLocalShortcutRow(callback) {
 | |
|   let engines = await Services.search.getVisibleEngines();
 | |
|   for (let i = 0; i < UrlbarUtils.LOCAL_SEARCH_MODES.length; i++) {
 | |
|     let shortcut = UrlbarUtils.LOCAL_SEARCH_MODES[i];
 | |
|     let row = engines.length + i;
 | |
|     // These tests assume LOCAL_SEARCH_MODES are enabled, this can be removed
 | |
|     // when we enable QuickActions. We cant just enable the pref in browser.ini
 | |
|     // as this test calls clearUserPref.
 | |
|     if (shortcut.pref == "shortcuts.quickactions") {
 | |
|       continue;
 | |
|     }
 | |
|     await callback(row, shortcut);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Prepends the `browser.urlbar.` branch to the given relative pref.
 | |
|  *
 | |
|  * @param {string} relativePref
 | |
|  *   A pref name relative to the `browser.urlbar.`.
 | |
|  * @returns {string}
 | |
|  *   The full pref name with `browser.urlbar.` prepended.
 | |
|  */
 | |
| function getUrlbarPrefName(relativePref) {
 | |
|   return `browser.urlbar.${relativePref}`;
 | |
| }
 | 
