Skip to content

Commit 7593f8f

Browse files
committed
Merge main
2 parents e9887c8 + 266d401 commit 7593f8f

File tree

8 files changed

+177
-15
lines changed

8 files changed

+177
-15
lines changed

.github/workflows/l10n.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ name: L10N Test Execution
33

44
run-name: ${{ github.actor }} is running l10n tests
55
on:
6-
pull_request:
76
workflow_call:
87
inputs:
98
channel:
@@ -30,7 +29,7 @@ env:
3029

3130
jobs:
3231
L10N-MacOS:
33-
if: ${{ inputs.job_to_run == 'L10N-MacOS' || github.event_name == 'pull_request' || inputs.mac_installer_link }}
32+
if: ${{ inputs.job_to_run == 'L10N-MacOS' || inputs.mac_installer_link }}
3433
runs-on: macos-latest
3534
steps:
3635
- name: Create app token

SELECTOR_INFO.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,13 @@ Location: about:preferences#privacy
662662
Path to .json: modules/data/about_prefs.components.json
663663
```
664664
```
665+
Selector Name: custom-tracker-options-parent
666+
Selector Data: "contentBlockingOptionCustom"
667+
Description: Parent Element in custom tracker blocking checkboxes
668+
Location: about:preferences#privacy
669+
Path to .json: modules/data/about_prefs.components.json
670+
```
671+
```
665672
Selector Name: cookies-checkbox
666673
Selector Data: "contentBlockingBlockCookiesCheckbox"
667674
Description: In Enhanced Tracking Protection, the check-box for Cookies

