Skip to content

Commit cb6d613

Browse files
authored
Merge pull request #133 from mozilla/sl/third-party-private-browsing
Third Party Content Private Browsing
2 parents a5b9278 + 0f99864 commit cb6d613

9 files changed

+304
-4
lines changed

modules/browser_object.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
from modules.browser_object_search_bar_context_menu import *
1111
from modules.browser_object_tab_context_menu import *
1212
from modules.browser_object_tabbar import *
13+
from modules.browser_object_tracker_panel import *

modules/browser_object_navigation.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,11 @@ def wait_for_download_animation_finish(
183183
)
184184
except TimeoutException:
185185
logging.warning("Animation did not finish or did not play.")
186+
187+
def open_tracker_panel(self) -> BasePage:
188+
"""
189+
Clicks the shield icon and opens the panel associated with it
190+
"""
191+
# self.set_chrome_context()
192+
self.get_element("shield-icon").click()
193+
return self
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import logging
2+
from typing import List
3+
4+
from selenium.common.exceptions import TimeoutException
5+
from selenium.webdriver.remote.webelement import WebElement
6+
7+
from modules.browser_object_navigation import Navigation
8+
from modules.page_base import BasePage
9+
10+
11+
class TrackerPanel(BasePage):
12+
"""
13+
BOM for the panel that shows up after clicking the shield
14+
"""
15+
16+
URL_TEMPLATE = ""
17+
18+
def wait_for_blocked_tracking_icon(
19+
self, nav: Navigation, page: BasePage
20+
) -> BasePage:
21+
"""
22+
Waits for the shield icon to indicate that cookies/trackers are being blocked by continuously refresing the page
23+
24+
Remember to open the passed in page beforehand, this waits for the page to load.
25+
26+
Example Usage:
27+
first_tracker_website.open()
28+
tracker_panel.wait_for_blocked_tracking_icon(nav, first_tracker_website)
29+
"""
30+
31+
def shield_active() -> bool:
32+
nav.get_element("refresh-button").click()
33+
with self.driver.context(self.driver.CONTEXT_CONTENT):
34+
page.open()
35+
page.wait_for_page_to_load()
36+
shield_icon = self.get_element("shield-icon")
37+
if (
38+
shield_icon.get_attribute("data-l10n-id")
39+
== "tracking-protection-icon-active-container"
40+
):
41+
return True
42+
return False
43+
44+
try:
45+
with self.driver.context(self.context_id):
46+
self.wait.until(lambda _: shield_active())
47+
except TimeoutException:
48+
logging.warning(
49+
"The shield icon was not active after refreshing mulitple times, the test has timed out."
50+
)
51+
return self
52+
53+
def verify_tracker_shield_indicator(self, nav: Navigation) -> BasePage:
54+
"""
55+
Verifies that the shield icon is in the correct mode
56+
"""
57+
with self.driver.context(self.context_id):
58+
shield_icon = self.get_element("shield-icon")
59+
assert (
60+
shield_icon.get_attribute("data-l10n-id")
61+
== "tracking-protection-icon-active-container"
62+
), "The label detected did not correspond to the expected one: tracking-protection-icon-active-container"
63+
return self
64+
65+
def open_and_return_cross_site_trackers(self) -> List[WebElement]:
66+
with self.driver.context(self.context_id):
67+
self.get_element("tracker-cross-site-tracking").click()
68+
return self.get_elements("tracking-cross-site-tracking-item")
69+
70+
def open_and_return_allowed_trackers(self) -> List[WebElement]:
71+
with self.driver.context(self.context_id):
72+
self.get_element("tracker-tracking-content").click()
73+
return self.get_elements("tracking-allowed-content-item")

modules/data/generic_page.components.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,23 @@
3333
"selectorData": "button[class='cdx-button cdx-button--action-default cdx-button--weight-normal cdx-button--size-medium cdx-button--framed cdx-search-input__end-button']",
3434
"strategy": "css",
3535
"groups": []
36+
},
37+
38+
"simulated-tracker-block-status": {
39+
"selectorData": "blacklisted-blocked",
40+
"strategy": "id",
41+
"groups": []
42+
},
43+
44+
"simulated-tracker-load-status": {
45+
"selectorData": "whitelisted-loaded",
46+
"strategy": "id",
47+
"groups": []
48+
},
49+
50+
"simulated-tracker-dnt-status": {
51+
"selectorData": "dnt-on",
52+
"strategy": "id",
53+
"groups": []
3654
}
3755
}

