summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_searchMode_switchTabs.js
blob: c4f541c9cdd6dfd1083fe892e65a63c8a91e11e5 (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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * Tests that search mode is stored per tab and restored when switching tabs.
 */

"use strict";

// Enters search mode using the one-off buttons.
add_task(async function switchTabs() {
  await SpecialPowers.pushPrefEnv({
    set: [["browser.urlbar.suggest.quickactions", false]],
  });

  // Open three tabs.  We'll enter search mode in tabs 0 and 2.
  let tabs = [];
  for (let i = 0; i < 3; i++) {
    let tab = await BrowserTestUtils.openNewForegroundTab({
      gBrowser,
      url: "http://example.com/" + i,
    });
    tabs.push(tab);
  }

  // Switch to tab 0.
  await BrowserTestUtils.switchTab(gBrowser, tabs[0]);

  // Do a search and enter search mode.  Pass fireInputEvent so that
  // userTypedValue is set and restored when we switch back to this tab.  This
  // isn't really necessary but it simulates the user's typing, and it also
  // means that we'll start a search when we switch back to this tab.
  await UrlbarTestUtils.promiseAutocompleteResultPopup({
    window,
    value: "test",
    fireInputEvent: true,
  });
  await UrlbarTestUtils.enterSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
  });

  // Switch to tab 1.  Search mode should be exited.
  await BrowserTestUtils.switchTab(gBrowser, tabs[1]);
  await UrlbarTestUtils.assertSearchMode(window, null);

  // Switch back to tab 0.  We should do a search (for "test") and re-enter
  // search mode.
  let searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[0]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
    entry: "oneoff",
  });
  Assert.equal(
    gURLBar.value,
    "test",
    "Value should remain the search string after switching back"
  );

  // Switch to tab 2.  Search mode should be exited.
  await BrowserTestUtils.switchTab(gBrowser, tabs[2]);
  await UrlbarTestUtils.assertSearchMode(window, null);

  // Do another search (in tab 2) and enter search mode.  Use a different source
  // from tab 0 just to use something different.
  await UrlbarTestUtils.promiseAutocompleteResultPopup({
    window,
    value: "test tab 2",
    fireInputEvent: true,
  });
  await UrlbarTestUtils.enterSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.TABS,
  });

  // Switch back to tab 0.  We should do a search and still be in search mode.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[0]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
    entry: "oneoff",
  });
  Assert.equal(
    gURLBar.value,
    "test",
    "Value should remain the search string after switching back"
  );

  // Switch to tab 1.  Search mode should be exited.
  await BrowserTestUtils.switchTab(gBrowser, tabs[1]);
  await UrlbarTestUtils.assertSearchMode(window, null);

  // Switch back to tab 2.  We should do a search and re-enter search mode.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[2]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.TABS,
    entry: "oneoff",
  });
  Assert.equal(
    gURLBar.value,
    "test tab 2",
    "Value should remain the search string after switching back"
  );

  // Exit search mode.
  await UrlbarTestUtils.exitSearchMode(window, { clickClose: true });

  // Switch to tab 0.  We should do a search and re-enter search mode.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[0]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
    entry: "oneoff",
  });
  Assert.equal(
    gURLBar.value,
    "test",
    "Value should remain the search string after switching back"
  );

  // Switch back to tab 2.  We should do a search but search mode should be
  // inactive.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[2]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, null);
  Assert.equal(
    gURLBar.value,
    "test tab 2",
    "Value should remain the search string after switching back"
  );

  // Switch back to tab 0.  We should do a search and re-enter search mode.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[0]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
    entry: "oneoff",
  });
  Assert.equal(
    gURLBar.value,
    "test",
    "Value should remain the search string after switching back"
  );

  // Exit search mode.
  await UrlbarTestUtils.exitSearchMode(window, { clickClose: true });

  // Switch back to tab 2.  We should do a search but search mode should be
  // inactive.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[2]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, null);
  Assert.equal(
    gURLBar.value,
    "test tab 2",
    "Value should remain the search string after switching back"
  );

  // Switch back to tab 0.  We should do a search but search mode should be
  // inactive.
  searchPromise = UrlbarTestUtils.promiseSearchComplete(window);
  await BrowserTestUtils.switchTab(gBrowser, tabs[0]);
  await searchPromise;
  await UrlbarTestUtils.assertSearchMode(window, null);
  Assert.equal(
    gURLBar.value,
    "test",
    "Value should remain the search string after switching back"
  );

  await UrlbarTestUtils.promisePopupClose(window);
  for (let tab of tabs) {
    BrowserTestUtils.removeTab(tab);
  }
});

