39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
"""Shared Playwright auth helper (phase 16).
|
|
|
|
``login`` drives the REAL form login on /login.html (fill → submit →
|
|
redirect) so every story that needs the admin does exactly what a human
|
|
would — no cookie surgery. ``password=None`` uses the shared E2E admin
|
|
password (success path); pass a wrong value to drive the error state
|
|
(no redirect, ``#login-error`` role=alert visible, still anonymous).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from playwright.sync_api import Page, expect
|
|
|
|
from e2e.conftest import ADMIN_PASSWORD # noqa: F401 (re-exported for tests)
|
|
|
|
DEFAULT_NEXT = "/sources.html"
|
|
|
|
|
|
def login(page: Page, app_url: str, password: str | None = None, next: str | None = None) -> None:
|
|
"""Perform the real form login and wait for its outcome.
|
|
|
|
* correct password (or ``password=None`` → the shared admin password)
|
|
→ redirects to ``next`` (default ``/sources.html``);
|
|
* wrong password → ``#login-error`` (role=alert) is visible, the URL
|
|
never changes, and the visitor is still anonymous.
|
|
"""
|
|
attempt = ADMIN_PASSWORD if password is None else password
|
|
url = f"{app_url}/login.html"
|
|
if next is not None:
|
|
url += f"?next={next}"
|
|
page.goto(url)
|
|
expect(page.locator("#login-password")).to_be_visible()
|
|
page.fill("#login-password", attempt)
|
|
page.click("#login-form button[type=submit]")
|
|
if attempt != ADMIN_PASSWORD:
|
|
expect(page.locator("#login-error")).to_be_visible(timeout=15_000)
|
|
expect(page).to_have_url(url) # no redirect on failure
|
|
return
|
|
expect(page).to_have_url(app_url + (next or DEFAULT_NEXT), timeout=30_000)
|