Bug 1715900 - Add initial tests (and helpers) for the mach test-interventions command; r=jgraham

Depends on D138384

Differential Revision: https://phabricator.services.mozilla.com/D138540
This commit is contained in:
Thomas Wisniewski 2022-02-11 17:27:45 +00:00
Родитель 10326d782c
Коммит 1fbbcbbcc2
12 изменённых файлов: 479 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,131 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import pytest
import time
from selenium.common.exceptions import NoAlertPresentException, NoSuchElementException
from selenium.webdriver.common.by import By
def expect_alert(session, text=None):
try:
alert = session.switch_to.alert
if text is not None:
assert alert.text == text
alert.dismiss()
except NoAlertPresentException:
pass
def is_float_cleared(session, elem1, elem2):
return session.execute_script(
"""return (function(a, b) {
// Ensure that a is placed under
// (and not to the right of) b
return a?.offsetTop >= b?.offsetTop + b?.offsetHeight &&
a?.offsetLeft < b?.offsetLeft + b?.offsetWidth;
}(arguments[0], arguments[1]));""",
elem1,
elem2,
)
def await_getUserMedia_call_on_click(session, elem_to_click):
return session.execute_script(
"""
navigator.mediaDevices.getUserMedia =
navigator.mozGetUserMedia =
navigator.getUserMedia =
() => { window.__gumCalled = true; };
"""
)
elem_to_click.click()
return session.execute_async_script(
"""
var done = arguments[0];
setInterval(500, () => {
if (window.__gumCalled === true) {
done();
}
});
"""
)
class Xpath:
by = By.XPATH
def __init__(self, value):
self.value = value
class Css:
by = By.CSS_SELECTOR
def __init__(self, value):
self.value = value
class Text:
by = By.XPATH
def __init__(self, value):
self.value = f"//*[contains(text(),'{value}')]"
Missing = object()
def find_elements(session, selector, all=True, default=Missing):
try:
if all:
return session.find_elements(selector.by, selector.value)
return session.find_element(selector.by, selector.value)
except NoSuchElementException:
if default is not Missing:
return default
raise
def find_element(session, selector, default=Missing):
return find_elements(session, selector, all=False, default=default)
def assert_not_element(session, sel):
with pytest.raises(NoSuchElementException):
find_element(session, sel)
def await_first_element_of(session, selectors, timeout=None, is_displayed=False):
t0 = time.time()
exc = None
if timeout is None:
timeout = 10
found = [None for sel in selectors]
while time.time() < t0 + timeout:
for i, selector in enumerate(selectors):
try:
ele = find_element(session, selector)
if not is_displayed or ele.is_displayed():
found[i] = ele
return found
except NoSuchElementException as e:
exc = e
time.sleep(0.5)
raise exc if exc is not None else NoSuchElementException
return found
def await_element(session, selector, timeout=None):
return await_first_element_of(session, [selector], timeout)[0]
def load_page_and_wait_for_iframe(session, url, selector, loads=1, timeout=None):
while loads > 0:
session.get(url)
frame = await_element(session, selector, timeout=timeout)
loads -= 1
session.switch_to.frame(frame)
return frame

Просмотреть файл

@ -0,0 +1,17 @@
import pytest
from helpers import Css, expect_alert, find_element
URL = "https://ib.absa.co.za/absa-online/login.jsp"
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
assert find_element(session, Css("html.gecko"))
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
expect_alert(session, text="Browser unsupported")
assert find_element(session, Css("html.unknown"))

Просмотреть файл

@ -0,0 +1,16 @@
import pytest
URL = "http://histography.io/"
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
assert session.current_url == URL
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
assert session.current_url == "http://histography.io/browser_support.htm"

Просмотреть файл

@ -0,0 +1,19 @@
import time
import pytest
from helpers import Css, await_element, find_element
URL = "https://www.bankofamerica.com/"
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
time.sleep(3)
assert find_element(session, Css("#browserUpgradeNoticeBar"), default=None) is None
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
warning = await_element(session, Css("#browserUpgradeNoticeBar"), timeout=3)
assert warning.is_displayed()

Просмотреть файл

