from pathlib import Path from pytest import fixture from pytest_pyodide.server import spawn_web_server from pytest_pyodide import runner

import logging

TEST_PATH = Path(__file__).parents.resolve()

class BaseRunner(runner._BrowserBaseRunner):

def __init__(
    self,
    *args,
    test_dir,
    **kwargs,
):
    self.test_dir = test_dir
    super().__init__(
        *args,
        **kwargs,
        load_pyodide=False,
    )

def prepare_driver(self):
    self.base_url = (
        f"http://{self.server_hostname}:{self.server_port}/{self.test_dir}/"
    )
    self.goto(f"{self.base_url}/test.html")

def javascript_setup(self):
    self.run_js("globalThis.TestModule = await globalThis.Module();")

class FirefoxRunner(BaseRunner, runner.SeleniumFirefoxRunner):

pass

class ChromeRunner(BaseRunner, runner.SeleniumChromeRunner):

pass

# TODO: Figure out how to get NodeRunner to work.

RUNNER_DICT = {x.browser: x for x in [FirefoxRunner, ChromeRunner]}

@fixture(params=list(RUNNER_DICT), scope=“class”) def selenium_class_scope(request, web_server_main):

server_hostname, server_port, server_log = web_server_main
assert request.param in RUNNER_DICT

logger = logging.getLogger('selenium')
logger.setLevel(logging.DEBUG)

cls = RUNNER_DICT[request.param]
selenium = cls(
    test_dir=request.cls.TEST_BUILD_DIR,
    server_port=server_port,
    server_hostname=server_hostname,
    server_log=server_log,
)
request.cls.call_number = 0
try:
    yield selenium
finally:
    print(selenium.logs)
    selenium.driver.quit()

@fixture(scope=“function”) def selenium(selenium_class_scope, request):

selenium = selenium_class_scope
request.cls.call_number += 1
# Refresh page every 50 calls to prevent firefox out of memory errors
if request.cls.call_number % 50 == 0:
    selenium.driver.refresh()
    selenium.javascript_setup()
selenium.clean_logs()
yield selenium

@fixture(scope=“session”) def web_server_main(request):

with spawn_web_server(TEST_PATH) as output:
    yield output