55 lines
3.6 KiB
Markdown
55 lines
3.6 KiB
Markdown
---
|
|
name: use-vishot-with-web
|
|
description: Capture deterministic web routes with Vishot. Use when the selected Vishot target is a locally runnable browser application and Codex must capture routes, responsive viewports, or interaction-driven UI states without requiring agent-browser.
|
|
---
|
|
|
|
# Use Vishot with Web
|
|
|
|
Prefer product-owned Vishot capture roots when available. Otherwise capture a local URL directly.
|
|
|
|
## Workflow
|
|
|
|
1. Identify the route, state, viewport, theme, locale, and output directory supplied by the caller.
|
|
2. Ensure Vishot's Playwright Chromium runtime exists. If Vishot reports a missing executable, run `pnpm exec playwright install chromium` once and retry.
|
|
3. Start the application with its repository-owned development or preview command.
|
|
4. Wait until the development server reports that it is listening, then let Vishot handle reload stability with an explicit `--settle-ms 2500`. Vishot intentionally has no default delay because it serves projects with different readiness contracts.
|
|
5. Run the documented scene command when the app exposes Vishot capture roots and a ready signal.
|
|
6. Otherwise capture the route directly:
|
|
|
|
```bash
|
|
pnpm exec vishot render \
|
|
--target browser \
|
|
http://127.0.0.1:5173/settings \
|
|
--width 1440 \
|
|
--height 900 \
|
|
--settle-ms 2500 \
|
|
--output-dir /absolute/output/settings
|
|
```
|
|
|
|
7. Repeat for each requested route and viewport. Use `--name` only when URL-derived names collide or fail to describe the state.
|
|
8. Inspect each image for loading screens, stale data, iframe refusal, missing fonts, permission prompts, and animation instability.
|
|
9. Return its stable ID, title, viewport, and absolute path to `$use-vishot` or the caller.
|
|
|
|
## Scenario Readiness and Locators
|
|
|
|
- Implement readiness for the specific route and UI state. A heading, button, or expected text from one page is not a reusable readiness condition for another page.
|
|
- Wait in this order: let Vishot establish URL and reload stability, confirm the final route, wait for a state-specific visible locator, confirm transient overlays or loading indicators are gone, then let Vishot keep its final settle window for remaining bundling, refresh, animation, or rendering.
|
|
- Use text only when it is visible, unique, stable for the selected locale, and intrinsic to the intended state. Do not wait on generic headings, placeholders, network-derived values, or text copied from another scenario.
|
|
- Prefer semantic locators such as `getByRole('button', { name })` and `getByLabel()`. For an icon-only control, locate the owning button by its icon and click the button, not the icon node:
|
|
|
|
```ts
|
|
const settingsButton = page.locator('button').filter({
|
|
has: page.locator('[i-solar\\:settings-minimalistic-outline]'),
|
|
}).first()
|
|
```
|
|
|
|
Escape `:` in attribute-based icon selectors. Inspect the rendered DOM and repository icon usage before choosing a selector; avoid coordinates, `nth-child`, and incidental layout classes.
|
|
- Treat drawers, menus, accordions, onboarding, and responsive navigation as stateful UI. Check the desired content, `aria-expanded`, or `data-state` before clicking a toggle. Make `ensureOpen()`-style helpers idempotent: return when already open, otherwise click once and wait for the open-state postcondition.
|
|
- If no stable accessible or product-owned selector exists, add one to the product scenario or UI instead of weakening the wait to a fixed timeout.
|
|
|
|
## Constraints
|
|
|
|
- Keep the target app local. Do not use this workflow to capture an untrusted remote page.
|
|
- Keep route state deterministic with fixtures or seeded local storage when necessary.
|
|
- Use identical dimensions and device scale behavior for captures that will be compared.
|