Skip to content

Commit 4b1d2bd

Browse files
committed
vs/Refactoring 2
1 parent 93d8297 commit 4b1d2bd

14 files changed

+247
-230
lines changed

modules/page_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ def element_has_text(self, name: str, text: str, labels=[]) -> Page:
431431
self.expect(lambda _: text in self.get_element(name, labels=labels).text)
432432
return self
433433

434-
def element_attribute_contains(
434+
def expect_element_attribute_contains(
435435
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"""

modules/page_object_example_page.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from selenium.webdriver.common.by import By
2+
13
from modules.page_base import BasePage
24

35

@@ -10,3 +12,11 @@ class ExamplePage(BasePage):
1012
TITLE = "Example Domain"
1113
MORE_INFO_URL = "https://www.iana.org/help/example-domains"
1214
MORE_INFO_TITLE = "Example Domains"
15+
16+
@BasePage.context_content
17+
def search_selected_header_via_context_menu(self):
18+
"""Open the page, triple-click the <h1>, right-click it to trigger the context menu."""
19+
self.open()
20+
header = (By.TAG_NAME, "h1")
21+
self.triple_click(header)
22+
self.context_click(header)

tests/address_bar_and_search/test_adaptive_history_autofill.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
WAIT_TIMEOUT = 10
1010
TEST_URL = "https://www.nationalgeographic.com/science/"
1111
EXPECTED_TITLE = "Science"
12+
EXPECTED_TYPE = "autofill_adaptive"
13+
EXPECTED_TEXT_FRAGMENT = "nationalgeographic.com/science"
1214

1315

1416
@pytest.fixture()
@@ -28,24 +30,26 @@ def test_add_adaptive_history_autofill(driver: Firefox):
2830
nav = Navigation(driver)
2931
tabs = TabBar(driver)
3032

33+
# Step 1: Visit the test site and verify tab title
3134
nav.search(TEST_URL)
3235
WebDriverWait(driver, WAIT_TIMEOUT).until(
3336
lambda d: tabs.get_tab_title(tabs.get_tab(1)) == EXPECTED_TITLE
3437
)
3538

39+
# Step 2: Open new tab, close the original
3640
tabs.new_tab_by_button()
3741
tabs.wait_for_num_tabs(2)
3842
driver.switch_to.window(driver.window_handles[1])
39-
4043
with driver.context(driver.CONTEXT_CHROME):
4144
tabs.get_elements("tab-x-icon")[0].click()
4245

46+
# Step 3: Type in address bar, click adaptive suggestion
4347
nav.type_in_awesome_bar("nat")
4448
with driver.context(driver.CONTEXT_CHROME):
4549
nav.get_element("firefox-suggest").click()
46-
4750
nav.expect_in_content(EC.url_contains(TEST_URL))
4851

52+
# Step 4: Open new tab and check for autofill suggestion
4953
tabs.new_tab_by_button()
5054
tabs.wait_for_num_tabs(2)
5155
driver.switch_to.window(driver.window_handles[-1])
@@ -54,9 +58,9 @@ def test_add_adaptive_history_autofill(driver: Firefox):
5458
tabs.set_chrome_context()
5559
autofill_element = nav.get_element("search-result-autofill-adaptive-element")
5660

57-
assert autofill_element.get_attribute("type") == "autofill_adaptive", (
58-
f"Expected type 'autofill_adaptive', got '{autofill_element.get_attribute('type')}'"
61+
assert autofill_element.get_attribute("type") == EXPECTED_TYPE, (
62+
f"Expected type '{EXPECTED_TYPE}', got '{autofill_element.get_attribute('type')}'"
5963
)
60-
assert "nationalgeographic.com/science" in autofill_element.text, (
64+
assert EXPECTED_TEXT_FRAGMENT in autofill_element.text, (
6165
f"Autofill text did not contain expected URL. Got: {autofill_element.text}"
6266
)

tests/address_bar_and_search/test_add_engine_address_bar.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from modules.browser_object import ContextMenu, Navigation, TabBar
55

6+
TEST_URL = "https://youtube.com"
7+
EXPECTED_ENGINE = "YouTube"
68

79
@pytest.fixture()
810
def test_case():
@@ -22,17 +24,17 @@ def test_add_search_engine_from_address_bar(driver: Firefox):
2224
menu = ContextMenu(driver)
2325
tabs = TabBar(driver)
2426

25-
driver.get("https://youtube.com")
27+
driver.get(TEST_URL)
2628
nav.custom_wait(timeout=20).until(lambda d: "youtube.com" in d.current_url)
2729

2830
with driver.context(driver.CONTEXT_CHROME):
2931
nav.context_click_in_awesome_bar()
3032
menu.click_context_item("context-menu-add-search-engine")
3133

3234
tabs.new_tab_by_button()
33-
youtube_tab = tabs.get_tab_by_title("YouTube")
35+
youtube_tab = tabs.get_tab_by_title(EXPECTED_ENGINE)
3436
tabs.close_tab(youtube_tab)
3537

3638
nav.click_on("searchmode-switcher")
37-
nav.element_exists("search-mode-switcher-option", labels=["YouTube"])
39+
nav.element_exists("search-mode-switcher-option", labels=[EXPECTED_ENGINE])
3840
nav.click_on("searchmode-switcher")
Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
import pytest
2-
from selenium.common.exceptions import TimeoutException
32
from selenium.webdriver import Firefox
43
from selenium.webdriver.support import expected_conditions as EC
5-
from selenium.webdriver.support.ui import WebDriverWait
64

75
from modules.browser_object import Navigation
86

7+
WAIT_TIMEOUT = 10
98
ADDONS_BASE_URL = "https://addons.mozilla.org/en-US/firefox/addon/"
109

10+
INPUT_TO_ADDON_NAME = {
11+
"clips": "video-downloadhelper",
12+
"grammar": "languagetool",
13+
"Temp mail": "private-relay",
14+
"pics search": "search_by_image",
15+
"darker theme": "darkreader",
16+
"privacy": "privacy-badger17",
17+
"read aloud": "read-aloud",
18+
}
19+
1120

1221
@pytest.fixture()
1322
def test_case():
@@ -26,31 +35,16 @@ def test_addon_suggestion_based_on_search_input(driver: Firefox):
2635
"""
2736
C2234714 - Verify that the address bar suggests relevant add-ons based on search input.
2837
"""
29-
input_to_addon_name = {
30-
"clips": "video-downloadhelper",
31-
"grammar": "languagetool",
32-
"Temp mail": "private-relay",
33-
"pics search": "search_by_image",
34-
"darker theme": "darkreader",
35-
"privacy": "privacy-badger17",
36-
"read aloud": "read-aloud",
37-
}
38-
3938
nav = Navigation(driver)
4039
nav.set_awesome_bar()
4140

42-
for input_text, addon_name in input_to_addon_name.items():
41+
for input_text, addon_slug in INPUT_TO_ADDON_NAME.items():
4342
nav.type_in_awesome_bar(input_text)
44-
try:
45-
nav.element_visible("addon-suggestion")
46-
except TimeoutException:
47-
raise AssertionError(
48-
f"Addon suggestion not visible for input: '{input_text}'"
49-
)
5043

51-
nav.select_element_in_nav("addon-suggestion")
44+
if not nav.element_visible("addon-suggestion"):
45+
raise AssertionError(f"Addon suggestion not visible for input: '{input_text}'")
5246

53-
expected_url = f"{ADDONS_BASE_URL}{addon_name}/"
47+
nav.select_element_in_nav("addon-suggestion")
48+
expected_url = f"{ADDONS_BASE_URL}{addon_slug}/"
5449
nav.expect_in_content(EC.url_contains(expected_url))
55-
5650
nav.clear_awesome_bar()

tests/address_bar_and_search/test_default_search_provider_change_awesome_bar.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def test_default_search_provider_change_awesome_bar(driver: Firefox):
2424

2525
driver.get("about:newtab")
2626
nav.open_searchmode_switcher_settings()
27+
2728
prefs.search_engine_dropdown().select_option(SEARCH_ENGINE)
2829

2930
driver.get("about:newtab")
30-
nav.element_attribute_contains("awesome-bar", "placeholder", EXPECTED_PLACEHOLDER)
31+
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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,38 @@ def test_default_search_provider_change_legacy_search_bar(driver: Firefox):
2020
"""
2121
C1365245 - Verify that changing the default search provider is reflected in the legacy search bar.
2222
"""
23+
nav = Navigation(driver)
2324
panel_ui = PanelUi(driver)
2425
customize = CustomizeFirefox(driver)
25-
nav = Navigation(driver)
2626
tabs = TabBar(driver)
2727
prefs = AboutPrefs(driver, category="search")
2828

29+
# Add legacy search bar to toolbar
2930
panel_ui.open_panel_menu()
3031
panel_ui.navigate_to_customize_toolbar()
3132
customize.add_widget_to_toolbar("search-bar")
3233

34+
# Open a new tab and trigger search settings navigation
3335
tabs.new_tab_by_button()
3436
nav.type_in_search_bar(SEARCH_TERM)
3537
nav.click_on_change_search_settings_button()
3638
driver.switch_to.window(driver.window_handles[2])
3739
assert driver.current_url == SEARCH_SETTINGS_URL
3840

41+
# Validate navigation returns to site and settings page opens in new tab
3942
driver.get("https://9gag.com/")
4043
nav.type_in_search_bar(SEARCH_TERM)
4144
nav.click_on_change_search_settings_button()
4245
assert driver.current_url == "https://9gag.com/"
4346
driver.switch_to.window(driver.window_handles[3])
4447
assert driver.current_url == SEARCH_SETTINGS_URL
4548

49+
# Change the default search engine
4650
prefs.open()
4751
prefs.search_engine_dropdown().select_option(SEARCH_ENGINE)
48-
nav.type_in_search_bar(SEARCH_TERM)
4952

53+
# Perform another search and validate engine label
54+
nav.type_in_search_bar(SEARCH_TERM)
5055
with driver.context(driver.CONTEXT_CHROME):
5156
engine_name = driver.find_element(By.CSS_SELECTOR, ".searchbar-engine-name")
5257
assert engine_name.get_attribute("value") == EXPECTED_ENGINE_DISPLAY

tests/address_bar_and_search/test_glean_basic.py

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -11,92 +11,101 @@
1111
from werkzeug.wrappers import Request, Response
1212

1313
from modules.browser_object import Navigation
14-
from modules.page_object import AboutGlean, AboutPrefs, GenericPage
14+
from modules.page_object import AboutGlean, AboutPrefs, GenericPage, AboutConfig
1515
from modules.util import Utilities
1616

17+
# Constants
18+
SEARCH_TERM_GOOGLE = "trombone"
19+
SEARCH_TERM_BING = "trumpet"
20+
ENGINE_NAME_INITIAL = "Google"
21+
ENGINE_NAME_UPDATED = "Bing"
22+
EXPECTED_BING_LOCATOR = (By.ID, "b_context")
23+
EXPECTED_SEARCH_LOCATOR = (By.CSS_SELECTOR, "div[role='navigation']")
24+
PING_METRIC_PATH = ["metrics", "string", "search.engine.default.display_name"]
25+
WAIT_PING_SECONDS = 1
26+
27+
# Globals (used for tracking ping verification)
28+
pings_with_id = 0
29+
ping_id_global = ""
30+
1731

1832
@pytest.fixture()
1933
def test_case():
2034
return "2234689"
2135

2236

23-
PINGS_WITH_ID = 0
24-
PING_ID = ""
25-
26-
27-
def confirm_glean_correctness(
28-
ping_ground: str, ping_test: str, engine_ground: str, engine_test: str
29-
) -> bool:
30-
"""Helper to confirm that the glean ping contains expected info"""
31-
assert ping_ground == ping_test
32-
assert engine_ground.lower() == engine_test.lower()
33-
34-
35-
def glean_handler(rq: Request) -> Response:
36-
"""HTTP mock of Glean"""
37-
global PINGS_WITH_ID
38-
global PING_ID
39-
if "X-Debug-Id" in rq.headers.keys():
40-
ping_id = rq.headers["X-Debug-Id"]
41-
if rq.data:
42-
body = json.loads(gzip.decompress(rq.data).decode())
43-
engine_name = body["metrics"]["string"][
44-
"search.engine.default.display_name"
45-
]
46-
if PINGS_WITH_ID == 0:
47-
engine_ground = "Google"
48-
else:
49-
engine_ground = "Bing"
50-
confirm_glean_correctness(
51-
ping_ground=PING_ID,
52-
ping_test=ping_id,
53-
engine_ground=engine_ground,
54-
engine_test=engine_name,
37+
def _verify_glean_ping(ping_actual: str, ping_expected: str, engine_actual: str, engine_expected: str):
38+
assert ping_actual == ping_expected
39+
assert engine_actual.lower() == engine_expected.lower()
40+
41+
42+
def glean_handler(request: Request) -> Response:
43+
global pings_with_id, ping_id_global
44+
45+
if "X-Debug-Id" in request.headers:
46+
incoming_ping_id = request.headers["X-Debug-Id"]
47+
if request.data:
48+
decompressed = gzip.decompress(request.data).decode()
49+
body = json.loads(decompressed)
50+
engine_name = body
51+
for key in PING_METRIC_PATH:
52+
engine_name = engine_name[key]
53+
expected_engine = ENGINE_NAME_INITIAL if pings_with_id == 0 else ENGINE_NAME_UPDATED
54+
_verify_glean_ping(
55+
ping_actual=incoming_ping_id,
56+
ping_expected=ping_id_global,
57+
engine_actual=engine_name,
58+
engine_expected=expected_engine,
5559
)
56-
PINGS_WITH_ID += 1
60+
pings_with_id += 1
61+
5762
return Response("", status=200)
5863

5964

6065
@pytest.mark.unstable
66+
# Still unstable sometime due to Captcha.
6167
def test_glean_ping(driver: Firefox, httpserver: HTTPServer):
62-
"""C2234689: Test that Glean pings contain expected info"""
63-
global PINGS_WITH_ID
64-
global PING_ID
65-
u = Utilities()
68+
"""C2234689 - Test that Glean pings contain expected info"""
69+
70+
global pings_with_id, ping_id_global
71+
utils = Utilities()
6672

67-
# mock server
73+
# Setup mock server
6874
httpserver.expect_request(re.compile("^/")).respond_with_handler(glean_handler)
6975

70-
# Set ping name
71-
ping = u.random_string(8)
72-
PING_ID = ping
76+
# Configure Glean ping ID
77+
ping_id = utils.random_string(8)
78+
ping_id_global = ping_id
7379
about_glean = AboutGlean(driver)
7480
about_glean.open()
75-
about_glean.change_ping_id(ping)
81+
about_glean.change_ping_id(ping_id)
7682

77-
# Search 1 (Google)
83+
# Disable cookie banner
84+
about_config = AboutConfig(driver)
85+
about_config.change_config_value("cookiebanners.service.mode", 1)
86+
# Test is more stable if this is done here instead of prefs
87+
88+
# Perform search using default engine (Google)
7889
page = GenericPage(driver, url="")
7990
nav = Navigation(driver)
80-
nav.search("trombone")
91+
nav.search(SEARCH_TERM_GOOGLE)
8192
page.title_contains("Search")
82-
page.expect(
83-
EC.presence_of_element_located((By.CSS_SELECTOR, "div[role='navigation']"))
84-
)
93+
page.expect(EC.presence_of_element_located(EXPECTED_SEARCH_LOCATOR))
8594

86-
# Change default search engine
87-
about_prefs = AboutPrefs(driver, category="search")
88-
about_prefs.open()
89-
about_prefs.search_engine_dropdown().select_option("Bing")
95+
# Change default engine to Bing
96+
prefs = AboutPrefs(driver, category="search")
97+
prefs.open()
98+
prefs.search_engine_dropdown().select_option(ENGINE_NAME_UPDATED)
9099

91-
# Search 2 (Bing)
92-
nav = Navigation(driver)
100+
# Perform search using updated engine (Bing)
93101
nav.open()
94-
nav.search("trumpet")
102+
nav.search(SEARCH_TERM_BING)
95103
page.url_contains("bing.com")
96-
page.expect(EC.visibility_of_element_located((By.ID, "b_context")))
104+
page.expect(EC.visibility_of_element_located(EXPECTED_BING_LOCATOR))
97105

98-
# We could go back to about:glean, but this is faster
106+
# Send metrics ping
99107
with driver.context(driver.CONTEXT_CHROME):
100108
driver.execute_script('Services.fog.sendPing("metrics");')
101-
sleep(1)
102-
assert PINGS_WITH_ID == 2
109+
110+
sleep(WAIT_PING_SECONDS)
111+
assert pings_with_id == 2

0 commit comments

Comments
 (0)