modules/data/about_prefs.components.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
"searchEngineDropdown"
1414
]
1515
},
16+
"custom-tracker-options-parent": {
17+
"selectorData": "contentBlockingOptionCustom",
18+
"strategy": "id",
19+
"groups": []
20+
},
1621
"search-engine-dropmarker": {
1722
"selectorData": "dropmarker",
1823
"strategy": "tag",

modules/page_object_prefs.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import datetime
2+
import logging
13
import re
24
from time import sleep
35
from typing import List
@@ -118,6 +120,19 @@ def select_content_and_action(self, content_type: str, action: str) -> BasePage:
118120
self.wait.until(lambda _: el.get_attribute("label") == action)
119121
return self
120122

123+
def select_trackers_to_block(self, *options):
124+
"""Select the trackers to block in the about:preferences page. Unchecks all first."""
125+
self.click_on("custom-radio")
126+
checkboxes = self.get_element("custom-tracker-options-parent").find_elements(
127+
By.TAG_NAME, "checkbox"
128+
)
129+
for checkbox in checkboxes:
130+
if checkbox.is_selected():
131+
checkbox.click()
132+
for option in options:
133+
self.click_on(option)
134+
return self
135+
121136
def get_history_menulist(self) -> WebElement:
122137
"""
123138
Gets the web element for the list of history items that appear in about:preferences
@@ -289,9 +304,16 @@ def update_cc_field_panel(self, field_name: str, value: str | int) -> BasePage:
289304
)
290305
self.switch_to_edit_saved_payments_popup_iframe()
291306
value_field = self.find_element(By.ID, fields[field_name])
292-
if value_field.tag_name != "select":
307+
if value.isdigit():
308+
value = int(value)
309+
if field_name == "expiration_year":
310+
value -= (datetime.datetime.now().year % 100) + 1
311+
312+
if value_field.tag_name == "select":
313+
Select(value_field).select_by_index(value)
314+
else:
293315
value_field.clear()
294-
value_field.send_keys(value)
316+
value_field.send_keys(value)
295317
self.get_element("save-button").click()
296318
return self
297319

modules/testrail.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ def get_test_case(self, case_id):
160160
"""Get a given Test Case"""
161161
return self.client.send_get(f"get_case/{case_id}")
162162

163+
def get_suites(self, project_id):
164+
"""Get all suites for project"""
165+
return self.client.send_get(f"get_suites/{project_id}")
166+
163167
def update_cases_in_suite(self, suite_id, case_ids, **kwargs):
164168
"""Given a suite and a list of test cases, update all listed
165169
test cases according to keyword args"""
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import logging
2+
3+
from dotenv import load_dotenv
4+
5+
from modules.testrail_integration import testrail_init
6+
7+
# Load environment variables from .env file
8+
load_dotenv()
9+
10+
# Configuration Constants
11+
PROJECT_ID = 17 # The ID of the TestRail project to work with
12+
SUITE_NAMES = ["Fakespot Shopping Sidebar"] # List of suite names to process
13+
14+
CUSTOM_SUB_TEST_SUITES = [1] # Value to set for the 'custom_sub_test_suites' field
15+
DRY_RUN = True # If True, only log actions without making changes
16+
17+
18+
def get_all_cases_from_suite(tr, project_id, suite_id):
19+
"""
20+
Fetch all test cases from a given TestRail suite using pagination.
21+
22+
Args:
23+
tr: TestRail API client instance.
24+
project_id (int): The ID of the TestRail project.
25+
suite_id (int): The ID of the suite to fetch cases from.
26+
27+
Returns:
28+
list: A list of test case dictionaries.
29+
"""
30+
all_cases = [] # List to store all fetched test cases
31+
offset = 0 # Starting point for pagination
32+
limit = 240 # Maximum number of cases to fetch in each API call
33+
34+
while True:
35+
# Build the API endpoint with pagination parameters
36+
endpoint = (
37+
f"get_cases/{project_id}&suite_id={suite_id}&limit={limit}&offset={offset}"
38+
)
39+
response = tr.client.send_get(endpoint) # Send API request to TestRail
40+
cases = response.get("cases", []) # Extract the list of test cases
41+
42+
if not cases:
43+
# If no more cases are found, break the loop
44+
break
45+
46+
# Add the fetched cases to the complete list
47+
all_cases.extend(cases)
48+
49+
if len(cases) < limit:
50+
# If the number of fetched cases is less than the limit, we are at the last page
51+
break
52+
53+
# Increment offset to fetch the next batch of cases
54+
offset += limit
55+
56+
# Log the total number of fetched cases
57+
logging.info(f"Total cases fetched from suite {suite_id}: {len(all_cases)}")
58+
return all_cases
59+
60+
61+
if __name__ == "__main__":
62+
# Initialize logging to display info messages
63+
logging.basicConfig(level=logging.INFO)
64+
65+
# Initialize the TestRail API client
66+
tr = testrail_init()
67+
68+
# Fetch suite IDs matching the given suite names
69+
suites = tr.get_suites(PROJECT_ID)
70+
suite_ids = [suite["id"] for suite in suites if suite["name"] in SUITE_NAMES]
71+
logging.info(f"Found suites: {suite_ids}")
72+
73+
# Fetch all test cases from the selected suites
74+
all_cases = [] # List to store all fetched test cases
75+
for suite_id in suite_ids:
76+
# Fetch and add cases from each suite
77+
cases = get_all_cases_from_suite(tr, PROJECT_ID, suite_id)
78+
all_cases.extend(cases)
79+
80+
# Log the total number of test cases found
81+
logging.info(f"Total test cases found for selected suites: {len(all_cases)}")
82+
83+
updated_count = 0 # Counter for the number of cases updated
84+
85+
# Iterate over each test case to display and update the 'custom_sub_test_suites' field
86+
for case in all_cases:
87+
# Get the current value of the 'custom_sub_test_suites' field
88+
current_value = case.get("custom_sub_test_suites", "Not Set")
89+
logging.info(f"Case ID {case['id']} current value: {current_value}")
90+
91+
if not DRY_RUN:
92+
# If not in dry run mode, perform the update
93+
result = tr.update_case_field(
94+
case["id"], "custom_sub_test_suites", CUSTOM_SUB_TEST_SUITES
95+
)
96+
logging.info(
97+
f"Updated case {case['id']} to '{CUSTOM_SUB_TEST_SUITES}', Result: {result}"
98+
)
99+
else:
100+
# In dry run mode, just log the intended change without making it
101+
logging.info(
102+
f"[DRY RUN] Would update case {case['id']} from '{current_value}' to '{CUSTOM_SUB_TEST_SUITES}'."
103+
)
104+
105+
updated_count += 1 # Increment the updated count
106+
107+
# Log the total number of cases updated or to be updated
108+
logging.info(
109+
f"Total cases {'updated' if not DRY_RUN else 'to be updated'}: {updated_count}"
110+
)

tests/security_and_privacy/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import pytest
22

3+
from modules.browser_object_navigation import Navigation
4+
from modules.page_object_prefs import AboutPrefs
5+
36

47
@pytest.fixture()
58
def suite_id():
@@ -17,3 +20,13 @@ def prefs_list(add_to_prefs_list: dict):
1720
@pytest.fixture()
1821
def add_to_prefs_list():
1922
return []
23+
24+
25+
@pytest.fixture()
26+
def nav(driver):
27+
return Navigation(driver)
28+
29+
30+
@pytest.fixture()
31+
def about_prefs_privacy(driver):
32+
return AboutPrefs(driver, category="privacy")

tests/security_and_privacy/test_blocking_fingerprinters.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from selenium.webdriver import Firefox
33

44
from modules.browser_object_navigation import Navigation
5+
from modules.browser_object_tracker_panel import TrackerPanel
6+
from modules.page_object_generics import GenericPage
57
from modules.page_object_prefs import AboutPrefs
68

79

@@ -15,25 +17,25 @@ def test_case():
1517
)
1618

1719

18-
def test_blocking_fingerprinter(driver: Firefox):
20+
def test_blocking_fingerprinter(
21+
driver: Firefox, nav: Navigation, about_prefs_privacy: AboutPrefs
22+
):
1923
"""
2024
C446404: Blocking Fingerprinters
2125
"""
2226
# instantiate objects
23-
nav = Navigation(driver)
24-
about_prefs = AboutPrefs(driver, category="privacy")
25-
about_prefs.open()
27+
about_prefs_privacy.open()
28+
tracker_panel = TrackerPanel(driver)
29+
tracking_page = GenericPage(driver, url=FINGERPRINTERS_URL)
2630

2731
# Select custom option and keep just known fingerprinters checked
28-
about_prefs.get_element("custom-radio").click()
29-
about_prefs.get_element("cookies-checkbox").click()
30-
about_prefs.get_element("tracking-checkbox").click()
31-
about_prefs.get_element("cryptominers-checkbox").click()
32-
about_prefs.get_element("suspected-fingerprints-checkbox").click()
32+
about_prefs_privacy.select_trackers_to_block("known-fingerprints-checkbox")
3333

3434
# Access url and click on the shield icon and verify that known fingerprinters are blocked
35-
driver.get(FINGERPRINTERS_URL)
36-
nav.click_on("shield-icon")
35+
tracking_page.open()
36+
tracker_panel.wait_for_blocked_tracking_icon(nav, tracking_page)
37+
38+
nav.open_tracker_panel()
3739
nav.element_visible("known-fingerprints")
3840

3941
# Click on fingerprinters and check if subpanel is correctly displayed

0 commit comments

Comments
 (0)