From 28ed698fec016f3b6c169c3c9ac314e701cce4b3 Mon Sep 17 00:00:00 2001 From: "virgil.sangerean" Date: Tue, 21 Oct 2025 13:05:49 +0300 Subject: [PATCH 1/5] vs/search-mode-persists --- modules/browser_object_navigation.py | 54 ++++++++++++ modules/page_object_prefs.py | 11 +++ .../test_search_mode_appears_after_input.py | 86 +++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 tests/address_bar_and_search/test_search_mode_appears_after_input.py diff --git a/modules/browser_object_navigation.py b/modules/browser_object_navigation.py index 558c9ad22..549ba7a4c 100644 --- a/modules/browser_object_navigation.py +++ b/modules/browser_object_navigation.py @@ -281,6 +281,60 @@ def open_tracker_panel(self) -> BasePage: self.get_element("shield-icon").click() return self + def wait_for_suggestions_present(self, at_least: int = 1): + """Wait until the suggestion list has at least one visible item.""" + self.set_chrome_context() + self.expect(lambda _: len(self.get_elements("suggestion-titles")) >= at_least) + return self + + def wait_for_suggestions_absent(self): + """Wait for the suggestions list to disappear (for non-general engines).""" + self.set_chrome_context() + self.element_not_visible("suggestion-titles") + return self + + def open_usb_and_select_engine(self, engine_title: str): + """Click the USB icon and select a search engine by its title.""" + self.get_element("searchmode-switcher").click() + self.get_element("search-mode-switcher-option", labels=[engine_title]).click() + return self + + def assert_search_mode_chip_visible(self): + """Ensure the search mode indicator (chip) is visible on the left.""" + self.set_chrome_context() + self.get_element("search-mode-span") + return self + + def click_first_suggestion_row(self): + """ + Clicks the first visible suggestion row in the list, using robust scrolling and fallback. + """ + from selenium.webdriver.common.by import By + from selenium.webdriver.common.action_chains import ActionChains + + self.set_chrome_context() + driver = self.driver + + try: + # Prefer Firefox Suggest row if present + row = self.get_element("firefox-suggest") + except Exception: + titles = self.get_elements("suggestion-titles") + assert titles, "No visible suggestion items found." + target = next((t for t in titles if t.is_displayed()), titles[0]) + try: + row = target.find_element(By.XPATH, "ancestor::*[contains(@class,'urlbarView-row')][1]") + except Exception: + row = target + + driver.execute_script("arguments[0].scrollIntoView({block:'center'});", row) + try: + ActionChains(driver).move_to_element(row).click().perform() + except Exception: + driver.execute_script("arguments[0].click();", row) + + return self + @BasePage.context_chrome def click_file_download_warning_panel(self) -> BasePage: """exit file download warning panel if present""" diff --git a/modules/page_object_prefs.py b/modules/page_object_prefs.py index a04fbcb76..2bc874bf1 100644 --- a/modules/page_object_prefs.py +++ b/modules/page_object_prefs.py @@ -65,6 +65,15 @@ def find_in_settings(self, term: str) -> BasePage: search_input.send_keys(term) return self + def enable_private_window_suggestions(self): + """Enable 'Show search suggestions in Private Windows' if not already checked.""" + from selenium.webdriver.common.by import By + + checkbox = self.driver.find_element(By.ID, "showSearchSuggestionsPrivateWindows") + if checkbox.get_attribute("checked") != "true": + checkbox.click() + return self + def set_alternative_language(self, lang_code: str) -> BasePage: """Changes the browser language""" self.get_element("language-set-alternative-button").click() @@ -678,6 +687,8 @@ def handle_unknown_content_dialog(self) -> BasePage: return self + + class AboutAddons(BasePage): """ The POM for the about:addons page diff --git a/tests/address_bar_and_search/test_search_mode_appears_after_input.py b/tests/address_bar_and_search/test_search_mode_appears_after_input.py new file mode 100644 index 000000000..a95cc8ac8 --- /dev/null +++ b/tests/address_bar_and_search/test_search_mode_appears_after_input.py @@ -0,0 +1,86 @@ +import pytest +from selenium.webdriver.support import expected_conditions as EC + +from modules.browser_object import Navigation +from modules.page_object_prefs import AboutPrefs +from modules.util import BrowserActions + +GENERAL_ENGINE = "Bing" +QUERY = "cobra kai" + + +@pytest.fixture() +def test_case(): + return "3028715" + + +def test_search_mode_appears_and_suggestions_update(driver): + """ + Steps: + 1) Open a new tab. + 2) Start typing in the address bar. + 3) Suggestions list starts to populate using the default search engine. + 4) Click the USB and select another search engine from the list. + 5) Search mode appears (left side). Check suggestions list. + 6) Search terms are retained and new suggestions are returned. + 7) Click one of the search suggestions. + 8) A search is done using the engine selected from step 4. + """ + nav = Navigation(driver) + actions = BrowserActions(driver) + + # 1) Open a new tab + nav.open_and_switch_to_new_window("tab") + + # 2) Start typing (no Enter) + actions.search(QUERY, with_enter=False) + + # 3) Suggestions list populates (default engine) + nav.wait_for_suggestions_present() + + # 4) Click the USB and select another engine + nav.open_usb_and_select_engine(GENERAL_ENGINE) + + # 5) Search mode chip appears + nav.assert_search_mode_chip_visible() + nav.wait_for_suggestions_present() + + # 6–7) Click a visible suggestion + nav.click_first_suggestion_row() + + # 8) Verify search executed with selected engine + nav.expect_in_content(EC.url_contains(GENERAL_ENGINE.lower())) + nav.clear_awesome_bar() + + +def test_private_mode_repeat_after_enabling_pref(driver): + """ + - Enable “Show search suggestions in Private Windows”. + - Open Private Window. + - Repeat steps 1–5 (verify search works with selected engine). + """ + nav = Navigation(driver) + actions = BrowserActions(driver) + + # Enable PBM suggestions pref by its known ID + AboutPrefs(driver, category="search").open().enable_private_window_suggestions() + + # Open Private Window using BasePage method + nav.open_and_switch_to_new_window("private") + + try: + # Repeat steps 1–8 in Private Mode + nav.open_and_switch_to_new_window("tab") + actions.search(QUERY, with_enter=False) + + nav.wait_for_suggestions_present() + nav.open_usb_and_select_engine(GENERAL_ENGINE) + nav.assert_search_mode_chip_visible() + nav.wait_for_suggestions_present() + + nav.click_first_suggestion_row() + nav.expect_in_content(EC.url_contains(GENERAL_ENGINE.lower())) + nav.clear_awesome_bar() + finally: + driver.close() + driver.switch_to.window(driver.window_handles[0]) From 130e6a9195325965d07c6c4e39b41cc2b090ef23 Mon Sep 17 00:00:00 2001 From: "virgil.sangerean" Date: Tue, 21 Oct 2025 15:52:18 +0300 Subject: [PATCH 2/5] vs/search-mode-persists --- SELECTOR_INFO.md | 7 +++++++ modules/data/about_prefs.components.json | 5 +++++ modules/page_object_prefs.py | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/SELECTOR_INFO.md b/SELECTOR_INFO.md index cf512adeb..61658329c 100644 --- a/SELECTOR_INFO.md +++ b/SELECTOR_INFO.md @@ -921,6 +921,13 @@ Location: about:preferences#general Language subsection Path to .json: modules/data/about_prefs.components.json ``` ``` +Selector Name: search-suggestion-in-private-windows +Selector Data: "showSearchSuggestionsPrivateWindows" +Description: Show search suggestions in Private Windows +Location: about:preferences#search +Path to .json: modules/data/about_prefs.components.json +``` +``` Selector Name: language-settings-search Selector Data: "menuitem[value='search']" Description: In the Language Set Alternatives dialog, the Select a language to add, Search for more languages… option diff --git a/modules/data/about_prefs.components.json b/modules/data/about_prefs.components.json index c1e5e3a9f..42547ccb4 100644 --- a/modules/data/about_prefs.components.json +++ b/modules/data/about_prefs.components.json @@ -355,6 +355,11 @@ "selectorData": "BrowserLanguagesDialog", "strategy": "id", "groups": [] + }, + "search-suggestion-in-private-windows": { + "selectorData": "showSearchSuggestionsPrivateWindows", + "strategy": "id", + "groups": [] }, "language-settings-select": { "selectorData": "[data-l10n-id='browser-languages-select-language']", diff --git a/modules/page_object_prefs.py b/modules/page_object_prefs.py index 2bc874bf1..37c575a6a 100644 --- a/modules/page_object_prefs.py +++ b/modules/page_object_prefs.py @@ -69,7 +69,7 @@ def enable_private_window_suggestions(self): """Enable 'Show search suggestions in Private Windows' if not already checked.""" from selenium.webdriver.common.by import By - checkbox = self.driver.find_element(By.ID, "showSearchSuggestionsPrivateWindows") + checkbox = self.get_element("search-suggestion-in-private-windows") if checkbox.get_attribute("checked") != "true": checkbox.click() return self From f9a1f173c0c78cb7eb5a67ab49c3635158df9d2f Mon Sep 17 00:00:00 2001 From: "virgil.sangerean" Date: Tue, 21 Oct 2025 16:01:28 +0300 Subject: [PATCH 3/5] vs/search-mode-persists --- modules/page_object_prefs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/page_object_prefs.py b/modules/page_object_prefs.py index 37c575a6a..94a97c329 100644 --- a/modules/page_object_prefs.py +++ b/modules/page_object_prefs.py @@ -5,7 +5,6 @@ from typing import List, Literal from selenium.webdriver import Firefox -from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC From eb5ae07726832dee9ad1af0fc80a18e42eaa9c36 Mon Sep 17 00:00:00 2001 From: "virgil.sangerean" Date: Tue, 21 Oct 2025 16:16:51 +0300 Subject: [PATCH 4/5] vs/search-mode-persists --- modules/page_object_prefs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/page_object_prefs.py b/modules/page_object_prefs.py index 94a97c329..37c575a6a 100644 --- a/modules/page_object_prefs.py +++ b/modules/page_object_prefs.py @@ -5,6 +5,7 @@ from typing import List, Literal from selenium.webdriver import Firefox +from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support import expected_conditions as EC From 7664f82796915c8d578d1996b7303a6b10970023 Mon Sep 17 00:00:00 2001 From: "virgil.sangerean" Date: Tue, 21 Oct 2025 16:21:24 +0300 Subject: [PATCH 5/5] vs/search-mode-persists --- modules/page_object_prefs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/page_object_prefs.py b/modules/page_object_prefs.py index 37c575a6a..a38616ec2 100644 --- a/modules/page_object_prefs.py +++ b/modules/page_object_prefs.py @@ -67,7 +67,6 @@ def find_in_settings(self, term: str) -> BasePage: def enable_private_window_suggestions(self): """Enable 'Show search suggestions in Private Windows' if not already checked.""" - from selenium.webdriver.common.by import By checkbox = self.get_element("search-suggestion-in-private-windows") if checkbox.get_attribute("checked") != "true":