Skip to content

Commit f95867a

Browse files
authored
Merge pull request #82 from mozilla/as/add-on-suggestion
As/addon suggestion based on search input
2 parents 11aaf4d + 1a3ebf4 commit f95867a

File tree

9 files changed

+93
-17
lines changed

9 files changed

+93
-17
lines changed

ci_pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ markers = [
77
"pynput: test uses pynput package",
88
"incident: incident smoke tests",
99
"unstable: temporary mark for unstable tests",
10+
"slow: test is clocked at more than 30s on modern machines",
1011
"ci: basic tests to run in ci",
1112
"locale_de: tests run in DE locale versions",
1213
"locale_fr: tests run in FR locale versions",

dev_pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ markers = [
88
"pynput: test uses pynput package",
99
"incident: incident smoke tests",
1010
"unstable: temporary mark for unstable tests",
11+
"slow: test is clocked at more than 30s on modern machines",
1112
"ci: basic tests to run in ci",
1213
"locale_de: tests run in DE locale versions",
1314
"locale_fr: tests run in FR locale versions",

modules/data/navigation.components.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@
134134
"groups": []
135135
},
136136

137+
"addon-suggestion": {
138+
"selectorData": "div.urlbarView-row[type='rust_amo'] span.urlbarView-title.urlbarView-overflowable",
139+
"strategy": "css",
140+
"groups": []
141+
},
142+
137143
"search-suggestion-list": {
138144
"selectorData": "div.urlbarView-row[type='search_engine'] span.urlbarView-title",
139145
"strategy": "css",

modules/page_object.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
from modules.page_object_about_newtab import *
66
from modules.page_object_about_prefs import *
77
from modules.page_object_about_profiles import *
8+
from modules.page_object_about_telemetry import *
89
from modules.page_object_addons_mozilla_org import *
910
from modules.page_object_autofill_credit_card import *
1011
from modules.page_object_autofill_test_basic import *
1112
from modules.page_object_example_page import *
1213
from modules.page_object_generic_pdf import *
1314
from modules.page_object_google_search import *
1415
from modules.page_object_wiki_firefox_logo import *
15-
from modules.page_object_about_telemetry import *

modules/util.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
import re
77
from os import remove
88
from random import shuffle
9-
from typing import Union
10-
from jsonpath_ng import parse
119
from typing import Literal, Union
1210

1311
from faker import Faker
1412
from faker.providers import internet, misc
13+
from jsonpath_ng import parse
1514
from PIL import Image
1615
from pynput.keyboard import Controller, Key
1716
from selenium.common.exceptions import (
@@ -316,7 +315,10 @@ def assert_json_value(self, json_data, jsonpath_expr, expected_value):
316315
"""Parse json and validate json search string with its value"""
317316
expr = parse(jsonpath_expr)
318317
match = expr.find(json_data)
319-
return match[0].value == expected_value, f"Expected {expected_value}, but got {match[0].value}"
318+
return (
319+
match[0].value == expected_value,
320+
f"Expected {expected_value}, but got {match[0].value}",
321+
)
320322

321323

322324
class BrowserActions:
@@ -382,15 +384,15 @@ def search(self, term: str, with_enter=True):
382384
url_bar.send_keys(term)
383385

384386
def filter_elements_by_attr(
385-
self, elements: list[WebElement], attr: str, value: str
387+
self, elements: list[WebElement], attr: str, value: str
386388
) -> list[WebElement]:
387389
"""
388390
Given a list of WebElements, return the ones where attribute `attr` has value `value`.
389391
"""
390392
return [el for el in elements if el.get_attribute(attr) == value]
391393

392394
def pick_element_from_list_by_text(
393-
self, elements: list[WebElement], substr: str
395+
self, elements: list[WebElement], substr: str
394396
) -> WebElement:
395397
"""
396398
Given a list of WebElements, return the one where innerText matches `substr`.
@@ -481,7 +483,7 @@ def __init__(self, driver: Firefox):
481483
self.driver = driver
482484

483485
def get_shadow_content(
484-
self, element: WebElement
486+
self, element: WebElement
485487
) -> list[Union[WebElement, ShadowRoot]]:
486488
"""
487489
Given a WebElement, return the shadow DOM root or roots attached to it. Returns a list.
@@ -515,7 +517,7 @@ def shadow_from_script():
515517
return []
516518

517519
def css_selector_matches_element(
518-
self, element: Union[WebElement, ShadowRoot], selector: list
520+
self, element: Union[WebElement, ShadowRoot], selector: list
519521
) -> bool:
520522
if type(element) == ShadowRoot:
521523
return False
@@ -525,7 +527,7 @@ def css_selector_matches_element(
525527
)
526528

527529
def find_shadow_chrome_element(
528-
self, nodes: list[WebElement], selector: list
530+
self, nodes: list[WebElement], selector: list
529531
) -> Union[WebElement, None]:
530532
logging.info("Selecting element in Chrome Context Shadow DOM...")
531533
if selector[0] not in self.allowed_selectors_shadow_chrome_element:
@@ -551,11 +553,11 @@ def find_shadow_chrome_element(
551553
return None
552554

553555
def find_shadow_element(
554-
self,
555-
shadow_parent: Union[WebElement, ShadowRoot],
556-
selector: list,
557-
multiple=False,
558-
context="content",
556+
self,
557+
shadow_parent: Union[WebElement, ShadowRoot],
558+
selector: list,
559+
multiple=False,
560+
context="content",
559561
) -> WebElement:
560562
"""
561563
Given a WebElement with a shadow root attached, find a selector in the

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ markers = [
88
"pynput: test uses pynput package",
99
"incident: incident smoke tests",
1010
"unstable: temporary mark for unstable tests",
11+
"slow: test is clocked at more than 30s on modern machines",
1112
"ci: basic tests to run in ci",
1213
"locale_de: tests run in DE locale versions",
1314
"locale_fr: tests run in FR locale versions",
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import time
2+
3+
import pytest
4+
from selenium.webdriver import Firefox
5+
from selenium.webdriver.support import expected_conditions as EC
6+
7+
from modules.browser_object import Navigation
8+
9+
10+
@pytest.fixture()
11+
def add_prefs():
12+
return [
13+
("browser.search.region", "US"),
14+
]
15+
16+
17+
@pytest.mark.slow
18+
def test_addon_suggestion_based_on_search_input(driver: Firefox):
19+
"""
20+
C2234714: Test that add-on suggestions match the URL bar input.
21+
22+
To avoid lengthy waits caused by network traffic during browser startup,
23+
this test loops through the list of addons in a single browser session
24+
instead of using parameterization. This reduces the overall test duration
25+
by waiting for the network traffic only once.
26+
"""
27+
28+
# Map input text to addon names
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+
39+
nav = Navigation(driver).open()
40+
time.sleep(20)
41+
nav.set_awesome_bar()
42+
time.sleep(20)
43+
nav.awesome_bar.click()
44+
45+
for input_text, addon_name in input_to_addon_name.items():
46+
nav.awesome_bar.send_keys(input_text)
47+
nav.element_visible("addon-suggestion")
48+
nav.get_element("addon-suggestion").click()
49+
50+
# Construct the expected URL
51+
expected_url = f"https://addons.mozilla.org/en-US/firefox/addon/{addon_name}/"
52+
nav.expect_in_content(EC.url_contains(expected_url))
53+
54+
nav.awesome_bar.clear()

tests/address_bar_and_search/test_google_search_counts_us.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import time
2+
23
import pytest
34
from selenium.webdriver import Firefox
45

56
from modules.browser_object import Navigation
67
from modules.page_object import AboutTelemetry
7-
88
from modules.util import Utilities
99

10+
1011
# unstable: for some reason cannot pass in Taskcluster Linux VM
1112
@pytest.mark.unstable
1213
def test_google_search_counts_us(driver: Firefox):
@@ -27,5 +28,11 @@ def test_google_search_counts_us(driver: Firefox):
2728

2829
# Verify pings are recorded
2930
json_data = u.decode_url(driver)
30-
assert u.assert_json_value(json_data, '$..SEARCH_COUNTS.["google-b-1-d.urlbar"].sum', 1)
31-
assert u.assert_json_value(json_data, '$..["browser.search.content.urlbar"].["google:tagged:firefox-b-1-d"]', 1)
31+
assert u.assert_json_value(
32+
json_data, '$..SEARCH_COUNTS.["google-b-1-d.urlbar"].sum', 1
33+
)
34+
assert u.assert_json_value(
35+
json_data,
36+
'$..["browser.search.content.urlbar"].["google:tagged:firefox-b-1-d"]',
37+
1,
38+
)

tests/address_bar_and_search/test_suggestion_engine_selection.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def add_prefs():
1616

1717
@pytest.mark.parametrize("site", sites)
1818
def test_search_suggestion_for_engine_selection(driver: Firefox, site: str):
19+
"""
20+
C1365228 - Test to verify that when entering "@", a list of search engines is suggested, and upon selecting an
21+
engine, the search is performed using the selected engine.
22+
"""
1923
nav = Navigation(driver).open()
2024
nav.type_in_awesome_bar("@")
2125
nav.element_has_text("results-dropdown", f"Search with {site}")

0 commit comments

Comments
 (0)