Skip to content

Commit

Permalink
ENH Add fixtures for JSPI
Browse files Browse the repository at this point in the history
These let us enable JSPI only for specific tests rather than globally, and allows
marking tests as jspi-only or to be run with both jspi and no jspi.
  • Loading branch information
hoodmane committed Jul 31, 2023
1 parent 05f95eb commit d8b8a58
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 14 deletions.
38 changes: 33 additions & 5 deletions pytest_pyodide/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def selenium_common(
load_pyodide=True,
script_type="classic",
browsers=None,
jspi=False,
):
"""Returns an initialized selenium object.
Expand Down Expand Up @@ -110,6 +111,7 @@ def selenium_common(
browsers=browsers,
script_type=script_type,
dist_dir=dist_dir,
jspi=jspi,
)
try:
yield runner
Expand Down Expand Up @@ -239,11 +241,37 @@ def selenium_context_manager(selenium_module_scope):

@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
with selenium_context_manager(

Check warning on line 244 in pytest_pyodide/fixture.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/fixture.py#L244

Added line #L244 was not covered by tests
selenium_module_scope
) as selenium, set_webdriver_script_timeout(
selenium, script_timeout=parse_driver_timeout(request.node)
):
yield selenium

Check warning on line 249 in pytest_pyodide/fixture.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/fixture.py#L249

Added line #L249 was not covered by tests


@pytest.fixture
def selenium_jspi(request, runtime, web_server_main, playwright_browsers):
if runtime in ["firefox", "safari"]:
pytest.skip(f"jspi not supported in {runtime}")
with selenium_common(

Check warning on line 256 in pytest_pyodide/fixture.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/fixture.py#L252-L256

Added lines #L252 - L256 were not covered by tests
request, runtime, web_server_main, browsers=playwright_browsers, jspi=True
) as selenium, set_webdriver_script_timeout(
selenium, script_timeout=parse_driver_timeout(request.node)
):
yield selenium

Check warning on line 261 in pytest_pyodide/fixture.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/fixture.py#L261

Added line #L261 was not covered by tests


@pytest.fixture(params=[False, True])
def selenium_also_with_jspi(request, runtime, web_server_main, playwright_browsers):
jspi = request.param
if jspi and runtime in ["firefox", "safari"]:
pytest.skip(f"jspi not supported in {runtime}")
with selenium_common(

Check warning on line 269 in pytest_pyodide/fixture.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/fixture.py#L264-L269

Added lines #L264 - L269 were not covered by tests
request, runtime, web_server_main, browsers=playwright_browsers, jspi=jspi
) as selenium, set_webdriver_script_timeout(
selenium, script_timeout=parse_driver_timeout(request.node)
):
yield selenium

Check warning on line 274 in pytest_pyodide/fixture.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/fixture.py#L274

Added line #L274 was not covered by tests


@pytest.fixture(scope="function")
Expand Down
30 changes: 21 additions & 9 deletions pytest_pyodide/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def __init__(
load_pyodide=True,
script_type="classic",
dist_dir=None,
jspi=False,
*args,
**kwargs,
):
Expand All @@ -125,7 +126,7 @@ def __init__(
self.server_log = server_log
self.script_type = script_type
self.dist_dir = dist_dir
self.driver = self.get_driver()
self.driver = self.get_driver(jspi)

Check warning on line 129 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L129

Added line #L129 was not covered by tests
self.set_script_timeout(self.script_timeout)
self.prepare_driver()
self.javascript_setup()
Expand All @@ -135,7 +136,7 @@ def __init__(
self.save_state()
self.restore_state()

def get_driver(self):
def get_driver(self, jspi=False):
raise NotImplementedError()

def goto(self, page):
Expand Down Expand Up @@ -378,7 +379,9 @@ def __init__(self, browsers, *args, **kwargs):
def goto(self, page):
self.driver.goto(page)

def get_driver(self):
def get_driver(self, jspi=False):
if jspi:
raise NotImplementedError("JSPI not supported with playwright")

Check warning on line 384 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L383-L384

Added lines #L383 - L384 were not covered by tests
return self.browsers[self.browser].new_page()

def set_script_timeout(self, timeout):
Expand Down Expand Up @@ -417,7 +420,9 @@ def run_js_inner(self, code, check_code):
class SeleniumFirefoxRunner(_SeleniumBaseRunner):
browser = "firefox"

def get_driver(self):
def get_driver(self, jspi=False):
if jspi:
raise NotImplementedError("JSPI not supported in Firefox")

Check warning on line 425 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L424-L425

Added lines #L424 - L425 were not covered by tests
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
Expand All @@ -433,13 +438,16 @@ def get_driver(self):
class SeleniumChromeRunner(_SeleniumBaseRunner):
browser = "chrome"

def get_driver(self):
def get_driver(self, jspi=False):
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
if jspi:
options.add_argument("--enable-features=WebAssemblyExperimentalJSPI")
options.add_argument("--enable-experimental-webassembly-features")

Check warning on line 450 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L448-L450

Added lines #L448 - L450 were not covered by tests
for flag in CHROME_FLAGS:
options.add_argument(flag)
return Chrome(options=options)
Expand All @@ -452,7 +460,9 @@ class SeleniumSafariRunner(_SeleniumBaseRunner):
browser = "safari"
script_timeout = 30

def get_driver(self):
def get_driver(self, jspi=False):
if jspi:
raise NotImplementedError("JSPI not supported in Firefox")

Check warning on line 465 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L464-L465

Added lines #L464 - L465 were not covered by tests
from selenium.webdriver import Safari
from selenium.webdriver.safari.options import Options

Expand All @@ -475,7 +485,7 @@ class PlaywrightFirefoxRunner(_PlaywrightBaseRunner):
class NodeRunner(_BrowserBaseRunner):
browser = "node"

def init_node(self):
def init_node(self, jspi=False):
curdir = Path(__file__).parent
self.p = pexpect.spawn("/bin/bash", timeout=60)
self.p.setecho(False)
Expand All @@ -488,6 +498,8 @@ def init_node(self):
extra_args = NODE_FLAGS[:]
# Node v14 require the --experimental-wasm-bigint which
# produces errors on later versions
if jspi:
extra_args.append("--experimental-wasm-stack-switching")

Check warning on line 502 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L501-L502

Added lines #L501 - L502 were not covered by tests
if node_version.startswith("v14"):
extra_args.append("--experimental-wasm-bigint")

Expand All @@ -500,9 +512,9 @@ def init_node(self):
except (pexpect.exceptions.EOF, pexpect.exceptions.TIMEOUT):
raise JavascriptException("", self.p.before.decode()) from None

def get_driver(self):
def get_driver(self, jspi=False):
self._logs = []
self.init_node()
self.init_node(jspi)

Check warning on line 517 in pytest_pyodide/runner.py

View check run for this annotation

Codecov / codecov/patch

pytest_pyodide/runner.py#L517

Added line #L517 was not covered by tests

class NodeDriver:
def __getattr__(self, x):
Expand Down
7 changes: 7 additions & 0 deletions tests/test_fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@ def test_playwright_browsers(playwright_browsers, request):
runtimes = pytest.pyodide_runtimes

assert set(playwright_browsers.keys()) == set(runtimes)


@run_in_pyodide
def test_jspi(selenium_jspi):
from js import WebAssembly

assert hasattr(WebAssembly, "Suspender")

0 comments on commit d8b8a58

Please sign in to comment.