summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_oneOffs_searchSuggestions.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/urlbar/tests/browser/browser_oneOffs_searchSuggestions.js')
-rw-r--r--browser/components/urlbar/tests/browser/browser_oneOffs_searchSuggestions.js358
1 files changed, 358 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/browser/browser_oneOffs_searchSuggestions.js b/browser/components/urlbar/tests/browser/browser_oneOffs_searchSuggestions.js
new file mode 100644
index 0000000000..ef324b08cd
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_oneOffs_searchSuggestions.js
@@ -0,0 +1,358 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Tests various actions relating to search suggestions and the one-off buttons.
+ */
+
+const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
+const TEST_ENGINE2_BASENAME = "searchSuggestionEngine2.xml";
+
+const serverInfo = {
+ scheme: "http",
+ host: "localhost",
+ port: 20709, // Must be identical to what is in searchSuggestionEngine2.xml
+};
+
+var gEngine;
+var gEngine2;
+
+add_setup(async function () {
+ await PlacesUtils.history.clear();
+ await UrlbarTestUtils.formHistory.clear();
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["browser.urlbar.suggest.searches", true],
+ ["browser.urlbar.maxHistoricalSearchSuggestions", 2],
+ ],
+ });
+ gEngine = await SearchTestUtils.promiseNewSearchEngine({
+ url: getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME,
+ });
+ gEngine2 = await SearchTestUtils.promiseNewSearchEngine({
+ url: getRootDirectory(gTestPath) + TEST_ENGINE2_BASENAME,
+ });
+ let oldDefaultEngine = await Services.search.getDefault();
+ await Services.search.moveEngine(gEngine2, 0);
+ await Services.search.moveEngine(gEngine, 0);
+ await Services.search.setDefault(
+ gEngine,
+ Ci.nsISearchService.CHANGE_REASON_UNKNOWN
+ );
+ registerCleanupFunction(async function () {
+ await Services.search.setDefault(
+ oldDefaultEngine,
+ Ci.nsISearchService.CHANGE_REASON_UNKNOWN
+ );
+
+ await PlacesUtils.history.clear();
+ await UrlbarTestUtils.formHistory.clear();
+ });
+});
+
+async function withSuggestions(testFn) {
+ // First run with remote suggestions, and then run with form history.
+ await withSuggestionOnce(false, testFn);
+ await withSuggestionOnce(true, testFn);
+}
+
+async function withSuggestionOnce(useFormHistory, testFn) {
+ if (useFormHistory) {
+ // Add foofoo twice so it's more frecent so it appears first so that the
+ // order of form history results matches the order of remote suggestion
+ // results.
+ await UrlbarTestUtils.formHistory.add(["foofoo", "foofoo", "foobar"]);
+ }
+ await BrowserTestUtils.withNewTab(gBrowser, async () => {
+ let value = "foo";
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value,
+ fireInputEvent: true,
+ });
+ let index = await UrlbarTestUtils.promiseSuggestionsPresent(window);
+ await assertState({
+ inputValue: value,
+ resultIndex: 0,
+ });
+ await withHttpServer(serverInfo, () => {
+ return testFn(index, useFormHistory);
+ });
+ });
+ await PlacesUtils.history.clear();
+ await UrlbarTestUtils.formHistory.clear();
+}
+
+async function selectSecondSuggestion(index, isFormHistory) {
+ // Down to select the first search suggestion.
+ for (let i = index; i > 0; --i) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+ await assertState({
+ inputValue: "foofoo",
+ resultIndex: index,
+ suggestion: {
+ isFormHistory,
+ },
+ });
+
+ // Down to select the next search suggestion.
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ await assertState({
+ inputValue: "foobar",
+ resultIndex: index + 1,
+ suggestion: {
+ isFormHistory,
+ },
+ });
+}
+
+// Presses the Return key when a one-off is selected after selecting a search
+// suggestion.
+add_task(async function test_returnAfterSuggestion() {
+ await withSuggestions(async (index, usingFormHistory) => {
+ await selectSecondSuggestion(index, usingFormHistory);
+
+ // Alt+Down to select the first one-off.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ await assertState({
+ inputValue: "foobar",
+ resultIndex: index + 1,
+ oneOffIndex: 0,
+ suggestion: {
+ isFormHistory: usingFormHistory,
+ },
+ });
+
+ let heuristicResult = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+ Assert.ok(
+ !BrowserTestUtils.is_visible(heuristicResult.element.action),
+ "The heuristic action should not be visible"
+ );
+
+ let resultsPromise = UrlbarTestUtils.promiseSearchComplete(window);
+ EventUtils.synthesizeKey("KEY_Enter");
+ await resultsPromise;
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: gEngine.name,
+ entry: "oneoff",
+ });
+ await UrlbarTestUtils.exitSearchMode(window, { backspace: true });
+ });
+});
+
+// Presses the Return key when a non-default one-off is selected after selecting
+// a search suggestion.
+add_task(async function test_returnAfterSuggestion_nonDefault() {
+ await withSuggestions(async (index, usingFormHistory) => {
+ await selectSecondSuggestion(index, usingFormHistory);
+
+ // Alt+Down twice to select the second one-off.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ await assertState({
+ inputValue: "foobar",
+ resultIndex: index + 1,
+ oneOffIndex: 1,
+ suggestion: {
+ isFormHistory: usingFormHistory,
+ },
+ });
+
+ let resultsPromise = UrlbarTestUtils.promiseSearchComplete(window);
+ EventUtils.synthesizeKey("KEY_Enter");
+ await resultsPromise;
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: gEngine2.name,
+ entry: "oneoff",
+ });
+ await UrlbarTestUtils.exitSearchMode(window, { backspace: true });
+ });
+});
+
+// Clicks a one-off engine after selecting a search suggestion.
+add_task(async function test_clickAfterSuggestion() {
+ await withSuggestions(async (index, usingFormHistory) => {
+ await selectSecondSuggestion(index, usingFormHistory);
+
+ let oneOffs =
+ UrlbarTestUtils.getOneOffSearchButtons(window).getSelectableButtons(true);
+ let resultsPromise = UrlbarTestUtils.promiseSearchComplete(window);
+ EventUtils.synthesizeMouseAtCenter(oneOffs[1], {});
+ await resultsPromise;
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: gEngine2.name,
+ entry: "oneoff",
+ });
+ await UrlbarTestUtils.exitSearchMode(window, { backspace: true });
+ });
+});
+
+// Clicks a non-default one-off engine after selecting a search suggestion.
+add_task(async function test_clickAfterSuggestion_nonDefault() {
+ await withSuggestions(async (index, usingFormHistory) => {
+ await selectSecondSuggestion(index, usingFormHistory);
+
+ let oneOffs =
+ UrlbarTestUtils.getOneOffSearchButtons(window).getSelectableButtons(true);
+ let resultsPromise = UrlbarTestUtils.promiseSearchComplete(window);
+ EventUtils.synthesizeMouseAtCenter(oneOffs[1], {});
+ await resultsPromise;
+ await UrlbarTestUtils.assertSearchMode(window, {
+ engineName: gEngine2.name,
+ entry: "oneoff",
+ });
+ await UrlbarTestUtils.exitSearchMode(window, { backspace: true });
+ });
+});
+
+// Selects a non-default one-off engine and then clicks a search suggestion.
+add_task(async function test_selectOneOffThenSuggestion() {
+ await withSuggestions(async (index, usingFormHistory) => {
+ // Select a non-default one-off engine.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ await assertState({
+ inputValue: "foo",
+ resultIndex: 0,
+ oneOffIndex: 1,
+ });
+
+ let heuristicResult = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
+ Assert.ok(
+ BrowserTestUtils.is_visible(heuristicResult.element.action),
+ "The heuristic action should be visible because the result is selected"
+ );
+
+ // Now click the second suggestion.
+ let result = await UrlbarTestUtils.getDetailsOfResultAt(window, index + 1);
+ // Note search history results don't change their engine when the selected
+ // one-off button changes!
+ let resultsPromise = BrowserTestUtils.browserLoaded(
+ gBrowser.selectedBrowser,
+ false,
+ usingFormHistory
+ ? `http://mochi.test:8888/?terms=foobar`
+ : `http://localhost:20709/?terms=foobar`
+ );
+ EventUtils.synthesizeMouseAtCenter(result.element.row, {});
+ await resultsPromise;
+ });
+});
+
+add_task(async function overridden_engine_not_reused() {
+ info(
+ "An overridden search suggestion item should not be reused by a search with another engine"
+ );
+ await BrowserTestUtils.withNewTab(gBrowser, async () => {
+ let typedValue = "foo";
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: typedValue,
+ fireInputEvent: true,
+ });
+ let index = await UrlbarTestUtils.promiseSuggestionsPresent(window);
+ // Down to select the first search suggestion.
+ for (let i = index; i > 0; --i) {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ }
+ await assertState({
+ inputValue: "foofoo",
+ resultIndex: index,
+ suggestion: {
+ isFormHistory: false,
+ },
+ });
+
+ // ALT+Down to select the second search engine.
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true });
+ await assertState({
+ inputValue: "foofoo",
+ resultIndex: index,
+ oneOffIndex: 1,
+ suggestion: {
+ isFormHistory: false,
+ },
+ });
+
+ let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 1);
+ let label = result.displayed.action;
+ // Run again the query, check the label has been replaced.
+ await UrlbarTestUtils.promisePopupClose(window);
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window,
+ value: typedValue,
+ fireInputEvent: true,
+ });
+ index = await UrlbarTestUtils.promiseSuggestionsPresent(window);
+ await assertState({
+ inputValue: "foo",
+ resultIndex: 0,
+ });
+ result = await UrlbarTestUtils.getDetailsOfResultAt(window, index);
+ Assert.notEqual(
+ result.displayed.action,
+ label,
+ "The label should have been updated"
+ );
+ });
+});
+
+async function assertState({
+ resultIndex,
+ inputValue,
+ oneOffIndex = -1,
+ suggestion = null,
+}) {
+ Assert.equal(
+ UrlbarTestUtils.getSelectedRowIndex(window),
+ resultIndex,
+ "Expected result should be selected"
+ );
+ Assert.equal(
+ UrlbarTestUtils.getOneOffSearchButtons(window).selectedButtonIndex,
+ oneOffIndex,
+ "Expected one-off should be selected"
+ );
+ if (inputValue !== undefined) {
+ Assert.equal(gURLBar.value, inputValue, "Expected input value");
+ }
+
+ if (suggestion) {
+ let result = await UrlbarTestUtils.getDetailsOfResultAt(
+ window,
+ resultIndex
+ );
+ Assert.equal(
+ result.type,
+ UrlbarUtils.RESULT_TYPE.SEARCH,
+ "Result type should be SEARCH"
+ );
+ if (suggestion.isFormHistory) {
+ Assert.equal(
+ result.source,
+ UrlbarUtils.RESULT_SOURCE.HISTORY,
+ "Result source should be HISTORY"
+ );
+ } else {
+ Assert.equal(
+ result.source,
+ UrlbarUtils.RESULT_SOURCE.SEARCH,
+ "Result source should be SEARCH"
+ );
+ }
+ Assert.equal(
+ typeof result.searchParams.suggestion,
+ "string",
+ "Result should have a suggestion"
+ );
+ Assert.equal(
+ result.searchParams.suggestion,
+ suggestion.value || inputValue,
+ "Result should have the expected suggestion"
+ );
+ }
+}