// Start loading a SERP from search mode then immediately switch to a new tab so
// the SERP finishes loading in the background. Switch back to the SERP tab and
// observe that we don't re-enter search mode despite having an entry for that
// tab in UrlbarInput._searchModesByBrowser. See bug 1675926.
//
// This subtest intermittently does not test bug 1675926 (NB: this does not mean
// it is an intermittent failure). The false-positive occurs if the SERP page
// finishes loading before we switch tabs. We include this subtest so we have
// one covering real-world behaviour. A subtest that is guaranteed to test this
// behaviour that does not simulate real world behaviour is included below.
add_task(async function slow_load() {
  await SpecialPowers.pushPrefEnv({
    set: [["browser.urlbar.suggest.searches", false]],
  });
  const engineName = "Test";
  let extension = await SearchTestUtils.installSearchExtension(
    {
      name: engineName,
    },
    { skipUnload: true }
  );

  const originalTab = gBrowser.selectedTab;
  const newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);

  await UrlbarTestUtils.promiseAutocompleteResultPopup({
    window,
    value: "test",
    fireInputEvent: true,
  });
  await UrlbarTestUtils.enterSearchMode(window, { engineName });

  const loadPromise = BrowserTestUtils.browserLoaded(newTab.linkedBrowser);
  // Select the search mode heuristic to load the example.com SERP.
  EventUtils.synthesizeKey("KEY_Enter");
  // Switch away from the tab before we let it load.
  await BrowserTestUtils.switchTab(gBrowser, originalTab);
  await loadPromise;

  // Switch back to the search mode tab and confirm we don't restore search
  // mode.
  await BrowserTestUtils.switchTab(gBrowser, newTab);
  await UrlbarTestUtils.assertSearchMode(window, null);

  BrowserTestUtils.removeTab(newTab);
  await SpecialPowers.popPrefEnv();
  await extension.unload();
});

// Tests the same behaviour as slow_load, but in a more reliable way using
// non-real-world behaviour.
add_task(async function slow_load_guaranteed() {
  const engineName = "Test";
  let extension = await SearchTestUtils.installSearchExtension(
    {
      name: engineName,
    },
    { skipUnload: true }
  );

  const backgroundTab = BrowserTestUtils.addTab(gBrowser);

  // Simulate a tab that was in search mode, loaded a SERP, then was switched
  // away from before setURI was called.
  backgroundTab.ownerGlobal.gURLBar.searchMode = { engineName };
  let loadPromise = BrowserTestUtils.browserLoaded(backgroundTab.linkedBrowser);
  BrowserTestUtils.loadURIString(
    backgroundTab.linkedBrowser,
    "http://example.com/?search=test"
  );
  await loadPromise;

  // Switch to the background mode tab and confirm we don't restore search mode.
  await BrowserTestUtils.switchTab(gBrowser, backgroundTab);
  await UrlbarTestUtils.assertSearchMode(window, null);

  BrowserTestUtils.removeTab(backgroundTab);
  await extension.unload();
});

// Enters search mode by typing a restriction char with no search string.
// Search mode and the search string should be restored after switching back to
// the tab.
add_task(async function userTypedValue_empty() {
  await doUserTypedValueTest("");
});

// Enters search mode by typing a restriction char followed by a search string.
// Search mode and the search string should be restored after switching back to
// the tab.
add_task(async function userTypedValue_nonEmpty() {
  await doUserTypedValueTest("foo bar");
});

/**
 * Enters search mode by typing a restriction char followed by a search string,
 * opens a new tab and immediately closes it so we switch back to the search
 * mode tab, and checks the search mode state and input value.
 *
 * @param {string} searchString
 *   The search string to enter search mode with.
 */
async function doUserTypedValueTest(searchString) {
  let value = `${UrlbarTokenizer.RESTRICT.BOOKMARK} ${searchString}`;
  await UrlbarTestUtils.promiseAutocompleteResultPopup({
    window,
    value,
    fireInputEvent: true,
  });
  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
    entry: "typed",
  });
  Assert.equal(
    gURLBar.value,
    searchString,
    "Sanity check: Value is the search string"
  );

  let tab = await BrowserTestUtils.openNewForegroundTab({ gBrowser });
  BrowserTestUtils.removeTab(tab);

  await UrlbarTestUtils.assertSearchMode(window, {
    source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
    entry: "typed",
  });
  Assert.equal(
    gURLBar.value,
    searchString,
    "Value should remain the search string after switching back"
  );

  gURLBar.handleRevert();
}