/* 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(); }