# capture — host-side website screenshot tool

Owner-run tooling. Requires `docker run` (developers on this host cannot run
docker directly — only the gateway/owner can). Not part of the Scout app; it
does not deploy with it and adds no dependency to the app image.

Runs Playwright inside `mcr.microsoft.com/playwright/python:v1.49.0-noble`,
an image already present on this host with Python, Chromium/Firefox/WebKit,
and system deps preinstalled. The image does not actually retain the
`playwright` pip package itself (its build venv is deleted after the
browsers are installed), so `run.sh` installs it inside the throwaway `--rm`
container at invocation time, pinned to the matching version (1.49.0) so no
browser download is triggered. Nothing is installed on the host and nothing
is added to any app image -- the container filesystem is discarded on exit.

## Usage

```bash
bash /srv/apps/scout/tools/capture/run.sh sites.json output-dir
```

`sites.json` is a JSON array of sites to capture:

```json
[
  {"slug": "example", "url": "https://example.com"},
  {"slug": "mozilla", "url": "https://www.mozilla.org"}
]
```

`slug` must be kebab-case (`^[a-z0-9][a-z0-9-]*$`); `url` must be http(s).

For each site, two full-page PNGs are written to `output-dir`:

- `<slug>-desktop.png` — 1440x900 viewport, device scale factor 1
- `<slug>-mobile.png` — 390x844 viewport, device scale factor 2, mobile
  emulation (iPhone Safari UA, touch enabled)

Both use locale `en-CA` and timezone `America/Vancouver`.

## Behavior notes

- Each page load waits for `domcontentloaded`, then best-effort waits for
  `networkidle` (many sites never go idle — this is not fatal), then settles
  for 2.5s.
- Before shooting, the page is scrolled to the bottom in steps and back to
  the top to trigger lazy-loaded images, so the full-page screenshot isn't
  full of blank space.
- A small set of common cookie/consent banner selectors are tried
  (OneTrust, HubSpot, generic "Accept" buttons, etc). This is best-effort —
  failure to dismiss a banner never aborts the capture.
- Each capture (one site, one form factor) gets up to 2 attempts before
  being recorded as failed.
- Exit code is 0 only if every requested capture succeeded, 1 otherwise. A
  summary table is printed at the end either way.

## Output permissions

The container runs as root, so output files are initially root-owned.
`run.sh` best-effort `chmod 664`s the PNGs afterward so the host user can
read/manage them; this can silently no-op if permissions don't allow it.
