# `PhxDemo.Case`
[🔗](https://github.com/thenatespack/phoenix_demo/blob/main/lib/phx_demo/case.ex#L1)

ExUnit case template for demos.

    use PhxDemo.Case
    use PhxDemo.Case, viewport: %{width: 1920, height: 1080}, output_dir: "priv/demos"

It wraps `PhoenixTest.Playwright.Case`, so every PhoenixTest and
`PhoenixTest.Playwright` function is available. `:viewport`, `:output_dir`,
`:check_env`, `:camera_fixtures` (paths checked in pre-flight) and the presentation settings in `PhxDemo.settings/1`
(`:intro`, `:outro`, `:captions`, `:zoom`, `:trim`, …) are
handled here; any other option is passed through. The defaults are
`async: false` and `ecto_sandbox_stop_owner_delay: 200`.

## What gets recorded

1. A one-frame-ish magenta "sync" flash on the blank page. The timeline
   clock starts at that moment and rendering finds it in the video, so
   timeline offsets are frame-accurate. It's trimmed away.
2. The intro card (if enabled).
3. The demo body.
4. A final screenshot for drift checks (`PhxDemo.Drift`), then the outro card.

Before the first demo runs, `PhxDemo.Env.check_once!/0` verifies the
endpoint is serving and assets are built. Disable that with `check_env: false`.
The same pre-flight verifies that every fixture file named literally in an
`upload/4`, `drop_files/4`, `upload_audio/4` or `use_microphone/3` call exists
(see `PhxDemo.Fixtures`).

Define demos with `demo/3` instead of `test/3`. A plain `test` in the same
module runs without recording.

# `demo`
*macro* 

Defines a recorded demo. Same shape as `ExUnit.Case.test/3`.

Sets the `browser_context_opts` tag (viewport and `record_video`), so don't
set that tag yourself on a demo. Use the `:viewport` option on `use` instead.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
