Adds playwright + pytest-playwright to workspace dev deps, an e2e pytest marker, and a live_server fixture that boots the Flask app on an ephemeral port with a temp SQLite DB. addopts default to -m 'not e2e' so the regular fast suite excludes them; explicit `pytest -m e2e` runs them. Smoke test confirms the live server is reachable. Workspace root pyproject.toml is the right place for the dev deps and pytest config — l4d2web/pyproject.toml is minimal and has neither. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
1.7 KiB
Python
64 lines
1.7 KiB
Python
"""Pytest fixtures for end-to-end browser tests.
|
|
|
|
Boots the Flask app in a background thread on an ephemeral port and
|
|
yields the base URL. The app uses a temp SQLite DB so e2e runs don't
|
|
contaminate the dev database.
|
|
"""
|
|
|
|
import socket
|
|
import threading
|
|
|
|
import pytest
|
|
from werkzeug.serving import make_server
|
|
|
|
from l4d2web.app import create_app
|
|
from l4d2web.auth import hash_password
|
|
from l4d2web.db import init_db, session_scope
|
|
from l4d2web.models import Blueprint, User
|
|
|
|
|
|
def _free_port() -> int:
|
|
s = socket.socket()
|
|
s.bind(("127.0.0.1", 0))
|
|
port = s.getsockname()[1]
|
|
s.close()
|
|
return port
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def live_server(tmp_path, monkeypatch):
|
|
db_path = tmp_path / "e2e.db"
|
|
db_url = f"sqlite:///{db_path}"
|
|
monkeypatch.setenv("DATABASE_URL", db_url)
|
|
app = create_app({"TESTING": False, "DATABASE_URL": db_url, "SECRET_KEY": "e2e"})
|
|
init_db()
|
|
|
|
with session_scope() as session:
|
|
user = User(
|
|
username="alice",
|
|
password_digest=hash_password("secret"),
|
|
admin=False,
|
|
)
|
|
session.add(user)
|
|
session.flush()
|
|
bp = Blueprint(
|
|
user_id=user.id, name="bp", arguments="[]", config="[]"
|
|
)
|
|
session.add(bp)
|
|
session.flush()
|
|
blueprint_id = bp.id
|
|
user_id = user.id
|
|
|
|
port = _free_port()
|
|
server = make_server("127.0.0.1", port, app)
|
|
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
thread.start()
|
|
try:
|
|
yield {
|
|
"base_url": f"http://127.0.0.1:{port}",
|
|
"user_id": user_id,
|
|
"blueprint_id": blueprint_id,
|
|
}
|
|
finally:
|
|
server.shutdown()
|
|
thread.join(timeout=2)
|