tor-browser

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

test_providerTabToSearch.js (17853B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /**
      5 * Tests UrlbarProviderTabToSearch. See also
      6 * browser/components/urlbar/tests/browser/browser_tabToSearch.js
      7 */
      8 
      9 "use strict";
     10 
     11 let testEngine;
     12 
     13 add_setup(async () => {
     14  // Disable search suggestions for a less verbose test.
     15  Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
     16  // Disable ScotchBonnet that provides its own tab to search implementation.
     17  Services.prefs.setBoolPref(
     18    "browser.urlbar.scotchBonnet.enableOverride",
     19    false
     20  );
     21  // Disable tab-to-search onboarding results. Those are covered in
     22  // browser/components/urlbar/tests/browser/browser_tabToSearch.js.
     23  Services.prefs.setIntPref(
     24    "browser.urlbar.tabToSearch.onboard.interactionsLeft",
     25    0
     26  );
     27  await SearchTestUtils.installSearchExtension({ name: "Test" });
     28  testEngine = await Services.search.getEngineByName("Test");
     29 
     30  registerCleanupFunction(async () => {
     31    Services.prefs.clearUserPref(
     32      "browser.urlbar.tabToSearch.onboard.interactionsLeft"
     33    );
     34    Services.prefs.clearUserPref("browser.search.suggest.enabled");
     35    Services.prefs.clearUserPref("browser.urlbar.scotchBonnet.enableOverride");
     36  });
     37 });
     38 
     39 // Tests that tab-to-search results appear when the engine's result domain is
     40 // autofilled.
     41 add_task(async function basic() {
     42  await PlacesTestUtils.addVisits(["https://example.com/"]);
     43  let context = createContext("examp", { isPrivate: false });
     44  await check_results({
     45    context,
     46    autofilled: "example.com/",
     47    completed: "https://example.com/",
     48    matches: [
     49      makeVisitResult(context, {
     50        uri: "https://example.com/",
     51        title: "test visit for https://example.com/",
     52        heuristic: true,
     53        providerName: "UrlbarProviderAutofill",
     54      }),
     55      makeSearchResult(context, {
     56        engineName: testEngine.name,
     57        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
     58        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
     59          testEngine.searchUrlDomain
     60        ),
     61        providesSearchMode: true,
     62        query: "",
     63        providerName: "UrlbarProviderTabToSearch",
     64      }),
     65    ],
     66  });
     67 
     68  info("Repeat the search but with tab-to-search disabled through pref.");
     69  Services.prefs.setBoolPref("browser.urlbar.suggest.engines", false);
     70  await check_results({
     71    context,
     72    autofilled: "example.com/",
     73    completed: "https://example.com/",
     74    matches: [
     75      makeVisitResult(context, {
     76        uri: "https://example.com/",
     77        title: "test visit for https://example.com/",
     78        heuristic: true,
     79        providerName: "UrlbarProviderAutofill",
     80      }),
     81    ],
     82  });
     83  Services.prefs.clearUserPref("browser.urlbar.suggest.engines");
     84 
     85  await cleanupPlaces();
     86 });
     87 
     88 // Tests that tab-to-search results are shown when the typed string matches an
     89 // engine domain even when there is no autofill.
     90 add_task(async function noAutofill() {
     91  // Note we are not adding any history visits.
     92  let context = createContext("examp", { isPrivate: false });
     93  await check_results({
     94    context,
     95    matches: [
     96      makeSearchResult(context, {
     97        engineName: Services.search.defaultEngine.name,
     98        engineIconUri: await Services.search.defaultEngine.getIconURL(),
     99        heuristic: true,
    100        providerName: "UrlbarProviderHeuristicFallback",
    101      }),
    102      makeSearchResult(context, {
    103        engineName: testEngine.name,
    104        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    105        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    106          testEngine.searchUrlDomain
    107        ),
    108        providesSearchMode: true,
    109        query: "",
    110        providerName: "UrlbarProviderTabToSearch",
    111      }),
    112    ],
    113  });
    114 });
    115 
    116 // Tests that tab-to-search results are not shown when the typed string matches
    117 // an engine domain, but something else is being autofilled.
    118 add_task(async function autofillDoesNotMatchEngine() {
    119  await PlacesTestUtils.addVisits(["https://example.test.ca/"]);
    120  let context = createContext("example", { isPrivate: false });
    121  await check_results({
    122    context,
    123    autofilled: "example.test.ca/",
    124    completed: "https://example.test.ca/",
    125    matches: [
    126      makeVisitResult(context, {
    127        uri: "https://example.test.ca/",
    128        title: "test visit for https://example.test.ca/",
    129        heuristic: true,
    130        providerName: "UrlbarProviderAutofill",
    131      }),
    132    ],
    133  });
    134 
    135  await cleanupPlaces();
    136 });
    137 
    138 // Tests that www. is ignored for the purposes of matching autofill to
    139 // tab-to-search.
    140 add_task(async function ignoreWww() {
    141  // The history result has www., the engine does not.
    142  await PlacesTestUtils.addVisits(["https://www.example.com/"]);
    143  let context = createContext("www.examp", { isPrivate: false });
    144  await check_results({
    145    context,
    146    autofilled: "www.example.com/",
    147    completed: "https://www.example.com/",
    148    matches: [
    149      makeVisitResult(context, {
    150        uri: "https://www.example.com/",
    151        title: "test visit for https://www.example.com/",
    152        heuristic: true,
    153        providerName: "UrlbarProviderAutofill",
    154      }),
    155      makeSearchResult(context, {
    156        engineName: testEngine.name,
    157        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    158        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    159          testEngine.searchUrlDomain
    160        ),
    161        providesSearchMode: true,
    162        query: "",
    163        providerName: "UrlbarProviderTabToSearch",
    164      }),
    165    ],
    166  });
    167  await cleanupPlaces();
    168 
    169  // The engine has www., the history result does not.
    170  await PlacesTestUtils.addVisits(["https://foo.bar/"]);
    171  let extension = await SearchTestUtils.installSearchExtension(
    172    {
    173      name: "TestWww",
    174      search_url: "https://www.foo.bar/",
    175    },
    176    { skipUnload: true }
    177  );
    178  let wwwTestEngine = Services.search.getEngineByName("TestWww");
    179  context = createContext("foo", { isPrivate: false });
    180  await check_results({
    181    context,
    182    autofilled: "foo.bar/",
    183    completed: "https://foo.bar/",
    184    matches: [
    185      makeVisitResult(context, {
    186        uri: "https://foo.bar/",
    187        title: "test visit for https://foo.bar/",
    188        heuristic: true,
    189        providerName: "UrlbarProviderAutofill",
    190      }),
    191      makeSearchResult(context, {
    192        engineName: wwwTestEngine.name,
    193        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    194        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    195          wwwTestEngine.searchUrlDomain
    196        ),
    197        providesSearchMode: true,
    198        query: "",
    199        providerName: "UrlbarProviderTabToSearch",
    200      }),
    201    ],
    202  });
    203  await cleanupPlaces();
    204 
    205  // Both the engine and the history result have www.
    206  await PlacesTestUtils.addVisits(["https://www.foo.bar/"]);
    207  context = createContext("foo", { isPrivate: false });
    208  await check_results({
    209    context,
    210    autofilled: "foo.bar/",
    211    completed: "https://www.foo.bar/",
    212    matches: [
    213      makeVisitResult(context, {
    214        uri: "https://www.foo.bar/",
    215        title: "test visit for https://www.foo.bar/",
    216        heuristic: true,
    217        providerName: "UrlbarProviderAutofill",
    218      }),
    219      makeSearchResult(context, {
    220        engineName: wwwTestEngine.name,
    221        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    222        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    223          wwwTestEngine.searchUrlDomain
    224        ),
    225        providesSearchMode: true,
    226        query: "",
    227        providerName: "UrlbarProviderTabToSearch",
    228      }),
    229    ],
    230  });
    231  await cleanupPlaces();
    232 
    233  await extension.unload();
    234 });
    235 
    236 // Tests that when a user's query causes autofill to replace one engine's domain
    237 // with another, the correct tab-to-search results are shown.
    238 add_task(async function conflictingEngines() {
    239  for (let i = 0; i < 3; i++) {
    240    await PlacesTestUtils.addVisits([
    241      "https://foobar.com/",
    242      "https://foo.com/",
    243    ]);
    244  }
    245  let extension1 = await SearchTestUtils.installSearchExtension(
    246    {
    247      name: "TestFooBar",
    248      search_url: "https://foobar.com/",
    249    },
    250    { skipUnload: true }
    251  );
    252  let extension2 = await SearchTestUtils.installSearchExtension(
    253    {
    254      name: "TestFoo",
    255      search_url: "https://foo.com/",
    256    },
    257    { skipUnload: true }
    258  );
    259  let fooBarTestEngine = Services.search.getEngineByName("TestFooBar");
    260  let fooTestEngine = Services.search.getEngineByName("TestFoo");
    261 
    262  // Search for "foo", autofilling foo.com. Observe that the foo.com
    263  // tab-to-search result is shown, even though the foobar.com engine was added
    264  // first (and thus enginesForDomainPrefix puts it earlier in its returned
    265  // array.)
    266  let context = createContext("foo", { isPrivate: false });
    267  await check_results({
    268    context,
    269    autofilled: "foo.com/",
    270    completed: "https://foo.com/",
    271    matches: [
    272      makeVisitResult(context, {
    273        uri: "https://foo.com/",
    274        title: "test visit for https://foo.com/",
    275        heuristic: true,
    276        providerName: "UrlbarProviderAutofill",
    277      }),
    278      makeSearchResult(context, {
    279        engineName: fooTestEngine.name,
    280        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    281        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    282          fooTestEngine.searchUrlDomain
    283        ),
    284        providesSearchMode: true,
    285        query: "",
    286        providerName: "UrlbarProviderTabToSearch",
    287      }),
    288      makeVisitResult(context, {
    289        uri: "https://foobar.com/",
    290        title: "test visit for https://foobar.com/",
    291        providerName: "UrlbarProviderPlaces",
    292      }),
    293    ],
    294  });
    295 
    296  // Search for "foob", autofilling foobar.com. Observe that the foo.com
    297  // tab-to-search result is replaced with the foobar.com tab-to-search result.
    298  context = createContext("foob", { isPrivate: false });
    299  await check_results({
    300    context,
    301    autofilled: "foobar.com/",
    302    completed: "https://foobar.com/",
    303    matches: [
    304      makeVisitResult(context, {
    305        uri: "https://foobar.com/",
    306        title: "test visit for https://foobar.com/",
    307        heuristic: true,
    308        providerName: "UrlbarProviderAutofill",
    309      }),
    310      makeSearchResult(context, {
    311        engineName: fooBarTestEngine.name,
    312        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    313        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    314          fooBarTestEngine.searchUrlDomain
    315        ),
    316        providesSearchMode: true,
    317        query: "",
    318        providerName: "UrlbarProviderTabToSearch",
    319      }),
    320    ],
    321  });
    322 
    323  await cleanupPlaces();
    324  await extension1.unload();
    325  await extension2.unload();
    326 });
    327 
    328 add_task(async function multipleEnginesForHostname() {
    329  info(
    330    "In case of multiple engines only one tab-to-search result should be returned"
    331  );
    332  let extension = await SearchTestUtils.installSearchExtension(
    333    {
    334      name: "TestMaps",
    335      search_url: "https://example.com/maps/",
    336    },
    337    { skipUnload: true }
    338  );
    339 
    340  let context = createContext("examp", { isPrivate: false });
    341  let maxResultCount = UrlbarPrefs.get("maxRichResults");
    342 
    343  // Add enough visits to autofill example.com.
    344  for (let i = 0; i < maxResultCount; i++) {
    345    await PlacesTestUtils.addVisits("https://example.com/");
    346  }
    347 
    348  // Add enough visits to other URLs matching our query to fill up the list of
    349  // results.
    350  let otherVisitResults = [];
    351  for (let i = 0; i < maxResultCount; i++) {
    352    let url = `https://mochi${i}.test:8888/example/` + i;
    353    await PlacesTestUtils.addVisits(url);
    354    otherVisitResults.unshift(
    355      makeVisitResult(context, {
    356        uri: url,
    357        title: "test visit for " + url,
    358      })
    359    );
    360  }
    361 
    362  await check_results({
    363    context,
    364    autofilled: "example.com/",
    365    completed: "https://example.com/",
    366    matches: [
    367      makeVisitResult(context, {
    368        uri: "https://example.com/",
    369        title: "test visit for https://example.com/",
    370        heuristic: true,
    371        providerName: "UrlbarProviderAutofill",
    372      }),
    373      makeSearchResult(context, {
    374        engineName: testEngine.name,
    375        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    376        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    377          testEngine.searchUrlDomain
    378        ),
    379        providesSearchMode: true,
    380        query: "",
    381        providerName: "UrlbarProviderTabToSearch",
    382      }),
    383      // There should be `maxResultCount` - 2 other visit results. If this fails
    384      // because there are actually `maxResultCount` - 3 other results, then the
    385      // muxer is improperly including both TabToSearch results in its
    386      // calculation of the total available result span instead of only one, so
    387      // one fewer visit result appears than expected.
    388      ...otherVisitResults.slice(0, maxResultCount - 2),
    389    ],
    390  });
    391  await cleanupPlaces();
    392  await extension.unload();
    393 });
    394 
    395 add_task(async function test_casing() {
    396  info("Tab-to-search results appear also in case of different casing.");
    397  await PlacesTestUtils.addVisits(["https://example.com/"]);
    398  let context = createContext("eXAm", { isPrivate: false });
    399  await check_results({
    400    context,
    401    autofilled: "eXAmple.com/",
    402    completed: "https://example.com/",
    403    matches: [
    404      makeVisitResult(context, {
    405        uri: "https://example.com/",
    406        title: "test visit for https://example.com/",
    407        heuristic: true,
    408        providerName: "UrlbarProviderAutofill",
    409      }),
    410      makeSearchResult(context, {
    411        engineName: testEngine.name,
    412        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    413        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    414          testEngine.searchUrlDomain
    415        ),
    416        providesSearchMode: true,
    417        query: "",
    418        providerName: "UrlbarProviderTabToSearch",
    419      }),
    420    ],
    421  });
    422  await cleanupPlaces();
    423 });
    424 
    425 add_task(async function test_publicSuffix() {
    426  info("Tab-to-search results appear also in case of partial host match.");
    427  let extension = await SearchTestUtils.installSearchExtension(
    428    {
    429      name: "MyTest",
    430      search_url: "https://test.mytest.it/",
    431    },
    432    { skipUnload: true }
    433  );
    434  let engine = Services.search.getEngineByName("MyTest");
    435  await PlacesTestUtils.addVisits(["https://test.mytest.it/"]);
    436  let context = createContext("my", { isPrivate: false });
    437  await check_results({
    438    context,
    439    matches: [
    440      makeSearchResult(context, {
    441        engineName: Services.search.defaultEngine.name,
    442        engineIconUri: await Services.search.defaultEngine.getIconURL(),
    443        heuristic: true,
    444        providerName: "UrlbarProviderHeuristicFallback",
    445      }),
    446      makeSearchResult(context, {
    447        engineName: engine.name,
    448        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    449        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    450          engine.searchUrlDomain
    451        ),
    452        providesSearchMode: true,
    453        query: "",
    454        providerName: "UrlbarProviderTabToSearch",
    455        satisfiesAutofillThreshold: true,
    456      }),
    457      makeVisitResult(context, {
    458        uri: "https://test.mytest.it/",
    459        title: "test visit for https://test.mytest.it/",
    460        providerName: "UrlbarProviderPlaces",
    461      }),
    462    ],
    463  });
    464  await cleanupPlaces();
    465  await extension.unload();
    466 });
    467 
    468 add_task(async function test_publicSuffixIsHost() {
    469  info("Tab-to-search results does not appear in case we autofill a suffix.");
    470  let extension = await SearchTestUtils.installSearchExtension(
    471    {
    472      name: "SuffixTest",
    473      search_url: "https://somesuffix.com.mx/",
    474    },
    475    { skipUnload: true }
    476  );
    477 
    478  // The top level domain will be autofilled, not the full domain.
    479  await PlacesTestUtils.addVisits(["https://com.mx/"]);
    480  let context = createContext("co", { isPrivate: false });
    481  await check_results({
    482    context,
    483    autofilled: "com.mx/",
    484    completed: "https://com.mx/",
    485    matches: [
    486      makeVisitResult(context, {
    487        uri: "https://com.mx/",
    488        title: "test visit for https://com.mx/",
    489        heuristic: true,
    490        providerName: "UrlbarProviderAutofill",
    491      }),
    492    ],
    493  });
    494  await cleanupPlaces();
    495  await extension.unload();
    496 });
    497 
    498 add_task(async function test_disabledEngine() {
    499  info("Tab-to-search results does not appear for a Pref-disabled engine.");
    500  let extension = await SearchTestUtils.installSearchExtension(
    501    {
    502      name: "Disabled",
    503      search_url: "https://disabled.com/",
    504    },
    505    { skipUnload: true }
    506  );
    507  let engine = Services.search.getEngineByName("Disabled");
    508  await PlacesTestUtils.addVisits(["https://disabled.com/"]);
    509  let context = createContext("dis", { isPrivate: false });
    510 
    511  info("Sanity check that the engine would appear.");
    512  await check_results({
    513    context,
    514    autofilled: "disabled.com/",
    515    completed: "https://disabled.com/",
    516    matches: [
    517      makeVisitResult(context, {
    518        uri: "https://disabled.com/",
    519        title: "test visit for https://disabled.com/",
    520        heuristic: true,
    521        providerName: "UrlbarProviderAutofill",
    522      }),
    523      makeSearchResult(context, {
    524        engineName: engine.name,
    525        engineIconUri: UrlbarUtils.ICON.SEARCH_GLASS,
    526        searchUrlDomainWithoutSuffix: UrlbarUtils.stripPublicSuffixFromHost(
    527          engine.searchUrlDomain
    528        ),
    529        providesSearchMode: true,
    530        query: "",
    531        providerName: "UrlbarProviderTabToSearch",
    532      }),
    533    ],
    534  });
    535 
    536  info("Now disable the engine.");
    537  engine.hideOneOffButton = true;
    538 
    539  await check_results({
    540    context,
    541    autofilled: "disabled.com/",
    542    completed: "https://disabled.com/",
    543    matches: [
    544      makeVisitResult(context, {
    545        uri: "https://disabled.com/",
    546        title: "test visit for https://disabled.com/",
    547        heuristic: true,
    548        providerName: "UrlbarProviderAutofill",
    549      }),
    550    ],
    551  });
    552  engine.hideOneOffButton = false;
    553 
    554  await cleanupPlaces();
    555  await extension.unload();
    556 });