summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_handleCommand_fallback.js
blob: 9d8ac8754c0566f9b3f929a240f18327d80b70e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * Tests that the fallback paths of handleCommand (no view and no previous
 * result) work consistently against the normal case of picking the heuristic
 * result.
 */

const TEST_STRINGS = [
  "test",
  "test/",
  "test.com",
  "test.invalid",
  "moz",
  "moz test",
  "@moz test",
  "keyword",
  "keyword test",
  "test/test/",
  "test /test/",
];

add_task(async function () {
  // Disable autofill so mozilla.org isn't autofilled below.
  await SpecialPowers.pushPrefEnv({
    set: [["browser.urlbar.autoFill", false]],
  });

  sandbox = sinon.createSandbox();
  await SearchTestUtils.installSearchExtension();
  await SearchTestUtils.installSearchExtension({ name: "Example2" });

  let bm = await PlacesUtils.bookmarks.insert({
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
    url: "https://example.com/?q=%s",
    title: "test",
  });
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "https://example.com/?q=%s",
  });
  registerCleanupFunction(async () => {
    sandbox.restore();
    await PlacesUtils.bookmarks.remove(bm);
    await UrlbarTestUtils.formHistory.clear();
  });

  async function promiseLoadURL() {
    return new Promise(resolve => {
      sandbox.stub(gURLBar, "_loadURL").callsFake(function () {
        sandbox.restore();
        // The last arguments are optional and apply only to some cases, so we
        // could not use deepEqual with them.
        resolve(Array.from(arguments).slice(0, 3));
      });
    });
  }

  // Run the string through a normal search where the user types the string
  // and confirms the heuristic result, store the arguments to _loadURL, then
  // confirm the same string without a view and without an input event, and
  // compare the arguments.
  for (let value of TEST_STRINGS) {
    info(`Input the value normally and Enter. Value: ${value}`);
    let promise = promiseLoadURL();
    await UrlbarTestUtils.promiseAutocompleteResultPopup({
      window,
      value,
    });
    EventUtils.synthesizeKey("KEY_Enter");
    let args = await promise;
    Assert.ok(args.length, "Sanity check");
    info("Close the panel and confirm again.");
    promise = promiseLoadURL();
    await UrlbarTestUtils.promisePopupClose(window);
    EventUtils.synthesizeKey("KEY_Enter");
    Assert.deepEqual(await promise, args, "Check arguments are coherent");

    info("Set the value directly and Enter.");
    // To properly testing the original value we must be out of search mode.
    if (gURLBar.searchMode) {
      await UrlbarTestUtils.exitSearchMode(window);
      // Exiting search mode may reopen the panel.
      await UrlbarTestUtils.promisePopupClose(window);
    }
    promise = promiseLoadURL();
    gURLBar.value = value;
    let spy = sinon.spy(UrlbarUtils, "getHeuristicResultFor");
    EventUtils.synthesizeKey("KEY_Enter");
    spy.restore();
    Assert.ok(spy.called, "invoked getHeuristicResultFor");
    Assert.deepEqual(await promise, args, "Check arguments are coherent");
    gURLBar.handleRevert();
  }
});

// This is testing the final fallback case that may happen when we can't
// get a heuristic result, maybe because the Places database is corrupt.
add_task(async function no_heuristic_test() {
  sandbox = sinon.createSandbox();

  let stub = sandbox
    .stub(UrlbarUtils, "getHeuristicResultFor")
    .callsFake(async function () {
      throw new Error("I failed!");
    });

  registerCleanupFunction(async () => {
    sandbox.restore();
    await UrlbarTestUtils.formHistory.clear();
  });

  async function promiseLoadURL() {
    return new Promise(resolve => {
      sandbox.stub(gURLBar, "_loadURL").callsFake(function () {
        sandbox.restore();
        // The last arguments are optional and apply only to some cases, so we
        // could not use deepEqual with them.
        resolve(Array.from(arguments).slice(0, 3));
      });
    });
  }

  // Run the string through a normal search where the user types the string
  // and confirms the heuristic result, store the arguments to _loadURL, then
  // confirm the same string without a view and without an input event, and
  // compare the arguments.
  for (let value of TEST_STRINGS) {
    // To properly testing the original value we must be out of search mode.
    if (gURLBar.searchMode) {
      await UrlbarTestUtils.exitSearchMode(window);
    }
    let promise = promiseLoadURL();
    gURLBar.value = value;
    EventUtils.synthesizeKey("KEY_Enter");
    Assert.ok(stub.called, "invoked getHeuristicResultFor");
    // The first argument to _loadURL should always be a valid url, so this
    // should never throw.
    new URL((await promise)[0]);
  }
});