Skip to content

Commit 7ffd1c8

Browse files
Merge pull request #584 from mozilla/vs/Refactoring3
VS/Refactoring address bar and search
2 parents 2622c00 + 2028abd commit 7ffd1c8

15 files changed

+153
-106
lines changed

modules/browser_object_navigation.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ def set_search_mode_via_awesome_bar(self, mode: str) -> BasePage:
106106
)
107107
return self
108108

109+
@BasePage.context_chrome
110+
def click_firefox_suggest(self) -> None:
111+
"""Click the Firefox suggested result."""
112+
self.get_element("firefox-suggest").click()
113+
109114
@BasePage.context_chrome
110115
def search(self, term: str, mode=None) -> BasePage:
111116
"""
@@ -215,6 +220,7 @@ def set_search_mode(self, search_mode: str) -> BasePage:
215220
self.get_element("search-mode-switcher-option", labels=[search_mode]).click()
216221
return self
217222

223+
@BasePage.context_chrome
218224
def context_click_in_awesome_bar(self) -> BasePage:
219225
self.set_awesome_bar()
220226
actions = ActionChains(self.driver)
@@ -390,3 +396,8 @@ def confirm_bookmark_exists(self, match_string: str) -> BasePage:
390396
)
391397
assert matches_short_string or matches_long_string
392398
return self
399+
400+
@BasePage.context_chrome
401+
def get_legacy_search_engine_label(self) -> str:
402+
"""Return the displayed engine name from the legacy search bar."""
403+
return self.driver.find_element(By.CSS_SELECTOR, ".searchbar-engine-name").get_attribute("value")

modules/browser_object_tabbar.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ def reopen_closed_tab_by_keys(self, sys_platform: str) -> BasePage:
7777
).key_up(Keys.SHIFT).key_up(Keys.CONTROL).perform()
7878
return self
7979

80+
@BasePage.context_chrome
81+
def close_first_tab_by_icon(self) -> None:
82+
"""Click the close icon on the first tab."""
83+
self.get_elements("tab-x-icon")[0].click()
84+
8085
@BasePage.context_chrome
8186
def click_tab_by_title(self, title: str) -> BasePage:
8287
"""Given a full page title, click the corresponding tab"""

modules/page_base.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def get_selector(self, name: str, labels=[]) -> list:
255255
return selector
256256

257257
def get_element(
258-
self, name: str, multiple=False, parent_element=None, labels=[]
258+
self, name: str, multiple=False, parent_element=None, labels=[]
259259
) -> Union[list[WebElement], WebElement]:
260260
"""
261261
Given a key for a self.elements dict entry, return the Selenium WebElement(s).
@@ -377,7 +377,7 @@ def get_elements(self, name: str, labels=[]):
377377
return self.get_element(name, multiple=True, labels=labels)
378378

