tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_search_firefoxSuggest.js (13758B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 // This tests the Search pane's Firefox Suggest UI.
      5 
      6 "use strict";
      7 
      8 ChromeUtils.defineESModuleGetters(this, {
      9  QuickSuggest: "moz-src:///browser/components/urlbar/QuickSuggest.sys.mjs",
     10 });
     11 
     12 const ONLINE_ENABLED_TOGGLE_ID = "firefoxSuggestOnlineEnabledToggle";
     13 const BUTTON_RESTORE_DISMISSED_ID = "restoreDismissedSuggestions";
     14 
     15 // Maps `SETTINGS_UI` values to expected visibility state objects. See
     16 // `assertSuggestVisibility()` in `head.js` for info on the state objects.
     17 const EXPECTED = {
     18  [QuickSuggest.SETTINGS_UI.FULL]: {
     19    [ONLINE_ENABLED_TOGGLE_ID]: { isVisible: true },
     20    locationBarGroupHeader: {
     21      isVisible: true,
     22      l10nId: "addressbar-header-firefox-suggest-2",
     23    },
     24  },
     25  [QuickSuggest.SETTINGS_UI.NONE]: {
     26    locationBarGroupHeader: { isVisible: true, l10nId: "addressbar-header-1" },
     27  },
     28  [QuickSuggest.SETTINGS_UI.OFFLINE_ONLY]: {
     29    [ONLINE_ENABLED_TOGGLE_ID]: { isVisible: false },
     30    locationBarGroupHeader: {
     31      isVisible: true,
     32      l10nId: "addressbar-header-firefox-suggest-2",
     33    },
     34  },
     35 };
     36 
     37 // This test can take a while due to the many permutations some of these tasks
     38 // run through, so request a longer timeout.
     39 requestLongerTimeout(10);
     40 
     41 add_setup(async function () {
     42  // Suggest needs to be initialized in order to dismiss a suggestion.
     43  await QuickSuggestTestUtils.ensureQuickSuggestInit();
     44 
     45  // Set the default value of the preference to FULL, since that's what the
     46  // test was originally written with.
     47  await SpecialPowers.pushPrefEnv({
     48    set: [
     49      ["browser.urlbar.quicksuggest.settingsUi", QuickSuggest.SETTINGS_UI.FULL],
     50    ],
     51  });
     52 });
     53 
     54 // The following tasks check the initial visibility of the Firefox Suggest UI
     55 // and the visibility after installing a Nimbus experiment.
     56 
     57 add_task(async function initiallyDisabled_disable() {
     58  await doSuggestVisibilityTest({
     59    initialSuggestEnabled: false,
     60    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
     61    nimbusVariables: {
     62      quickSuggestEnabled: false,
     63    },
     64  });
     65 });
     66 
     67 add_task(async function initiallyDisabled_disable_settingsUiFull() {
     68  await doSuggestVisibilityTest({
     69    initialSuggestEnabled: false,
     70    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
     71    nimbusVariables: {
     72      quickSuggestEnabled: false,
     73      // `quickSuggestEnabled: false` should override this, so the Suggest
     74      // settings should not be visible (`initialExpected` should persist).
     75      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.FULL,
     76    },
     77  });
     78 });
     79 
     80 add_task(async function initiallyDisabled_enable() {
     81  await doSuggestVisibilityTest({
     82    initialSuggestEnabled: false,
     83    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
     84    nimbusVariables: {
     85      quickSuggestEnabled: true,
     86    },
     87    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
     88  });
     89 });
     90 
     91 add_task(async function initiallyDisabled_enable_settingsUiFull() {
     92  await doSuggestVisibilityTest({
     93    initialSuggestEnabled: false,
     94    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
     95    nimbusVariables: {
     96      quickSuggestEnabled: true,
     97      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.FULL,
     98    },
     99    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    100  });
    101 });
    102 
    103 add_task(async function initiallyDisabled_enable_settingsUiNone() {
    104  await doSuggestVisibilityTest({
    105    initialSuggestEnabled: false,
    106    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
    107    nimbusVariables: {
    108      quickSuggestEnabled: true,
    109      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.NONE,
    110    },
    111  });
    112 });
    113 
    114 add_task(async function initiallyDisabled_enable_settingsUiOfflineOnly() {
    115  await doSuggestVisibilityTest({
    116    initialSuggestEnabled: false,
    117    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
    118    nimbusVariables: {
    119      quickSuggestEnabled: true,
    120      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.OFFLINE_ONLY,
    121    },
    122    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.OFFLINE_ONLY],
    123  });
    124 });
    125 
    126 add_task(async function initiallyEnabled_disable() {
    127  await doSuggestVisibilityTest({
    128    initialSuggestEnabled: true,
    129    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    130    nimbusVariables: {
    131      quickSuggestEnabled: false,
    132    },
    133    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
    134  });
    135 });
    136 
    137 add_task(async function initiallyEnabled_disable_settingsUiFull() {
    138  await doSuggestVisibilityTest({
    139    initialSuggestEnabled: true,
    140    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    141    nimbusVariables: {
    142      quickSuggestEnabled: false,
    143      // `quickSuggestEnabled: false` should override this, so the Suggest
    144      // settings should not be visible.
    145      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.FULL,
    146    },
    147    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
    148  });
    149 });
    150 
    151 add_task(async function initiallyEnabled_enable() {
    152  await doSuggestVisibilityTest({
    153    initialSuggestEnabled: true,
    154    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    155    nimbusVariables: {
    156      quickSuggestEnabled: true,
    157    },
    158  });
    159 });
    160 
    161 add_task(async function initiallyEnabled_settingsUiFull() {
    162  await doSuggestVisibilityTest({
    163    initialSuggestEnabled: true,
    164    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    165    nimbusVariables: {
    166      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.FULL,
    167    },
    168  });
    169 });
    170 
    171 add_task(async function initiallyEnabled_settingsUiNone() {
    172  await doSuggestVisibilityTest({
    173    initialSuggestEnabled: true,
    174    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    175    nimbusVariables: {
    176      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.NONE,
    177    },
    178    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.NONE],
    179  });
    180 });
    181 
    182 add_task(async function initiallyEnabled_settingsUiOfflineOnly() {
    183  await doSuggestVisibilityTest({
    184    initialSuggestEnabled: true,
    185    initialExpected: EXPECTED[QuickSuggest.SETTINGS_UI.FULL],
    186    nimbusVariables: {
    187      quickSuggestSettingsUi: QuickSuggest.SETTINGS_UI.OFFLINE_ONLY,
    188    },
    189    newExpected: EXPECTED[QuickSuggest.SETTINGS_UI.OFFLINE_ONLY],
    190  });
    191 });
    192 
    193 add_task(async function toggling_all_firefoxsuggest_disables_other_options() {
    194  // Enable quicksuggest since it could be off by default depending on location.
    195  await SpecialPowers.pushPrefEnv({
    196    set: [["browser.urlbar.suggest.quicksuggest.all", true]],
    197  });
    198 
    199  await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
    200 
    201  let doc = gBrowser.selectedBrowser.contentDocument;
    202  let allCheckbox = doc.getElementById("firefoxSuggestAll");
    203  let sponsoredCheckbox = doc.getElementById("firefoxSuggestSponsored");
    204  let onlineEnabledCheckbox = doc.getElementById(
    205    "firefoxSuggestOnlineEnabledToggle"
    206  );
    207 
    208  // Initial state.
    209  Assert.ok(
    210    allCheckbox.checked,
    211    "firefoxSuggestAll should initially be checked"
    212  );
    213  Assert.ok(
    214    !sponsoredCheckbox.disabled,
    215    "sponsoredCheckbox should initially be enabled"
    216  );
    217  Assert.ok(
    218    !onlineEnabledCheckbox.disabled,
    219    "onlineEnabledCheckbox should initially be enabled"
    220  );
    221 
    222  allCheckbox.click();
    223  await allCheckbox.parentElement.updateComplete;
    224 
    225  Assert.ok(!allCheckbox.checked, "firefoxSuggestAll should now be unchecked");
    226  Assert.ok(sponsoredCheckbox.disabled, "sponsoredCheckbox should be disabled");
    227  Assert.ok(
    228    onlineEnabledCheckbox.disabled,
    229    "onlineEnabledCheckbox should be disabled"
    230  );
    231 
    232  allCheckbox.click();
    233  await allCheckbox.parentElement.updateComplete;
    234 
    235  Assert.ok(allCheckbox.checked, "firefoxSuggestAll should be checked");
    236  Assert.ok(
    237    !sponsoredCheckbox.disabled,
    238    "sponsoredCheckbox should be enabled again"
    239  );
    240  Assert.ok(
    241    !onlineEnabledCheckbox.disabled,
    242    "onlineEnabledCheckbox should be enabled again"
    243  );
    244 
    245  gBrowser.removeCurrentTab();
    246 });
    247 
    248 add_task(
    249  async function all_firefoxsuggest_disabled_disables_other_options_on_open() {
    250    // Disable the "all" preference and enable the others before opening settings.
    251    await SpecialPowers.pushPrefEnv({
    252      set: [
    253        ["browser.urlbar.suggest.quicksuggest.all", false],
    254        ["browser.urlbar.suggest.quicksuggest.sponsored", true],
    255        ["browser.urlbar.quicksuggest.online.enabled", true],
    256      ],
    257    });
    258 
    259    await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
    260 
    261    let doc = gBrowser.selectedBrowser.contentDocument;
    262    let allCheckbox = doc.getElementById("firefoxSuggestAll");
    263    let sponsoredCheckbox = doc.getElementById("firefoxSuggestSponsored");
    264    let onlineEnabledCheckbox = doc.getElementById(
    265      "firefoxSuggestOnlineEnabledToggle"
    266    );
    267 
    268    // Initial state.
    269    Assert.ok(!allCheckbox.checked, "firefoxSuggestAll should not be checked");
    270    Assert.ok(
    271      sponsoredCheckbox.disabled,
    272      "sponsoredCheckbox should initially be disabled"
    273    );
    274    Assert.ok(
    275      onlineEnabledCheckbox.disabled,
    276      "onlineEnabledCheckbox should initially be disabled"
    277    );
    278 
    279    gBrowser.removeCurrentTab();
    280 
    281    await SpecialPowers.popPrefEnv();
    282  }
    283 );
    284 
    285 // Tests the "Restore" button for dismissed suggestions.
    286 add_task(async function restoreDismissedSuggestions() {
    287  // Start with no dismissed suggestions.
    288  await QuickSuggest.clearDismissedSuggestions();
    289  Assert.ok(
    290    !(await QuickSuggest.canClearDismissedSuggestions()),
    291    "canClearDismissedSuggestions should be false after clearing suggestions"
    292  );
    293 
    294  await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
    295 
    296  let doc = gBrowser.selectedBrowser.contentDocument;
    297  let addressBarSection = doc.getElementById("locationBarGroup");
    298  addressBarSection.scrollIntoView();
    299 
    300  let button = doc.getElementById(BUTTON_RESTORE_DISMISSED_ID);
    301  Assert.ok(button.disabled, "Restore button is disabled initially.");
    302 
    303  await QuickSuggest.dismissResult(QuickSuggestTestUtils.ampResult());
    304 
    305  Assert.ok(
    306    await QuickSuggest.canClearDismissedSuggestions(),
    307    "canClearDismissedSuggestions should return true after dismissing a suggestion"
    308  );
    309  await TestUtils.waitForCondition(
    310    () => !button.disabled,
    311    "Waiting for Restore button to become enabled after dismissing suggestion"
    312  );
    313  Assert.ok(
    314    !button.disabled,
    315    "Restore button should be enabled after dismissing suggestion"
    316  );
    317 
    318  let clearPromise = TestUtils.topicObserved("quicksuggest-dismissals-cleared");
    319  button.click();
    320  await clearPromise;
    321 
    322  Assert.ok(
    323    !(await QuickSuggest.canClearDismissedSuggestions()),
    324    "canClearDismissedSuggestions should return false after restoring dismissals"
    325  );
    326  await TestUtils.waitForCondition(
    327    () => button.disabled,
    328    "Waiting for Restore button to become disabled after clicking it"
    329  );
    330  Assert.ok(
    331    button.disabled,
    332    "Restore button should be disabled after clearing suggestions"
    333  );
    334 
    335  gBrowser.removeCurrentTab();
    336 });
    337 
    338 // If the pane is open while Suggest is still initializing and there are
    339 // dismissed suggestions, the "Restore" button should become enabled when init
    340 // finishes.
    341 add_task(async function restoreDismissedSuggestions_init_enabled() {
    342  // Dismiss a suggestion.
    343  await QuickSuggest.dismissResult(QuickSuggestTestUtils.ampResult());
    344  Assert.ok(
    345    await QuickSuggest.canClearDismissedSuggestions(),
    346    "canClearDismissedSuggestions should be true after dismissing suggestion"
    347  );
    348 
    349  await doRestoreInitTest(async button => {
    350    // The button should become enabled since we dismissed a suggestion above.
    351    await TestUtils.waitForCondition(
    352      () => !button.disabled,
    353      "Waiting for Restore button to become enabled after re-enabling Rust backend"
    354    );
    355    Assert.ok(
    356      !button.disabled,
    357      "Restore button should be enabled after re-enabling Rust backend"
    358    );
    359  });
    360 });
    361 
    362 // If the pane is open while Suggest is still initializing and there are no
    363 // dismissed suggestions, the "Restore" button should remain disabled when init
    364 // finishes.
    365 add_task(async function restoreDismissedSuggestions_init_disabled() {
    366  // Clear dismissed suggestions.
    367  await QuickSuggest.clearDismissedSuggestions();
    368  Assert.ok(
    369    !(await QuickSuggest.canClearDismissedSuggestions()),
    370    "canClearDismissedSuggestions should be false after clearing suggestions"
    371  );
    372 
    373  await doRestoreInitTest(async button => {
    374    // The button should remain disabled since there are no dismissed
    375    // suggestions.
    376    await TestUtils.waitForTick();
    377    Assert.ok(
    378      button.disabled,
    379      "Restore button should remain disabled after re-enabling Rust backend"
    380    );
    381  });
    382 });
    383 
    384 async function doRestoreInitTest(checkButton) {
    385  // Disable the Suggest Rust backend, which manages individually dismissed
    386  // suggestions. While Rust is disabled, Suggest won't be able to tell whether
    387  // there are any individually dismissed suggestions.
    388  await SpecialPowers.pushPrefEnv({
    389    set: [["browser.urlbar.quicksuggest.rustEnabled", false]],
    390  });
    391 
    392  // Open the pane.
    393  await openPreferencesViaOpenPreferencesAPI("search", { leaveOpen: true });
    394 
    395  let doc = gBrowser.selectedBrowser.contentDocument;
    396  let addressBarSection = doc.getElementById("locationBarGroup");
    397  addressBarSection.scrollIntoView();
    398 
    399  let button = doc.getElementById(BUTTON_RESTORE_DISMISSED_ID);
    400  Assert.ok(button.disabled, "Restore button is disabled initially.");
    401 
    402  // Re-enable the Rust backend. It will send `quicksuggest-dismissals-changed`
    403  // when it finishes initialization.
    404  let changedPromise = TestUtils.topicObserved(
    405    "quicksuggest-dismissals-changed"
    406  );
    407  await SpecialPowers.popPrefEnv();
    408 
    409  info(
    410    "Waiting for quicksuggest-dismissals-changed after re-enabling Rust backend"
    411  );
    412  await changedPromise;
    413 
    414  await checkButton(button);
    415 
    416  // Clean up.
    417  await QuickSuggest.clearDismissedSuggestions();
    418  gBrowser.removeCurrentTab();
    419 }