@ -0,0 +1,92 @@
import pytest
from helpers import (
Css,
Text,
Xpath,
await_element,
await_first_element_of,
await_getUserMedia_call_on_click,
find_element,
assert_not_element,
)
URL = "https://steamcommunity.com/chat"
USERID_CSS = Css("input#input_username")
PASSWORD_CSS = Css("input#input_password")
SIGNIN_CSS = Css("#login_btn_signin button")
GEAR_CSS = Css(".friendSettingsButton")
AUTH_CSS = Css("input#authcode")
RATE_TEXT = Text("too many login failures")
VOICE_XPATH = Xpath(
"//*[contains(text(), 'Voice') and "
"contains(@class, 'pagedsettings_PagedSettingsDialog_PageListItem')]"
)
MIC_BUTTON_CSS = Css("button.LocalMicTestButton")
UNSUPPORTED_TEXT = Text("currently unsupported in Firefox")
def load_mic_test(session, credentials):
session.get(URL)
userid = find_element(session, USERID_CSS)
password = find_element(session, PASSWORD_CSS)
submit = find_element(session, SIGNIN_CSS)
assert userid.is_displayed()
assert password.is_displayed()
assert submit.is_displayed()
userid.send_keys(credentials["username"])
password.send_keys(credentials["password"])
submit.click()
while True:
[gear, auth, rate] = await_first_element_of(
session, [GEAR_CSS, AUTH_CSS, RATE_TEXT], is_displayed=True, timeout=20
)
if rate:
pytest.skip(
"Too many Steam login attempts detected in a short time; try again later."
)
return None
elif auth:
pytest.skip("Two-factor authentication requested; disable Steam Guard.")
return None
else:
break
assert gear
gear.click()
voice = await_element(session, VOICE_XPATH)
assert voice.is_displayed()
voice.click()
mic_test = await_element(session, MIC_BUTTON_CSS)
assert mic_test.is_displayed()
return mic_test
@pytest.mark.with_interventions
def test_enabled(session, credentials):
mic_test = load_mic_test(session, credentials)
if not mic_test:
return
await_getUserMedia_call_on_click(session, mic_test)
assert_not_element(session, UNSUPPORTED_TEXT)
@pytest.mark.without_interventions
def test_disabled(session, credentials):
mic_test = load_mic_test(session, credentials)
if not mic_test:
return
mic_test.click()
unsupported = await_element(session, UNSUPPORTED_TEXT)
assert unsupported.is_displayed()

Просмотреть файл

@ -0,0 +1,43 @@
import pytest
from helpers import Css, Text, find_element
def load_site(session):
session.get("https://www.mobilesuica.com/")
address = find_element(session, Css("input[name=MailAddress]"), default=None)
password = find_element(session, Css("input[name=Password]"), default=None)
error = find_element(session, Css("input[name=winclosebutton]"), default=None)
# The page can be down at certain times, making testing impossible. For instance:
# "モバイルSuicaサービスが可能な時間は4:00翌日2:00です。
# 時間をお確かめの上、再度実行してください。"
# "Mobile Suica service is available from 4:00 to 2:00 the next day.
# Please check the time and try again."
site_is_down = None is not find_element(
session, Text("時間をお確かめの上、再度実行してください。"), default=None
)
if site_is_down:
pytest.xfail("Site is currently down")
return address, password, error, site_is_down
@pytest.mark.with_interventions
def test_enabled(session):
address, password, error, site_is_down = load_site(session)
if site_is_down:
return
assert address.is_displayed()
assert password.is_displayed()
assert error is None
@pytest.mark.without_interventions
def test_disabled(session):
address, password, error, site_is_down = load_site(session)
if site_is_down:
return
assert address is None
assert password is None
assert error.is_displayed()

Просмотреть файл