379379
def get_parent_of(
380-
self, reference: Union[str, tuple, WebElement], labels=[]
380+
self, reference: Union[str, tuple, WebElement], labels=[]
381381
) -> WebElement:
382382
"""
383383
Given a name + labels, a WebElement, or a tuple, return the direct parent node of the element.
@@ -400,15 +400,15 @@ def element_visible(self, name: str, labels=[]) -> Page:
400400
"""Expect helper: wait until element is visible or timeout"""
401401
self.expect(
402402
lambda _: self.get_element(name, labels=labels)
403-
and self.get_element(name, labels=labels).is_displayed()
403+
and self.get_element(name, labels=labels).is_displayed()
404404
)
405405
return self
406406

407407
def element_not_visible(self, name: str, labels=[]) -> Page:
408408
"""Expect helper: wait until element is not visible or timeout"""
409409
self.expect(
410410
lambda _: self.get_elements(name, labels=labels) == []
411-
or not self.get_element(name, labels=labels).is_displayed()
411+
or not self.get_element(name, labels=labels).is_displayed()
412412
)
413413
return self
414414

@@ -422,7 +422,7 @@ def element_selected(self, name: str, labels=[]) -> Page:
422422
"""Expect helper: wait until element is selected or timeout"""
423423
self.expect(
424424
lambda _: self.get_element(name, labels=labels)
425-
and self.get_element(name, labels=labels).is_selected()
425+
and self.get_element(name, labels=labels).is_selected()
426426
)
427427
return self
428428

@@ -432,13 +432,13 @@ def element_has_text(self, name: str, text: str, labels=[]) -> Page:
432432
return self
433433

434434
def expect_element_attribute_contains(
435-
self, name: str, attr_name: str, attr_value: Union[str, float, int], labels=[]
435+
self, name: str, attr_name: str, attr_value: Union[str, float, int], labels=[]
436436
) -> Page:
437437
"""Expect helper: wait until element attribute contains certain value"""
438438
self.expect(
439439
lambda _: self.get_element(name, labels=labels)
440-
and str(attr_value)
441-
in self.get_element(name, labels=labels).get_attribute(attr_name)
440+
and str(attr_value)
441+
in self.get_element(name, labels=labels).get_attribute(attr_name)
442442
)
443443
return self
444444

@@ -468,7 +468,7 @@ def verify_opened_image_url(self, url_substr: str, pattern: str) -> Page:
468468
return self
469469

470470
def fill(
471-
self, name: str, term: str, clear_first=True, press_enter=True, labels=[]
471+
self, name: str, term: str, clear_first=True, press_enter=True, labels=[]
472472
) -> Page:
473473
"""
474474
Get a fillable element and fill it with text. Return self.
@@ -527,7 +527,7 @@ def click_on(self, reference: Union[str, tuple, WebElement], labels=[]) -> Page:
527527
return self
528528

529529
def multi_click(
530-
self, iters: int, reference: Union[str, tuple, WebElement], labels=[]
530+
self, iters: int, reference: Union[str, tuple, WebElement], labels=[]
531531
) -> Page:
532532
"""Perform multiple clicks at once on an element by name, selector, or WebElement"""
533533
with self.driver.context(self.context_id):
@@ -559,7 +559,7 @@ def triple_click(self, reference: Union[str, tuple, WebElement], labels=[]) -> P
559559
return self.multi_click(3, reference, labels)
560560

561561
def context_click(
562-
self, reference: Union[str, tuple, WebElement], labels=[]
562+
self, reference: Union[str, tuple, WebElement], labels=[]
563563
) -> Page:
564564
"""Context (right-) click on an element"""
565565
with self.driver.context(self.context_id):
@@ -595,7 +595,7 @@ def undo(self) -> Page:
595595
return self
596596

