Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c1316dc
stabilize autofill tests
ben-c-at-moz Oct 13, 2025
f89ac53
add selectors
ben-c-at-moz Oct 13, 2025
45bf766
Anca/ Stabilization on allow audio-video (#834)
soncuteanca Oct 14, 2025
63397ea
Hani/ Refactor tabs batch 2 (#824)
sv-hyacoub Oct 14, 2025
848c9eb
Update example.com hyperlink (#835)
Tracy-Walker Oct 14, 2025
aa94934
Vs/Add tests for seach modes persistance with @bing (#838)
vsangereanMOZ Oct 14, 2025
c322021
stabilize autofill tests
ben-c-at-moz Oct 13, 2025
a0403af
add selectors
ben-c-at-moz Oct 13, 2025
2f83970
Merge branch 'ben/stabilize-autofill' of github.com:mozilla/fx-deskto…
ben-c-at-moz Oct 14, 2025
8511f0c
Tracy/ Skip new failing tests (#839)
Tracy-Walker Oct 14, 2025
109f57a
stabilize autofill tests
ben-c-at-moz Oct 13, 2025
42d2152
add selectors
ben-c-at-moz Oct 13, 2025
69eafb8
Merge branch 'ben/stabilize-autofill' of github.com:mozilla/fx-deskto…
ben-c-at-moz Oct 14, 2025
706954a
modify one selector
ben-c-at-moz Oct 14, 2025
6a3fc08
check running version is actually correct
ben-c-at-moz Oct 14, 2025
e963d91
attempt to force CI machine to see payment/address buttons in prefs
ben-c-at-moz Oct 14, 2025
c0f49db
get loc of installed win fx
ben-c-at-moz Oct 14, 2025
cc05964
just test the version for now
ben-c-at-moz Oct 14, 2025
3bf9fc8
test quotes for exec
ben-c-at-moz Oct 14, 2025
ea9c0be
test quotes for exec
ben-c-at-moz Oct 14, 2025
249b4cc
test win path again
ben-c-at-moz Oct 15, 2025
b396cd0
test win path again
ben-c-at-moz Oct 15, 2025
d1df827
test win path again
ben-c-at-moz Oct 15, 2025
b25316a
test win path again
ben-c-at-moz Oct 15, 2025
35e18b4
test win path again
ben-c-at-moz Oct 15, 2025
c625f42
test win path again
ben-c-at-moz Oct 15, 2025
e816258
add log to see binary location
philimon-reset Oct 15, 2025
1910d3f
see full capabilities object
philimon-reset Oct 15, 2025
af1312b
see full capabilities object
philimon-reset Oct 15, 2025
4e3a032
remove lines
philimon-reset Oct 15, 2025
6406efb
test win path again, sleep
ben-c-at-moz Oct 15, 2025
aeb8fd4
Merge branch 'ben/stabilize-autofill' of github.com:mozilla/fx-deskto…
ben-c-at-moz Oct 15, 2025
ae96758
test win path again, sleep
ben-c-at-moz Oct 15, 2025
00b8d74
test win path again
ben-c-at-moz Oct 15, 2025
fd3d44d
test win path again
ben-c-at-moz Oct 15, 2025
6cff6ea
test win path again
ben-c-at-moz Oct 15, 2025
b2cf173
try to force a write of fx location
ben-c-at-moz Oct 15, 2025
94050fe
try to force a write of fx location
ben-c-at-moz Oct 15, 2025
182c7e5
attempt to disable Se driver mgmt
ben-c-at-moz Oct 15, 2025
0b4c5c5
attempt to disable Se driver mgmt
ben-c-at-moz Oct 15, 2025
d37dc4b
attempt to disable Se driver mgmt
ben-c-at-moz Oct 15, 2025
a499274
attempt to run again
ben-c-at-moz Oct 15, 2025
ffed07e
remove debug
ben-c-at-moz Oct 15, 2025
5b1a102
remove debug
ben-c-at-moz Oct 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
$env:FX_EXECUTABLE = "C:\Program Files\Custom Firefox\firefox.exe"
Start-Process -FilePath $env:FX_EXECUTABLE -ArgumentList "--version" -Wait -NoNewWindow
pipenv run python choose_ci_set.py
pipenv run pytest $(cat selected_tests)
pipenv run pytest --geckodriver geckodriver.exe $(cat selected_tests)
$env:TEST_EXIT_CODE = $LASTEXITCODE
mv artifacts artifacts-win || true
exit $env:TEST_EXIT_CODE
Expand All @@ -120,7 +120,7 @@ jobs:
mv ./ci_pyproject_headed.toml ./pyproject.toml;
$env:FX_EXECUTABLE = "C:\Program Files\Custom Firefox\firefox.exe"
pipenv run python choose_ci_set.py
pipenv run pytest $(cat selected_tests)
pipenv run pytest --geckodriver geckodriver.exe $(cat selected_tests)
$env:TEST_EXIT_CODE = $LASTEXITCODE
rm artifacts/assets -r -Force
Get-ChildItem -Path "artifacts" | ForEach-Object {
Expand Down
26 changes: 20 additions & 6 deletions SELECTOR_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,14 +495,14 @@ Path to .json: modules/data/about_prefs.components.json
```
```
Selector Name: save-and-fill-addresses
Selector Data: "checkbox[label='Save and fill addresses']"
Selector Data: "[data-l10n-id='autofill-addresses-checkbox-message']"
Description: Label for Autofill > Save and fill addresses option
Location: about:preferences#privacy
Path to .json: modules/data/about_prefs.components.json
```
```
Selector Name: save-and-fill-payment-methods
Selector Data: "checkbox[label='Save and fill payment methods']"
Selector Data: "[data-l10n-id='autofill-payment-methods-checkbox-message-2']"
Description: Label for Autofill > Save and fill payment methods option
Location: about:preferences#privacy
Path to .json: modules/data/about_prefs.components.json
Expand All @@ -515,6 +515,20 @@ Location: about:preferences#privacy
Path to .json: modules/data/about_prefs.components.json
```
```
Selector Name: saved-payments-button
Selector Data: "[data-l10n-id='autofill-payment-methods-manage-payments-button']"
Description: Embedded button/label for "Manage Saved Payments"
Location: about:preferences#privacy
Path to .json: modules/data/about_prefs.components.json
```
```
Selector Name: saved-addresses-button
Selector Data: "[data-l10n-id='autofill-addresses-manage-addresses-button']"
Description: Embedded button/label for "Manage Addresses and more..."
Location: about:preferences#privacy
Path to .json: modules/data/about_prefs.components.json
```
```
Selector Name: import-browser-data
Selector Data: "button[id='data-migration']"
Description: Import Browser Data > Import Data button
Expand Down Expand Up @@ -845,7 +859,7 @@ Path to .json: modules/data/about_prefs.components.json
```
```
Selector Name: cookies-privacy-label
Selector Data: "description[data-l10n-id='sitedata-delete-on-close-private-browsing2']"
Selector Data: "[data-l10n-id='sitedata-delete-on-close-private-browsing3']"
Description: Message in Cookies and Site data when History is not remembered
Location: about:preferences#privacy
Path to .json: modules/data/about_prefs.components.json
Expand Down Expand Up @@ -1833,9 +1847,9 @@ Location: Any non-linked content space inside example.com page
Path to .json: modules/data/exemple_page.components.json
```
```
Selector Name: more-information
Selector Data: "More information..."
Description: More information..." link
Selector Name: learn-more
Selector Data: "Learn more"
Description: "Learn more" link
Location: The hyperlink positioned in the middle of example.com page
Path to .json: modules/data/exemple_page.components.json
```
Expand Down
33 changes: 28 additions & 5 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
from subprocess import check_output, run
from typing import Callable, List, Tuple, Union

# import psutil
import pytest
from PIL import Image, ImageGrab
from selenium.common.exceptions import TimeoutException, WebDriverException
from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

Expand Down Expand Up @@ -132,6 +134,13 @@ def pytest_addoption(parser):
help="Path to Fx executable. Will overwrite --fx-channel.",
)

parser.addoption(
"--geckodriver",
action="store",
default="",
help="Path to geckodriver.",
)

parser.addoption(
"--run-headless",
action="store_true",
Expand Down Expand Up @@ -216,12 +225,17 @@ def sys_platform():
return platform.system()


@pytest.fixture(scope="session")
def geckodriver(request):
return request.config.getoption("--geckodriver")


@pytest.fixture()
def downloads_folder(sys_platform):
"""Return the downloads folder location for this OS"""
if sys_platform == "Windows":
user = os.environ.get("USERNAME")
return f"C:\\Users\\{user}\\Downloads"
return rf"C:\Users\{user}\Downloads"
elif sys_platform == "Darwin": # MacOS
user = os.environ.get("USER")
return f"/Users/{user}/Downloads"
Expand All @@ -242,11 +256,11 @@ def fx_executable(request, sys_platform):
location = ""
if sys_platform == "Windows":
if version == "Firefox":
location = "C:\\Program Files\\Mozilla Firefox\\firefox.exe"
location = r"C:\Program Files\Mozilla Firefox\firefox.exe"
elif version == "Nightly":
location = "C:\\Program Files\\Firefox Nightly\\firefox.exe"
location = r"C:\Program Files\Firefox Nightly\firefox.exe"
elif version == "Custom":
location = "C:\\Program Files\\Custom Firefox\\firefox.exe"
location = r"C:\Program Files\Custom Firefox\firefox.exe"
elif sys_platform == "Darwin":
if version == "Firefox":
location = "/Applications/Firefox.app/Contents/MacOS/firefox"
Expand Down Expand Up @@ -392,6 +406,7 @@ def hard_quit():
@pytest.fixture(autouse=True)
def driver(
fx_executable: str,
geckodriver: str,
opt_headless: bool,
opt_implicit_timeout: int,
prefs_list: List[Tuple],
Expand Down Expand Up @@ -457,7 +472,15 @@ def driver(
options.profile = profile_path
for opt, value in prefs_list:
options.set_preference(opt, value)
driver = Firefox(options=options)
if geckodriver:
service = Service(executable_path=geckodriver)
driver = Firefox(service=service, options=options)
else:
driver = Firefox(options=options)
# Uncomment below to find Fx process info
# for proc in psutil.process_iter(["name", "exe", "cmdline"]):
# if proc.info["name"] and "firefox" in proc.info["name"].lower():
# print(proc.info)
separator = "x"
if separator not in opt_window_size:
if "by" in opt_window_size:
Expand Down
2 changes: 1 addition & 1 deletion modules/browser_object_panel_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def reopen_recently_closed_tabs(self) -> BasePage:
self.click_on("panel-ui-history")

self.click_on("panel-ui-history-recently-closed")
if self.sys_platform() == "Linux":
if self.sys_platform() in ("Linux", "Darwin"):
sleep(2)

self.click_on("panel-ui-history-recently-closed-reopen-tabs")
Expand Down
2 changes: 1 addition & 1 deletion modules/browser_object_tracker_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def wait_for_blocked_tracking_icon(
self, nav: Navigation, page: BasePage
) -> BasePage:
"""
Waits for the shield icon to indicate that cookies/trackers are being blocked by continuously refresing the page
Waits for the shield icon to indicate that cookies/trackers are being blocked by continuously refreshing the page

Remember to open the passed in page beforehand, this waits for the page to load.

Expand Down
16 changes: 13 additions & 3 deletions modules/data/about_prefs.components.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
"groups": []
},
"save-and-fill-addresses": {
"selectorData": "checkbox[label='Save and fill addresses']",
"selectorData": "[data-l10n-id='autofill-addresses-checkbox-message']",
"strategy": "css",
"groups": []
},
"save-and-fill-payment-methods": {
"selectorData": "checkbox[label='Save and fill payment methods']",
"selectorData": "[data-l10n-id='autofill-payment-methods-checkbox-message-2']",
"strategy": "css",
"groups": []
},
Expand All @@ -59,6 +59,16 @@
"strategy": "css",
"groups": []
},
"saved-payments-button": {
"selectorData": "[data-l10n-id='autofill-payment-methods-manage-payments-button']",
"strategy": "css",
"groups": []
},
"saved-addresses-button": {
"selectorData": "[data-l10n-id='autofill-addresses-manage-addresses-button']",
"strategy": "css",
"groups": []
},
"import-browser-data": {
"selectorData": "button[id='data-migration']",
"strategy": "css",
Expand Down Expand Up @@ -307,7 +317,7 @@
"groups": []
},
"cookies-privacy-label": {
"selectorData": "description[data-l10n-id='sitedata-delete-on-close-private-browsing2']",
"selectorData": "[data-l10n-id='sitedata-delete-on-close-private-browsing3']",
"strategy": "css",
"groups": []
},
Expand Down
4 changes: 2 additions & 2 deletions modules/data/example_page.components.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
]
},

"more-information": {
"selectorData": "More information...",
"learn-more": {
"selectorData": "Learn more",
"strategy": "link_text",
"groups": []
}
Expand Down
2 changes: 1 addition & 1 deletion modules/data/panel_ui.components.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
},

"panel-ui-history-recently-closed-reopen-tabs": {
"selectorData": "toolbarbutton[class='restoreallitem subviewbutton panel-subview-footer-button']",
"selectorData": "toolbarbutton[class='subviewbutton subviewbutton-nav'][label='Recently closed tabs']",
"strategy": "css",
"groups": []
},
Expand Down
24 changes: 9 additions & 15 deletions modules/page_object_prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,6 @@ def verify_cc_edit_saved_payments_profile(
assert field_value != expected_cvv, "CVV is displayed."
return self

def get_saved_payments_popup(self) -> WebElement:
"""
Open saved payments dialog panel
"""
return self.get_element("prefs-button", labels=["Saved payment methods"])

def click_edit_on_dialog_element(self):
"""
Click on edit button on dialog panel
Expand Down Expand Up @@ -283,7 +277,11 @@ def add_entry_to_saved_payments(self, cc_data: CreditCardBase):
def close_dialog_box(self):
"""Close dialog box for saved addresses or payments."""
self.element_clickable("panel-popup-button", labels=["close-button"])
self.get_element("panel-popup-button", labels=["close-button"]).click()
self.click_on("panel-popup-button", labels=["close-button"])
if self.get_element(
"panel-popup-button", labels=["close-button"]
).is_displayed():
self.click_on("panel-popup-button", labels=["close-button"])
return self

def update_cc_field_panel(self, field_name: str, value: str | int) -> BasePage:
Expand Down Expand Up @@ -317,12 +315,6 @@ def update_cc_field_panel(self, field_name: str, value: str | int) -> BasePage:
self.get_element("save-button").click()
return self

def get_saved_addresses_popup(self) -> WebElement:
"""
Returns saved addresses button element
"""
return self.get_element("prefs-button", labels=["Saved addresses"])

def open_and_switch_to_saved_addresses_popup(self) -> BasePage:
"""
Open and Switch to saved addresses popup frame.
Expand Down Expand Up @@ -420,7 +412,8 @@ def get_saved_payments_popup_iframe(self) -> WebElement:
"""
Returns the iframe object for the dialog panel in the popup
"""
self.get_saved_payments_popup().click()
self.find_in_settings("pay")
self.click_on("saved-payments-button")
iframe = self.get_element("browser-popup")
return iframe

Expand All @@ -444,7 +437,8 @@ def get_saved_addresses_popup_iframe(self) -> WebElement:
"""
Returns the iframe object for the dialog panel in the popup
"""
self.get_saved_addresses_popup().click()
self.find_in_settings("pay")
self.click_on("saved-addresses-button")
iframe = self.get_element("browser-popup")
return iframe

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import pytest
from selenium.webdriver import Firefox
from selenium.webdriver.common.keys import Keys

from modules.browser_object_navigation import Navigation
from modules.page_object_generics import GenericPage


@pytest.fixture()
def test_case():
return "3028730"


@pytest.mark.parametrize("engine", ["DuckDuckGo"])
def test_search_mode_persists_mixed_with_bing(driver: Firefox, engine):
"""
TC 3028730: Ensure '@bing' is NOT recognized as a special Bing search when DuckDuckGo is selected.
"""
# Open a neutral page (new tab) and prepare helpers
page = GenericPage(driver, url="about:newtab")
nav = Navigation(driver)

page.open()

# Step 1: pick DuckDuckGo from the search mode switcher (aka USB)
nav.click_search_mode_switcher()
nav.set_search_mode(engine)

# Step 2: type '@bing' in the Awesome Bar
nav.click_in_awesome_bar()
nav.type_in_awesome_bar("@bing")

# Assert that the "tab to search" / alias UI is NOT shown for '@bing'
nav.element_not_visible("tab-to-search-text-span")

# Step 3: continue typing any word and hit Enter
nav.type_in_awesome_bar(" test" + Keys.ENTER)

# Expectation: a DuckDuckGo results page, with '@bing' included as plain text in the query.
page.url_contains("duckduckgo.com")

# Verify '@bing' appears in the query (allowing for URL encoding)
current_url = driver.current_url
assert ("%40bing" in current_url) or ("@bing" in current_url), (
f"@bing should be part of the search term, but URL was: {current_url}"
)
16 changes: 9 additions & 7 deletions tests/audio_video/test_allow_audio_video_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ def test_case():


WIN_GHA = environ.get("GITHUB_ACTIONS") == "true" and sys.platform.startswith("win")
TEST_URL = "https://www.w3schools.com/html/mov_bbb.mp4"


TEST_URL = "https://www.mlb.com/video/rockies-black-agree-on-extension"


@pytest.mark.skipif(WIN_GHA, reason="Test unstable in Windows Github Actions")
@pytest.mark.skipif(
WIN_GHA, reason="Audio playback not supported in Windows CI environment"
)
@pytest.mark.audio
@pytest.mark.noxvfb
def test_allow_audio_video_functionality(driver: Firefox):
Expand All @@ -32,9 +32,11 @@ def test_allow_audio_video_functionality(driver: Firefox):
tabs = TabBar(driver)
page = GenericPage(driver, url=TEST_URL)

# Open privacy and click on the "Settings" button from Autoplay
# Open privacy and security preferences and set 'Allow Audio and Video' for autoplay
about_prefs.set_autoplay_setting_in_preferences("allow-audio-video")

# Open the website and check if the video starts playing with sound
# Open the website in a new tab and check if the video starts playing with sound
tabs.new_tab_by_button()
tabs.switch_to_new_tab()
page.open()
tabs.expect_tab_sound_status(1, tabs.MEDIA_STATUS.PLAYING)
tabs.expect_tab_sound_status(2, tabs.MEDIA_STATUS.PLAYING)
5 changes: 5 additions & 0 deletions tests/downloads/test_download_pdf_from_context_menu.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from platform import system
from time import sleep

import pytest
Expand All @@ -24,6 +25,10 @@ def delete_files_regex_string():
PDF_TELEMETRY_DATA = ["downloads", "added", "fileExtension", "pdf"]


@pytest.mark.skipif(
system().lower().startswith("darwin") or system().lower().startswith("linux"),
reason="bug 1994061",
)
@pytest.mark.headed
def test_download_pdf_from_context_menu(
driver: Firefox,
Expand Down
Loading
Loading