modules/data/navigation.components.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@
189189
"shield-icon": {
190190
"selectorData": "tracking-protection-icon-container",
191191
"strategy": "id",
192-
"groups": []
192+
"groups": [
193+
"doNotCache"
194+
]
193195
},
194196

195197
"cryptominers": {
@@ -232,5 +234,13 @@
232234
"selectorData": ".urlbarView-action",
233235
"strategy": "css",
234236
"groups": []
237+
},
238+
239+
"refresh-button": {
240+
"selectorData": "reload-button",
241+
"strategy": "id",
242+
"groups": [
243+
"doNotCache"
244+
]
235245
}
236246
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"context": "chrome",
3+
"tracker-title": {
4+
"selectorData": "protections-popup-mainView-panel-header-span",
5+
"strategy": "id",
6+
"groups": []
7+
},
8+
9+
"tracker-cross-site-tracking": {
10+
"selectorData": "protections-popup-category-cookies",
11+
"strategy": "id",
12+
"groups": []
13+
},
14+
15+
"tracker-tracking-content": {
16+
"selectorData": "protections-popup-category-trackers",
17+
"strategy": "id",
18+
"groups": []
19+
},
20+
21+
"tracking-social-media": {
22+
"selectorData": "protections-popup-category-socialblock",
23+
"strategy": "id",
24+
"groups": []
25+
},
26+
27+
"tracking-finger-prints": {
28+
"selectorData": "protections-popup-category-fingerprinters",
29+
"strategy": "id",
30+
"groups": []
31+
},
32+
33+
"tracking-crypto-miners": {
34+
"selectorData": "protections-popup-category-cryptominers",
35+
"strategy": "id",
36+
"groups": []
37+
},
38+
39+
"tracking-cross-site-tracking-items": {
40+
"selectorData": "vbox[class='protections-popup-cookiesView-list-section']",
41+
"strategy": "css",
42+
"groups": []
43+
},
44+
45+
"tracking-cross-site-tracking-item": {
46+
"selectorData": "protections-popup-list-host-label",
47+
"strategy": "class",
48+
"groups": []
49+
},
50+
51+
"tracking-allowed-content-item": {
52+
"selectorData": "protections-popup-list-host-label",
53+
"strategy": "class",
54+
"groups": []
55+
},
56+
57+
"shield-icon": {
58+
"selectorData": "tracking-protection-icon-container",
59+
"strategy": "id",
60+
"groups": [
61+
"doNotCache",
62+
"requiredForPage"
63+
]
64+
}
65+
}

modules/page_object_autofill_login.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from selenium.webdriver import Firefox
2-
31
from modules.page_object_autofill import Autofill
42

53