597597
def paste_to_element(
598-
self, sys_platform, reference: Union[str, tuple, WebElement], labels=[]
598+
self, sys_platform, reference: Union[str, tuple, WebElement], labels=[]
599599
) -> Page:
600600
"""Paste the copied item into the element"""
601601
with self.driver.context(self.context_id):
@@ -608,7 +608,7 @@ def paste_to_element(
608608
return self
609609

610610
def copy_image_from_element(
611-
self, keyboard, reference: Union[str, tuple, WebElement], labels=[]
611+
self, keyboard, reference: Union[str, tuple, WebElement], labels=[]
612612
) -> Page:
613613
"""Copy from the given element using right click (pynput)"""
614614
with self.driver.context(self.context_id):
@@ -623,7 +623,7 @@ def copy_image_from_element(
623623
return self
624624

625625
def copy_selection(
626-
self, keyboard, reference: Union[str, tuple, WebElement], labels=[]
626+
self, keyboard, reference: Union[str, tuple, WebElement], labels=[]
627627
) -> Page:
628628
"""Copy from the current selection using right click (pynput)"""
629629
with self.driver.context(self.context_id):
@@ -636,7 +636,7 @@ def copy_selection(
636636
return self
637637

638638
def click_and_hide_menu(
639-
self, reference: Union[str, tuple, WebElement], labels=[]
639+
self, reference: Union[str, tuple, WebElement], labels=[]
640640
) -> Page:
641641
"""Click an option in a context menu, then hide it"""
642642
with self.driver.context(self.driver.CONTEXT_CHROME):
@@ -667,7 +667,7 @@ def scroll_to_element(self, reference: Union[str, tuple, WebElement], labels=[])
667667
return self
668668

669669
def get_all_children(
670-
self, reference: Union[str, tuple, WebElement], labels=[]
670+
self, reference: Union[str, tuple, WebElement], labels=[]
671671
) -> List[WebElement]:
672672
"""
673673
Gets all the children of a webelement
@@ -679,7 +679,7 @@ def get_all_children(
679679
return children
680680

681681
def wait_for_no_children(
682-
self, parent: Union[str, tuple, WebElement], labels=[]
682+
self, parent: Union[str, tuple, WebElement], labels=[]
683683
) -> Page:
684684
"""
685685
Waits for 0 children under the given parent, the wait is instant (note, this changes the driver implicit wait and changes it back)
@@ -840,7 +840,7 @@ def handle_os_download_confirmation(self, keyboard: Controller, sys_platform: st
840840
keyboard.release(Key.enter)
841841

842842
def hide_popup_by_child_node(
843-
self, reference: Union[str, tuple, WebElement], labels=[], retry=False
843+
self, reference: Union[str, tuple, WebElement], labels=[], retry=False
844844
) -> Page:
845845
try:
846846
with self.driver.context(self.context_id):

modules/util.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ def __init__(self):
106106
self.fake = None
107107
self.locale = None
108108

109+
def assert_search_code_in_url(self, driver, nav, expected_code):
110+
assert expected_code in driver.current_url, (
111+
f"Expected '{expected_code}' in URL, got: {driver.current_url}"
112+
)
113+
nav.clear_awesome_bar()
114+
109115
def remove_file(self, path: str):
110116
try:
111117
os.remove(path)

tests/address_bar_and_search/test_adaptive_history_autofill.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,11 @@ def test_add_adaptive_history_autofill(driver: Firefox):
4040
tabs.new_tab_by_button()
4141
tabs.wait_for_num_tabs(2)
4242
driver.switch_to.window(driver.window_handles[1])
43-
with driver.context(driver.CONTEXT_CHROME):
44-
tabs.get_elements("tab-x-icon")[0].click()
43+
tabs.close_first_tab_by_icon()
4544

4645
# Step 3: Type in address bar, click adaptive suggestion
4746
nav.type_in_awesome_bar("nat")
48-
with driver.context(driver.CONTEXT_CHROME):
49-
nav.get_element("firefox-suggest").click()
47+
nav.click_firefox_suggest()
5048
nav.expect_in_content(EC.url_contains(TEST_URL))
5149

5250
# Step 4: Open new tab and check for autofill suggestion

tests/address_bar_and_search/test_add_engine_address_bar.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,33 @@ def test_case():
1313

1414

1515
@pytest.fixture()
16-
def hard_quit():
16+
def hard_quit() -> bool:
17+
"""Ensure Firefox quits cleanly after the test."""
1718
return True
1819

1920

2021
def test_add_search_engine_from_address_bar(driver: Firefox):
2122
"""
22-
C1365478 - Verify that Open Search engines can be added via the address bar context menu.
23+
C1365478 - Verify that OpenSearch engines can be added via the address bar context menu.
2324
"""
2425
nav = Navigation(driver)
2526
menu = ContextMenu(driver)
2627
tabs = TabBar(driver)
2728

29+
# Step 1: Open target site
2830
driver.get(TEST_URL)
2931
nav.custom_wait(timeout=20).until(lambda d: "youtube.com" in d.current_url)
3032

31-
with driver.context(driver.CONTEXT_CHROME):
32-
nav.context_click_in_awesome_bar()
33-
menu.click_context_item("context-menu-add-search-engine")
33+
# Step 2: Open context menu on address bar and click "Add search engine"
34+
nav.context_click_in_awesome_bar()
35+
menu.click_context_item("context-menu-add-search-engine")
3436

35-
tabs.new_tab_by_button()
36-
youtube_tab = tabs.get_tab_by_title(EXPECTED_ENGINE)
37-
tabs.close_tab(youtube_tab)
37+
# Step 3: A new tab should open with the engine config page, close it
38+
tabs.new_tab_by_button()
39+
youtube_tab = tabs.get_tab_by_title(EXPECTED_ENGINE)
40+
tabs.close_tab(youtube_tab)
3841

39-
nav.click_on("searchmode-switcher")
40-
nav.element_exists("search-mode-switcher-option", labels=[EXPECTED_ENGINE])
41-
nav.click_on("searchmode-switcher")
42+
# Step 4: Open search mode switcher and verify engine is listed
43+
nav.click_on("searchmode-switcher")
44+
nav.element_exists("search-mode-switcher-option", labels=[EXPECTED_ENGINE])
45+
nav.click_on("searchmode-switcher") # close dropdown

tests/address_bar_and_search/test_default_search_provider_change_awesome_bar.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ def test_default_search_provider_change_awesome_bar(driver: Firefox):
2222
nav = Navigation(driver)
2323
prefs = AboutPrefs(driver)
2424

25+
# Step 1: Open new tab and go to search engine settings
2526
driver.get("about:newtab")
2627
nav.open_searchmode_switcher_settings()
2728

29+
# Step 2: Change the default search engine
2830
prefs.search_engine_dropdown().select_option(SEARCH_ENGINE)
2931

32+
# Step 3: Re-open new tab and verify placeholder
3033
driver.get("about:newtab")
31-
nav.expect_element_attribute_contains(
32-
"awesome-bar", "placeholder", EXPECTED_PLACEHOLDER
33-
)
34+
nav.expect_element_attribute_contains("awesome-bar", "placeholder", EXPECTED_PLACEHOLDER)

tests/address_bar_and_search/test_default_search_provider_change_legacy_search_bar.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import pytest
22
from selenium.webdriver import Firefox
3-
from selenium.webdriver.common.by import By
43

54
from modules.browser_object import Navigation, PanelUi, TabBar
65
from modules.page_object import AboutPrefs, CustomizeFirefox
@@ -26,32 +25,31 @@ def test_default_search_provider_change_legacy_search_bar(driver: Firefox):
2625
tabs = TabBar(driver)
2726
prefs = AboutPrefs(driver, category="search")
2827

29-
# Add legacy search bar to toolbar
28+
# Step 1: Add legacy search bar to toolbar
3029
panel_ui.open_panel_menu()
3130
panel_ui.navigate_to_customize_toolbar()
3231
customize.add_widget_to_toolbar("search-bar")
3332

34-
# Open a new tab and trigger search settings navigation
33+
# Step 2: Open a new tab and trigger search settings from search bar
3534
tabs.new_tab_by_button()
3635
nav.type_in_search_bar(SEARCH_TERM)
3736
nav.click_on_change_search_settings_button()
3837
driver.switch_to.window(driver.window_handles[2])
3938
assert driver.current_url == SEARCH_SETTINGS_URL
4039

41-
# Validate navigation returns to site and settings page opens in new tab
40+
# Step 3: Open site, repeat nav to settings (validates correct tab handling)
4241
driver.get("https://9gag.com/")
4342
nav.type_in_search_bar(SEARCH_TERM)
4443
nav.click_on_change_search_settings_button()
4544
assert driver.current_url == "https://9gag.com/"
4645
driver.switch_to.window(driver.window_handles[3])
4746
assert driver.current_url == SEARCH_SETTINGS_URL
4847

49-
# Change the default search engine
48+
# Step 4: Change the default search engine
5049
prefs.open()
5150
prefs.search_engine_dropdown().select_option(SEARCH_ENGINE)
5251

53-
# Perform another search and validate engine label
52+
# Step 5: Perform another search and validate engine label (via decorated method)
5453
nav.type_in_search_bar(SEARCH_TERM)
55-
with driver.context(driver.CONTEXT_CHROME):
56-
engine_name = driver.find_element(By.CSS_SELECTOR, ".searchbar-engine-name")
57-
assert engine_name.get_attribute("value") == EXPECTED_ENGINE_DISPLAY
54+
engine_label = nav.get_legacy_search_engine_label()
55+
assert engine_label == EXPECTED_ENGINE_DISPLAY

0 commit comments

Comments
 (0)