361 lines
14 KiB
Python
361 lines
14 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: UTF-8 -*-
|
|
|
|
import time
|
|
import unittest
|
|
|
|
import pbtest
|
|
|
|
from selenium.common.exceptions import TimeoutException
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support import expected_conditions
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
|
|
|
|
def get_domain_slider_state(driver, domain):
|
|
label = driver.find_element_by_css_selector(
|
|
'input[name="{}"][checked]'.format(domain))
|
|
return label.get_attribute('value')
|
|
|
|
|
|
class PopupTest(pbtest.PBSeleniumTest):
|
|
"""Make sure the popup works correctly."""
|
|
|
|
def clear_seed_data(self):
|
|
self.load_url(self.options_url)
|
|
self.js("chrome.extension.getBackgroundPage().badger.storage.clearTrackerData();")
|
|
|
|
def wait_for_page_to_start_loading(self, url, timeout=20):
|
|
"""Wait until the title element is present. Use it to work around
|
|
Firefox not updating self.driver.current_url fast enough."""
|
|
try:
|
|
WebDriverWait(self.driver, timeout).until(
|
|
expected_conditions.presence_of_element_located(
|
|
(By.CSS_SELECTOR, "title")))
|
|
except TimeoutException:
|
|
# TODO debug info
|
|
print("\n")
|
|
print("driver.current_url=" + self.driver.current_url)
|
|
print()
|
|
print(self.driver.page_source[:5000])
|
|
print("...\n")
|
|
|
|
self.fail("Timed out waiting for %s to start loading" % url)
|
|
|
|
def open_popup(self, show_nag=False, origins=None):
|
|
"""Open popup and optionally close overlay."""
|
|
|
|
DUMMY_PAGE_URL = "https://efforg.github.io/privacybadger-test-fixtures/"
|
|
|
|
# hack to get tabData populated for the popup's tab
|
|
# to get the popup shown for regular pages
|
|
# as opposed to special (no-tabData) browser pages
|
|
self.open_window()
|
|
self.load_url(DUMMY_PAGE_URL)
|
|
|
|
self.open_window()
|
|
self.load_url(self.popup_url)
|
|
self.wait_for_script("return window.POPUP_INITIALIZED")
|
|
|
|
# override tab ID (to get regular page popup instead of
|
|
# special browser page popup),
|
|
# optionally set the domains the popup should report,
|
|
# optionally ask for the new user welcome page reminder
|
|
popup_js = (
|
|
"(function (origins, show_nag, DUMMY_PAGE_URL) {"
|
|
"chrome.tabs.query({ url: DUMMY_PAGE_URL }, (tabs) => {"
|
|
" chrome.runtime.sendMessage({"
|
|
" type: 'getPopupData',"
|
|
" tabId: tabs[0].id"
|
|
" }, (response) => {"
|
|
" response.seenComic = !show_nag;"
|
|
" response.origins = origins;"
|
|
" setPopupData(response);"
|
|
" refreshPopup();"
|
|
" showNagMaybe();"
|
|
" window.DONE_REFRESHING = true;"
|
|
" });"
|
|
"});"
|
|
"}(arguments[0], arguments[1], arguments[2]));"
|
|
)
|
|
self.js(popup_js, origins if origins else {}, show_nag, DUMMY_PAGE_URL)
|
|
# wait until the async getTab function is done
|
|
self.wait_for_script(
|
|
"return typeof window.DONE_REFRESHING != 'undefined'",
|
|
timeout=5,
|
|
message="Timed out waiting for getTab() to complete."
|
|
)
|
|
|
|
# wait for any sliders to finish rendering
|
|
self.wait_for_script("return window.SLIDERS_DONE")
|
|
|
|
def get_enable_button(self):
|
|
"""Get enable button on popup."""
|
|
return self.driver.find_element_by_id("activate_site_btn")
|
|
|
|
def get_disable_button(self):
|
|
"""Get disable button on popup."""
|
|
return self.driver.find_element_by_id("deactivate_site_btn")
|
|
|
|
def test_welcome_page_reminder_overlay(self):
|
|
"""Ensure overlay links to new user welcome page."""
|
|
|
|
# first close the welcome page if already open
|
|
try:
|
|
self.close_window_with_url(self.first_run_url, max_tries=1)
|
|
except pbtest.WindowNotFoundException:
|
|
pass
|
|
|
|
self.open_popup(show_nag=True)
|
|
self.driver.find_element_by_id("intro-reminder-btn").click()
|
|
|
|
# Look for first run page and return if found.
|
|
self.switch_to_window_with_url(self.first_run_url)
|
|
|
|
def test_help_button(self):
|
|
"""Ensure FAQ website is opened when help button is clicked."""
|
|
|
|
FAQ_URL = "https://privacybadger.org/#faq"
|
|
|
|
try:
|
|
self.switch_to_window_with_url(FAQ_URL, max_tries=1)
|
|
except pbtest.WindowNotFoundException:
|
|
pass
|
|
else:
|
|
self.fail("FAQ should not already be open")
|
|
|
|
self.open_popup()
|
|
self.driver.find_element_by_id("help").click()
|
|
|
|
self.switch_to_window_with_url(FAQ_URL)
|
|
|
|
def test_options_button(self):
|
|
"""Ensure options page is opened when button is clicked."""
|
|
self.open_popup()
|
|
self.driver.find_element_by_id("options").click()
|
|
self.switch_to_window_with_url(self.options_url)
|
|
|
|
@pbtest.repeat_if_failed(5)
|
|
def test_trackers_link(self):
|
|
"""Ensure trackers link opens EFF website."""
|
|
|
|
EFF_URL = "https://privacybadger.org/#What-is-a-third-party-tracker"
|
|
|
|
self.open_popup()
|
|
|
|
# Get all possible tracker links (none, one, multiple)
|
|
trackers_links = self.driver.find_elements_by_css_selector("#pbInstructions a")
|
|
if not trackers_links:
|
|
self.fail("Unable to find trackers link on popup")
|
|
|
|
# Get the one that's displayed on the page that this test is using
|
|
for link in trackers_links:
|
|
if link.is_displayed():
|
|
trackers_link = link
|
|
|
|
trackers_link.click()
|
|
|
|
# Make sure EFF website not opened in same window.
|
|
if self.driver.current_url != self.popup_url:
|
|
self.fail("EFF website not opened in new window")
|
|
|
|
# Look for EFF website and return if found.
|
|
self.switch_to_window_with_url(EFF_URL)
|
|
|
|
self.wait_for_page_to_start_loading(EFF_URL)
|
|
|
|
self.assertEqual(self.driver.current_url, EFF_URL,
|
|
"EFF website should open after clicking trackers link on popup")
|
|
|
|
# Verify EFF website contains the linked anchor element.
|
|
faq_selector = 'a[href="{}"]'.format(EFF_URL[EFF_URL.index('#'):])
|
|
try:
|
|
WebDriverWait(self.driver, pbtest.SEL_DEFAULT_WAIT_TIMEOUT).until(
|
|
expected_conditions.presence_of_element_located(
|
|
(By.CSS_SELECTOR, faq_selector)))
|
|
except TimeoutException:
|
|
self.fail("Unable to find expected element ({}) on EFF website".format(faq_selector))
|
|
|
|
def test_toggling_sliders(self):
|
|
"""Ensure toggling sliders is persisted."""
|
|
self.clear_seed_data()
|
|
|
|
# enable learning to show not-yet-blocked domains in popup
|
|
self.wait_for_script("return window.OPTIONS_INITIALIZED")
|
|
self.find_el_by_css('#local-learning-checkbox').click()
|
|
|
|
DOMAIN = "example.com"
|
|
DOMAIN_ID = DOMAIN.replace(".", "-")
|
|
|
|
self.open_popup(origins={DOMAIN:"allow"})
|
|
|
|
# click input with JavaScript to avoid "Element ... is not clickable" /
|
|
# "Other element would receive the click" Selenium limitation
|
|
self.js("$('#block-{}').click()".format(DOMAIN_ID))
|
|
|
|
# retrieve the new action
|
|
self.load_url(self.options_url)
|
|
self.wait_for_script("return window.OPTIONS_INITIALIZED")
|
|
self.find_el_by_css('a[href="#tab-tracking-domains"]').click()
|
|
new_action = get_domain_slider_state(self.driver, DOMAIN)
|
|
|
|
self.assertEqual(new_action, "block",
|
|
"The domain should be blocked on options page.")
|
|
|
|
# test toggling some more
|
|
self.open_popup(origins={DOMAIN:"user_block"})
|
|
|
|
self.assertTrue(
|
|
self.driver.find_element_by_id("block-" + DOMAIN_ID).is_selected(),
|
|
"The domain should be shown as blocked in popup."
|
|
)
|
|
|
|
# change to "cookieblock"
|
|
self.js("$('#cookieblock-{}').click()".format(DOMAIN_ID))
|
|
# change again to "block"
|
|
self.js("$('#block-{}').click()".format(DOMAIN_ID))
|
|
|
|
# retrieve the new action
|
|
self.load_url(self.options_url)
|
|
self.wait_for_script("return window.OPTIONS_INITIALIZED")
|
|
self.find_el_by_css('a[href="#tab-tracking-domains"]').click()
|
|
new_action = get_domain_slider_state(self.driver, DOMAIN)
|
|
|
|
self.assertEqual(new_action, "block",
|
|
"The domain should still be blocked on options page.")
|
|
|
|
def test_reverting_control(self):
|
|
"""Test restoring control of a domain to Privacy Badger."""
|
|
self.clear_seed_data()
|
|
|
|
DOMAIN = "example.com"
|
|
DOMAIN_ID = DOMAIN.replace(".", "-")
|
|
|
|
# record the domain as cookieblocked by Badger
|
|
self.cookieblock_domain(DOMAIN)
|
|
|
|
self.open_popup(origins={DOMAIN:"cookieblock"})
|
|
|
|
# set the domain to user control
|
|
# click input with JavaScript to avoid "Element ... is not clickable" /
|
|
# "Other element would receive the click" Selenium limitation
|
|
self.js("$('#block-{}').click()".format(DOMAIN_ID))
|
|
|
|
# restore control to Badger
|
|
self.driver.find_element_by_css_selector(
|
|
'div[data-origin="{}"] a.honeybadgerPowered'.format(DOMAIN)
|
|
).click()
|
|
|
|
# get back to a valid window handle as the window just got closed
|
|
self.driver.switch_to.window(self.driver.window_handles[0])
|
|
|
|
# verify the domain is no longer user controlled
|
|
self.load_url(self.options_url)
|
|
self.wait_for_script("return window.OPTIONS_INITIALIZED")
|
|
self.find_el_by_css('a[href="#tab-tracking-domains"]').click()
|
|
|
|
# assert the action is not what we manually clicked
|
|
action = get_domain_slider_state(self.driver, DOMAIN)
|
|
self.assertEqual(action, "cookieblock",
|
|
"Domain's action should have been restored.")
|
|
|
|
# assert the undo arrow is not displayed
|
|
self.driver.find_element_by_css_selector('a[href="#tab-tracking-domains"]').click()
|
|
self.driver.find_element_by_id('show-tracking-domains-checkbox').click()
|
|
self.assertFalse(
|
|
self.driver.find_element_by_css_selector(
|
|
'div[data-origin="{}"] a.honeybadgerPowered'.format(DOMAIN)
|
|
).is_displayed(),
|
|
"Undo arrow should not be displayed."
|
|
)
|
|
|
|
def test_disable_enable_buttons(self):
|
|
"""Ensure disable/enable buttons change popup state."""
|
|
|
|
DISPLAYED_ERROR = " should not be displayed on popup"
|
|
NOT_DISPLAYED_ERROR = " should be displayed on popup"
|
|
|
|
self.open_popup()
|
|
|
|
self.get_disable_button().click()
|
|
|
|
# get back to a valid window handle as the window just got closed
|
|
self.driver.switch_to.window(self.driver.window_handles[0])
|
|
self.open_popup()
|
|
|
|
# Check that popup state changed after disabling.
|
|
disable_button = self.get_disable_button()
|
|
self.assertFalse(disable_button.is_displayed(),
|
|
"Disable button" + DISPLAYED_ERROR)
|
|
enable_button = self.get_enable_button()
|
|
self.assertTrue(enable_button.is_displayed(),
|
|
"Enable button" + NOT_DISPLAYED_ERROR)
|
|
|
|
enable_button.click()
|
|
|
|
self.driver.switch_to.window(self.driver.window_handles[0])
|
|
self.open_popup()
|
|
|
|
# Check that popup state changed after re-enabling.
|
|
disable_button = self.get_disable_button()
|
|
self.assertTrue(disable_button.is_displayed(),
|
|
"Disable button" + NOT_DISPLAYED_ERROR)
|
|
enable_button = self.get_enable_button()
|
|
self.assertFalse(enable_button.is_displayed(),
|
|
"Enable button" + DISPLAYED_ERROR)
|
|
|
|
def test_error_button(self):
|
|
"""Ensure error button opens report error overlay."""
|
|
self.open_popup()
|
|
|
|
# TODO: selenium firefox has a bug where is_displayed() is always True
|
|
# for these elements. But we should use is_displayed when this is fixed.
|
|
#overlay_input = self.driver.find_element_by_id("error_input")
|
|
#self.assertTrue(overlay_input.is_displayed(), "User input" + error_message)
|
|
|
|
# assert error reporting menu is not open
|
|
self.assertTrue(len(self.driver.find_elements_by_class_name('active')) == 0,
|
|
'error reporting should not be open')
|
|
|
|
# Click error button to open overlay for reporting sites.
|
|
error_button = self.driver.find_element_by_id("error")
|
|
error_button.click()
|
|
time.sleep(1)
|
|
|
|
# check error is open
|
|
self.assertTrue(len(self.driver.find_elements_by_class_name('active')) == 1,
|
|
'error reporting should be open')
|
|
|
|
overlay_close = self.driver.find_element_by_id("report_close")
|
|
overlay_close.click()
|
|
time.sleep(1)
|
|
self.assertTrue(len(self.driver.find_elements_by_class_name('active')) == 0,
|
|
'error reporting should be closed again')
|
|
|
|
@pbtest.repeat_if_failed(5)
|
|
def test_donate_button(self):
|
|
"""Ensure donate button opens EFF website."""
|
|
|
|
EFF_URL = "https://supporters.eff.org/donate/support-privacy-badger"
|
|
|
|
self.open_popup()
|
|
|
|
donate_button = self.driver.find_element_by_id("donate")
|
|
|
|
donate_button.click()
|
|
|
|
# Make sure EFF website not opened in same window.
|
|
if self.driver.current_url != self.popup_url:
|
|
self.fail("EFF website not opened in new window")
|
|
|
|
# Look for EFF website and return if found.
|
|
self.switch_to_window_with_url(EFF_URL)
|
|
|
|
self.wait_for_page_to_start_loading(EFF_URL)
|
|
|
|
self.assertEqual(self.driver.current_url, EFF_URL,
|
|
"EFF website should open after clicking donate button on popup")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|