taskcluster/kinds/run-smoke-tests/kind.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ tasks:
2424
./collect_executables.sh;
2525
mv ./ci_pyproject.toml ./pyproject.toml;
2626
pipenv install;
27-
pipenv run pytest --fx-executable ./firefox/firefox -n 4 .
27+
pipenv run pytest --fx-executable ./firefox/firefox -n 4 .
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
from selenium.webdriver import Firefox
2+
3+
from modules.browser_object import Navigation, PanelUi, TrackerPanel
4+
from modules.page_object import GenericPage
5+
6+
ALLOWED_TRACKING_URLS = set(
7+
[
8+
"https://content-track-digest256.dummytracker.org",
9+
"https://ads-track-digest256.dummytracker.org",
10+
"https://social-track-digest256.dummytracker.org",
11+
"https://analytics-track-digest256.dummytracker.org",
12+
]
13+
)
14+
BLOCKED_TRACKER_URL = "https://content-track-digest256.dummytracker.org"
15+
16+
FIRST_TRACKER_WEBSITE = "https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html"
17+
SECOND_TRACKER_WEBSITE = "https://www.itisatrap.org/firefox/its-a-tracker.html"
18+
19+
20+
def test_third_party_content_blocked_private_browsing_cross_site(driver: Firefox):
21+
"""
22+
C446323.1: Ensure that third party content is blocked correctly
23+
"""
24+
# instantiate objects
25+
panel_ui = PanelUi(driver).open()
26+
nav = Navigation(driver)
27+
tracker_panel = TrackerPanel(driver)
28+
tracker_website = GenericPage(driver, url=FIRST_TRACKER_WEBSITE)
29+
30+
# open the new window
31+
panel_ui.open_private_window()
32+
nav.switch_to_new_window()
33+
34+
# open the website, ensure the blocking is taking place by continuously refreshing website until indicated
35+
tracker_website.open()
36+
tracker_panel.wait_for_blocked_tracking_icon(nav, tracker_website)
37+
38+
# verify the indicator
39+
driver.set_context(driver.CONTEXT_CHROME)
40+
tracker_panel.verify_tracker_shield_indicator(nav)
41+
nav.open_tracker_panel()
42+
43+
# verify the panel title
44+
tracker_panel_title = tracker_panel.get_element("tracker-title")
45+
assert (
46+
tracker_panel_title.get_attribute("innerHTML")
47+
== "Protections for senglehardt.com"
48+
)
49+
50+
# fetch the items in the cross site trackers
51+
cross_site_trackers = tracker_panel.open_and_return_cross_site_trackers()
52+
53+
# ensure that the correct blocked site is listed
54+
found_tracker = False
55+
for item in cross_site_trackers:
56+
if item.get_attribute("value") == BLOCKED_TRACKER_URL:
57+
found_tracker = True
58+
assert found_tracker
59+
60+
61+
def test_third_party_content_blocked_private_browsing_allowed_tracking(driver: Firefox):
62+
"""
63+
C446323.2: Ensure that some third party content is allowed
64+
"""
65+
# instantiate objects
66+
panel_ui = PanelUi(driver).open()
67+
nav = Navigation(driver)
68+
tracker_panel = TrackerPanel(driver)
69+
tracker_website = GenericPage(driver, url=FIRST_TRACKER_WEBSITE)
70+
71+
# open a private window
72+
panel_ui.open_private_window()
73+
nav.switch_to_new_window()
74+
75+
# open the website, ensure the blocking is taking place by continuously refreshing website until indicated
76+
tracker_website.open()
77+
tracker_panel.wait_for_blocked_tracking_icon(nav, tracker_website)
78+
79+
# verify the indicator
80+
driver.set_context(driver.CONTEXT_CHROME)
81+
tracker_panel.verify_tracker_shield_indicator(nav)
82+
83+
# open the panel and verify the title
84+
nav.open_tracker_panel()
85+
tracker_panel_title = tracker_panel.get_element("tracker-title")
86+
assert (
87+
tracker_panel_title.get_attribute("innerHTML")
88+
== "Protections for senglehardt.com"
89+
)
90+
91+
# fetch allowed trackers
92+
allowed_trackers = tracker_panel.open_and_return_allowed_trackers()
93+
94+
# verify the correct ones are allowed
95+
for item in allowed_trackers:
96+
assert item.get_attribute("value") in ALLOWED_TRACKING_URLS
97+
98+
99+
def test_third_party_content_private_browsing_tracking_statuses(driver: Firefox):
100+
"""
101+
C446323.3: Ensure that the statuses of some third party content are loaded properly
102+
"""
103+
# instantiate objects
104+
panel_ui = PanelUi(driver).open()
105+
nav = Navigation(driver)
106+
tracker_panel = TrackerPanel(driver)
107+
tracker_website = GenericPage(driver, url=SECOND_TRACKER_WEBSITE)
108+
109+
# open a private window
110+
panel_ui.open_private_window()
111+
nav.switch_to_new_window()
112+
113+
# open the tracker website
114+
tracker_website.open()
115+
tracker_panel.wait_for_blocked_tracking_icon(nav, tracker_website)
116+
117+
# verify the indicator
118+
tracker_panel.verify_tracker_shield_indicator(nav)
119+
120+
# assert all of the various statuses, ensure that the correct one is displayed
121+
block_status = tracker_website.get_element("simulated-tracker-block-status")
122+
load_status = tracker_website.get_element("simulated-tracker-load-status")
123+
dnt_status = tracker_website.get_element("simulated-tracker-dnt-status")
124+
125+
assert "hidden" not in block_status.get_attribute("class")
126+
assert "hidden" not in load_status.get_attribute("class")
127+
assert "hidden" not in dnt_status.get_attribute("class")

0 commit comments

Comments
 (0)