import socket import threading from wsgiref import simple_server import pytest @pytest.fixture(scope="session") def server_port(): """Return a (likely) free port. Note that due to OS race conditions between picking the port and opening something on it, it might be taken again, but that is unlikely. """ sock = socket.socket(socket.AF_INET) sock.bind(("", 0)) port = sock.getsockname()[1] sock.close() return port @pytest.fixture(scope="session", autouse=True) def running_server(server_port, app): """Have the app running as an actual server.""" server = simple_server.make_server("127.0.0.1", server_port, app) thread = threading.Thread(target=server.serve_forever) thread.daemon = True thread.start() yield server.shutdown() @pytest.fixture def browser_context_args(server_port) -> dict: return {"base_url": f"http://localhost:{server_port}"} @pytest.fixture def dbaccess(app): """Provide direct access to the database. This is needed for the selenium tests, because the normal "dbsession" fixture has a doomed transaction attached. This is nice for keeping the test database clean, but it does mean that the changes are not propagated through and the running WSGI app cannot read them. """ session_factory = app.registry["dbsession_factory"] return session_factory()