22import re
33import time
44from typing import Literal
5+ from urllib .parse import urlparse
56
67from selenium .common .exceptions import StaleElementReferenceException , TimeoutException
78from selenium .webdriver import ActionChains , Firefox
@@ -90,15 +91,6 @@ def type_in_awesome_bar(self, term: str) -> BasePage:
9091 self .awesome_bar .send_keys (term )
9192 return self
9293
93- @BasePage .context_chrome
94- def press_ctrl_enter (self ) -> BasePage :
95- """Press Ctrl/Cmd + Enter in Awesome Bar."""
96- if self .sys_platform () == "Darwin" :
97- self .perform_key_combo (Keys .COMMAND , Keys .ENTER )
98- else :
99- self .perform_key_combo (Keys .CONTROL , Keys .ENTER )
100- return self
101-
10294 def set_search_mode_via_awesome_bar (self , mode : str ) -> BasePage :
10395 """
10496 Given a `mode`, set the Awesome Bar search mode. Returns self.
@@ -382,10 +374,11 @@ def wait_for_suggestions_absent(self):
382374 self .element_not_visible ("suggestion-titles" )
383375 return self
384376
385- def open_usb_and_select_engine (self , engine_title : str ):
386- """Click the USB icon and select a search engine by its title."""
377+ @BasePage .context_chrome
378+ def open_usb_and_select_option (self , option_title : str ):
379+ """Click the USB icon and select an option by its title."""
387380 self .get_element ("searchmode-switcher" ).click ()
388- self .get_element ("search-mode-switcher-option" , labels = [engine_title ]).click ()
381+ self .get_element ("search-mode-switcher-option" , labels = [option_title ]).click ()
389382 return self
390383
391384 def assert_search_mode_chip_visible (self ):
@@ -394,6 +387,40 @@ def assert_search_mode_chip_visible(self):
394387 self .get_element ("search-mode-span" )
395388 return self
396389
390+ @BasePage .context_chrome
391+ def verify_search_mode_is_visible (self ):
392+ """Ensure the search mode is visible in URLbar"""
393+ self .element_visible ("search-mode-chicklet" )
394+ return self
395+
396+ @BasePage .context_chrome
397+ def verify_search_mode_is_not_visible (self ):
398+ """Ensure the search mode is cleared from URLbar"""
399+ self .element_not_visible ("search-mode-chicklet" )
400+ return self
401+
402+ @BasePage .context_chrome
403+ def verify_search_mode_label (self , engine_name : str ):
404+ """Verify that the search mode chicklet displays the correct engine."""
405+ chicklet = self .get_element ("search-mode-chicklet" )
406+ chip_text = (
407+ chicklet .text or chicklet .get_attribute ("aria-label" ) or ""
408+ ).lower ()
409+ assert engine_name .lower () in chip_text , (
410+ f"Expected search mode engine '{ engine_name } ', got '{ chip_text } '"
411+ )
412+ return self
413+
414+ @BasePage .context_chrome
415+ def verify_plain_text_in_input_awesome_bar (self , expected_text : str ):
416+ """Verify the awesomebar input contains the exact literal text."""
417+ input_el = self .get_element ("awesome-bar" )
418+ value = input_el .get_attribute ("value" )
419+ assert value == expected_text , (
420+ f"Expected input '{ expected_text } ', got '{ value } '"
421+ )
422+ return self
423+
397424 def click_first_suggestion_row (self ):
398425 """
399426 Clicks the first visible suggestion row in the list, using robust scrolling and fallback.
@@ -907,6 +934,27 @@ def verify_status_panel_url(self, expected_url: str):
907934 f"Expected '{ expected_url } ' in status panel URL, got '{ actual_url } '"
908935 )
909936
937+ @BasePage .context_content
938+ def verify_domain (self , expected_domain : str ) -> None :
939+ """
940+ Verify that the current URL's domain matches the expected domain using urlparse.
941+ This explicitly checks the domain (netloc) rather than just a substring match.
942+ Uses content context to get the actual page URL.
943+
944+ Argument:
945+ expected_domain: The expected domain (e.g., "wikipedia.org", "google.com")
946+ """
947+
948+ def _domain_matches (_ ):
949+ parsed = urlparse (self .driver .current_url )
950+ return expected_domain in parsed .netloc
951+
952+ self .custom_wait (timeout = 15 ).until (_domain_matches )
953+ parsed_url = urlparse (self .driver .current_url )
954+ assert expected_domain in parsed_url .netloc , (
955+ f"Expected '{ expected_domain } ' domain, got '{ parsed_url .netloc } '"
956+ )
957+
910958 @BasePage .context_chrome
911959 def verify_engine_returned (self , engine : str ) -> None :
912960 """
@@ -996,3 +1044,15 @@ def add_search_bar_to_toolbar(self) -> BasePage:
9961044 self .panel_ui .navigate_to_customize_toolbar ()
9971045 self .customize .add_widget_to_toolbar ("search-bar" )
9981046 return self
1047+
1048+ @BasePage .context_chrome
1049+ def click_exit_button_searchmode (self ) -> None :
1050+ """
1051+ Click the 'Exit' button in the search mode.
1052+ Waits until the button is visible and clickable before performing the click.
1053+ """
1054+ # Wait until the element is visible and clickable
1055+ self .expect (lambda _ : self .get_element ("exit-button-searchmode" ).is_displayed ())
1056+
1057+ # Click the button
1058+ self .get_element ("exit-button-searchmode" ).click ()
0 commit comments