@ -0,0 +1,42 @@
import pytest
from helpers import (
Css,
Text,
await_element,
load_page_and_wait_for_iframe,
find_element,
)
# Note that we have to load this page twice, as when it is loaded the
# first time by the tests, the webcompat issue is avoided somehow
# (presumably a script race condition somewhere). However, it is
# triggered consistently the second time it is loaded.
URL = "https://ageor.dipot.com/2020/03/Covid-19-in-Greece.html"
FRAME_SELECTOR = Css("iframe[src^='https://datastudio.google.com/']")
FRAME_TEXT = Text("Coranavirus SARS-CoV-2 (Covid-19) in Greece")
@pytest.mark.with_interventions
def test_enabled(session):
load_page_and_wait_for_iframe(session, URL, FRAME_SELECTOR, loads=2)
assert session.execute_script("return window.indexedDB === undefined;")
success_text = await_element(session, FRAME_TEXT)
assert success_text.is_displayed()
@pytest.mark.without_interventions
def test_disabled(session):
load_page_and_wait_for_iframe(session, URL, FRAME_SELECTOR, loads=2)
assert session.execute_script(
"""
try {
window.indexedDB;
return false;
} catch (_) {
return true;
}
"""
)
assert find_element(session, FRAME_TEXT, default=None) is None

Просмотреть файл

@ -0,0 +1,21 @@
import pytest
from helpers import Css, await_element, find_element
URL = "https://m.aliexpress.com/?tracelog=wwwhome2mobilesitehome"
SELECTOR = Css("#header input[placeholder]")
DISABLED_SELECTOR = Css(f"{SELECTOR.value}:disabled")
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
find_element(session, SELECTOR)
assert find_element(session, DISABLED_SELECTOR, default=None) is None
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
await_element(session, SELECTOR)
find_element(session, DISABLED_SELECTOR)

Просмотреть файл

@ -0,0 +1,17 @@
import pytest
URL = "https://buskocchi.desuca.co.jp/smartPhone.html"
SCRIPT = """return document.getElementById("map_canvas")?.clientHeight;"""
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
assert session.execute_script(SCRIPT)
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
assert session.execute_script(SCRIPT)

Просмотреть файл

@ -0,0 +1,28 @@
import pytest
from helpers import Css, find_element
URL = (
"https://www.saxoinvestor.fr/login/?adobe_mc="
"MCORGID%3D173338B35278510F0A490D4C%2540AdobeOrg%7CTS%3D1621688498"
)
@pytest.mark.skip_platforms("linux")
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
userid = find_element(session, Css("input#field_userid"))
password = find_element(session, Css("input#field_password"))
submit = find_element(session, Css("input#button_login"))
assert userid.is_displayed()
assert password.is_displayed()
assert submit.is_displayed()
@pytest.mark.skip_platforms("linux")
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
warning = find_element(session, Css("#browser_support_section"))
assert warning.is_displayed()

Просмотреть файл

@ -0,0 +1,28 @@
import pytest
from helpers import Css, is_float_cleared, find_element
URL = (
"https://www.lcbo.com/webapp/wcs/stores/servlet/PhysicalStoreInventoryView"
"?langId=-1&storeId=10203&catalogId=10051&productId=54875"
)
PRODUCT_INFO = Css("#content > div")
LOCATIONS = Css("#inventoryTable")
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
product_info = find_element(session, PRODUCT_INFO)
locations = find_element(session, LOCATIONS)
assert is_float_cleared(session, locations, product_info)
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
product_info = find_element(session, PRODUCT_INFO)
locations = find_element(session, LOCATIONS)
assert not is_float_cleared(session, locations, product_info)

Просмотреть файл

@ -0,0 +1,25 @@
import pytest
from helpers import Css, is_float_cleared, find_element
URL = "https://curriculum.gov.bc.ca/curriculum/arts-education/10/media-arts"
SHOULD_CLEAR = Css(".curriculum_big_ideas")
SHOULD_BE_CLEARED = Css(".view-display-id-attachment_1")
@pytest.mark.with_interventions
def test_enabled(session):
session.get(URL)
should_clear = find_element(session, SHOULD_CLEAR)
should_be_cleared = find_element(session, SHOULD_BE_CLEARED)
assert is_float_cleared(session, should_clear, should_be_cleared)
@pytest.mark.without_interventions
def test_disabled(session):
session.get(URL)
should_clear = find_element(session, SHOULD_CLEAR)
should_be_cleared = find_element(session, SHOULD_BE_CLEARED)
assert not is_float_cleared(session, should_clear, should_be_cleared)