# STARTHERE — mgf-uitest-web

> **Sibling library in the Magogi Foundation federation.**
> See [README.md](README.md) for what this library does; see
> [PUBLIC_API.md](PUBLIC_API.md) for the surface; see
> [FEDERATION.md](FEDERATION.md) for the federation contract.

`mgf-uitest-web` is a **browser-level UI-testing harness** for the Magogi web
consoles: a `pytest11` plugin + small library that launches each console
(ProofWarden / `mgf-test-web`, `mgf-fed-web`, `mgf-cloud-web`) as a black-box
subprocess on an ephemeral localhost port and drives it in a **real Chromium via
Playwright** — asserting layout integrity, accessibility (axe-core), and runtime
health that an in-process `TestClient` can't see (it renders no CSS, runs no
JavaScript, and never opens a browser).

## The black-box model — read this first

The harness never imports FastAPI/Jinja or any console's stack. It runs each
console the way an operator does: as its **own `mgf-*-web` CLI**, from the
console's own virtualenv, spawned as a subprocess on an ephemeral port and driven
over HTTP. Its only runtime dependencies are `playwright`,
`axe-playwright-python`, and `pytest`. (`mgf-common` is **not** a runtime
dependency — only a `[standards]` extra.)

A consuming console provides exactly **one** fixture — `console_launch`, returning
a `ConsoleLaunch` that says how to start itself on the injected `console_port`.
The plugin supplies everything else:

```
console_port (free_port) → console_launch → console_server (live_server spawns
the CLI, polls until it serves) → ui_browser (session Chromium) → ui_context
(viewport × colour scheme) → ui_page → console  ← what your spec uses
```

A spec then reads as a handful of lines: `console.open("/")` then
`assert_layout_clean()` / `assert_accessible()` / `assert_healthy()` (or
`assert_ok()` for all of them) and `snapshot("overview")`.

## The modules

| Module | What it does |
|---|---|
| `src/mgf/uitest_web/server.py` | Launch a console subprocess + wait until it serves — `live_server`, `LiveServer`, `free_port`, `ServerStartError` (and the `UITestWebError` base it derives from). |
| `src/mgf/uitest_web/browser.py` | Launch the pinned, bundled Chromium — `launch_browser`. |
| `src/mgf/uitest_web/checks.py` | The pillar checks — `audit_layout`/`LayoutReport`, `scan_a11y`/`describe_a11y`, `watch_health`/`HealthWatch`, `capture`. |
| `src/mgf/uitest_web/console.py` | The ergonomic wrapper — `Console`, `ConsoleLaunch`, `Viewport`. |
| `src/mgf/uitest_web/plugin.py` | The `pytest11` fixtures (registered on install). |

## Running the suite

The harness uses Playwright's **pinned** Chromium — never a system-browser
fallback, because a different browser resolves CSS `@import` / relative URLs
differently and produces findings that don't reproduce. One-time setup, then run:

```bash
uv venv
uv pip install -e ".[dev]"
python -m playwright install chromium
PYTHONPATH=src python -m pytest tests/
```

Screenshots land in `tests/_artifacts/gallery/` (page × width × theme). See
`tests/proofwarden/conftest.py` for a worked `console_launch` fixture.

## For contributors

See [CONTRIBUTING.md](CONTRIBUTING.md). Standards are inherited from
[mgf-standard](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/)
via the `mgf-common[standards]` extra — see
[docs/standards/README.md](docs/standards/README.md).

## Quick links

| Resource | Where |
|---|---|
| Library purpose | [README.md](README.md) |
| Stable surface | [PUBLIC_API.md](PUBLIC_API.md) |
| Release notes | [CHANGELOG.md](CHANGELOG.md) |
| What we depend on / who depends on us | [DEPS.md](DEPS.md) |
| Scope policy | [SCOPE.md](SCOPE.md) |
| Conformance ledger | [docs/inprogress/MGF_STANDARDS_CONFORMANCE.md](docs/inprogress/MGF_STANDARDS_CONFORMANCE.md) |
| Federation contract | [FEDERATION.md](FEDERATION.md) |
| Cross-project standards | [docs/standards/README.md](docs/standards/README.md) |
