mirror of https://github.com/pyodide/pyodide.git
238 lines
7.4 KiB
Python
238 lines
7.4 KiB
Python
import contextlib
|
|
|
|
import pytest
|
|
|
|
from .browser import (
|
|
BrowserWrapper,
|
|
NodeWrapper,
|
|
PlaywrightChromeWrapper,
|
|
PlaywrightFirefoxWrapper,
|
|
SeleniumChromeWrapper,
|
|
SeleniumFirefoxWrapper,
|
|
)
|
|
from .server import spawn_web_server
|
|
from .utils import parse_driver_timeout, set_webdriver_script_timeout
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def playwright_browsers(request):
|
|
if request.config.option.runner.lower() != "playwright":
|
|
yield {}
|
|
else:
|
|
# import playwright here to allow running tests without playwright installation
|
|
try:
|
|
from playwright.sync_api import sync_playwright
|
|
except ImportError:
|
|
pytest.exit(
|
|
"playwright not installed. try `pip install playwright && python -m playwright install`",
|
|
returncode=1,
|
|
)
|
|
|
|
with sync_playwright() as p:
|
|
try:
|
|
chromium = p.chromium.launch(
|
|
args=[
|
|
"--js-flags=--expose-gc",
|
|
],
|
|
)
|
|
firefox = p.firefox.launch()
|
|
# webkit = p.webkit.launch()
|
|
except Exception as e:
|
|
pytest.exit(f"playwright failed to launch\n{e}", returncode=1)
|
|
try:
|
|
yield {
|
|
"chrome": chromium,
|
|
"firefox": firefox,
|
|
# "webkit": webkit,
|
|
}
|
|
finally:
|
|
chromium.close()
|
|
firefox.close()
|
|
# webkit.close()
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def selenium_common(
|
|
request, web_server_main, load_pyodide=True, script_type="classic", browsers=None
|
|
):
|
|
"""Returns an initialized selenium object.
|
|
|
|
If `_should_skip_test` indicate that the test will be skipped,
|
|
return None, as initializing Pyodide for selenium is expensive
|
|
"""
|
|
|
|
server_hostname, server_port, server_log = web_server_main
|
|
runner_type = request.config.option.runner.lower()
|
|
cls: type[BrowserWrapper]
|
|
|
|
browser_set = {
|
|
("selenium", "firefox"): SeleniumFirefoxWrapper,
|
|
("selenium", "chrome"): SeleniumChromeWrapper,
|
|
("selenium", "node"): NodeWrapper,
|
|
("playwright", "firefox"): PlaywrightFirefoxWrapper,
|
|
("playwright", "chrome"): PlaywrightChromeWrapper,
|
|
("playwright", "node"): NodeWrapper,
|
|
}
|
|
|
|
cls = browser_set.get((runner_type, request.param))
|
|
if cls is None:
|
|
raise AssertionError(
|
|
f"Unknown runner or browser: {runner_type} / {request.param}"
|
|
)
|
|
|
|
dist_dir = request.config.getoption("--dist-dir")
|
|
runner = cls(
|
|
server_port=server_port,
|
|
server_hostname=server_hostname,
|
|
server_log=server_log,
|
|
load_pyodide=load_pyodide,
|
|
browsers=browsers,
|
|
script_type=script_type,
|
|
dist_dir=dist_dir,
|
|
)
|
|
try:
|
|
yield runner
|
|
finally:
|
|
runner.quit()
|
|
|
|
|
|
@pytest.fixture(params=["firefox", "chrome", "node"], scope="function")
|
|
def selenium_standalone(request, web_server_main, playwright_browsers):
|
|
with selenium_common(
|
|
request, web_server_main, browsers=playwright_browsers
|
|
) as selenium:
|
|
with set_webdriver_script_timeout(
|
|
selenium, script_timeout=parse_driver_timeout(request.node)
|
|
):
|
|
try:
|
|
yield selenium
|
|
finally:
|
|
print(selenium.logs)
|
|
|
|
|
|
@pytest.fixture(params=["firefox", "chrome", "node"], scope="module")
|
|
def selenium_esm(request, web_server_main, playwright_browsers):
|
|
with selenium_common(
|
|
request,
|
|
web_server_main,
|
|
load_pyodide=True,
|
|
browsers=playwright_browsers,
|
|
script_type="module",
|
|
) as selenium:
|
|
with set_webdriver_script_timeout(
|
|
selenium, script_timeout=parse_driver_timeout(request.node)
|
|
):
|
|
try:
|
|
yield selenium
|
|
finally:
|
|
print(selenium.logs)
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def selenium_standalone_noload_common(
|
|
request, web_server_main, playwright_browsers, script_type="classic"
|
|
):
|
|
with selenium_common(
|
|
request,
|
|
web_server_main,
|
|
load_pyodide=False,
|
|
browsers=playwright_browsers,
|
|
script_type=script_type,
|
|
) as selenium:
|
|
with set_webdriver_script_timeout(
|
|
selenium, script_timeout=parse_driver_timeout(request.node)
|
|
):
|
|
try:
|
|
yield selenium
|
|
finally:
|
|
print(selenium.logs)
|
|
|
|
|
|
@pytest.fixture(params=["firefox", "chrome"], scope="function")
|
|
def selenium_webworker_standalone(
|
|
request, web_server_main, playwright_browsers, script_type
|
|
):
|
|
# Avoid loading the fixture if the test is going to be skipped
|
|
if request.param == "firefox" and script_type == "module":
|
|
pytest.skip("firefox does not support module type web worker")
|
|
|
|
with selenium_standalone_noload_common(
|
|
request, web_server_main, playwright_browsers, script_type=script_type
|
|
) as selenium:
|
|
yield selenium
|
|
|
|
|
|
@pytest.fixture(params=["firefox", "chrome", "node"], scope="function")
|
|
def selenium_standalone_noload(request, web_server_main, playwright_browsers):
|
|
"""Only difference between this and selenium_webworker_standalone is that
|
|
this also tests on node."""
|
|
|
|
with selenium_standalone_noload_common(
|
|
request, web_server_main, playwright_browsers
|
|
) as selenium:
|
|
yield selenium
|
|
|
|
|
|
# selenium instance cached at the module level
|
|
@pytest.fixture(params=["firefox", "chrome", "node"], scope="module")
|
|
def selenium_module_scope(request, web_server_main, playwright_browsers):
|
|
with selenium_common(
|
|
request, web_server_main, browsers=playwright_browsers
|
|
) as selenium:
|
|
yield selenium
|
|
|
|
|
|
# Hypothesis is unhappy with function scope fixtures. Instead, use the
|
|
# module scope fixture `selenium_module_scope` and use:
|
|
# `with selenium_context_manager(selenium_module_scope) as selenium`
|
|
@contextlib.contextmanager
|
|
def selenium_context_manager(selenium_module_scope):
|
|
try:
|
|
selenium_module_scope.clean_logs()
|
|
yield selenium_module_scope
|
|
finally:
|
|
print(selenium_module_scope.logs)
|
|
|
|
|
|
@pytest.fixture
|
|
def selenium(request, selenium_module_scope):
|
|
with selenium_context_manager(selenium_module_scope) as selenium:
|
|
with set_webdriver_script_timeout(
|
|
selenium, script_timeout=parse_driver_timeout(request.node)
|
|
):
|
|
yield selenium
|
|
|
|
|
|
@pytest.fixture(params=["firefox", "chrome"], scope="function")
|
|
def console_html_fixture(request, web_server_main, playwright_browsers):
|
|
with selenium_common(
|
|
request, web_server_main, load_pyodide=False, browsers=playwright_browsers
|
|
) as selenium:
|
|
selenium.goto(
|
|
f"http://{selenium.server_hostname}:{selenium.server_port}/console.html"
|
|
)
|
|
selenium.javascript_setup()
|
|
try:
|
|
yield selenium
|
|
finally:
|
|
print(selenium.logs)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def web_server_main(request):
|
|
"""Web server that serves files in the dist directory"""
|
|
with spawn_web_server(request.config.option.dist_dir) as output:
|
|
yield output
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def web_server_secondary(request):
|
|
"""Secondary web server that serves files dist directory"""
|
|
with spawn_web_server(request.config.option.dist_dir) as output:
|
|
yield output
|
|
|
|
|
|
@pytest.fixture(params=["classic", "module"], scope="module")
|
|
def script_type(request):
|
|
return request.param
|