# Capture Playwright

> Use when a screenshot or short video needs to be captured with Playwright and saved to local disk, with optional upload through `gh image` (upload requires explicit user approval and must target a PR or issue).

- Skill: `kenn-io/capture-playwright` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kenn-io/capture-playwright`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kenn-io/capture-playwright/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: kenn-io (https://skillmd.com/u/kenn-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kenn-io/capture-playwright

---


# capture-playwright

Generate the artifact with Playwright and save it to local disk. **Do not upload by default.**

## Upload Policy

- **Never upload screenshots or videos that are not attached to a specific PR or issue.** Standalone uploads with no PR/issue target are forbidden.
- **Default is local-only.** Always save artifacts to disk first. Treat that as the finished output unless the user explicitly asks for an upload.
- **Before uploading any image or video, prompt the user for confirmation.** Ask the user to approve the upload, stating the file path and the target PR/issue. No exceptions — even if the workflow calls for it, ask first.
- **NEVER UPLOAD AN IMAGE THAT WAS GENERATED BY POINTING AT A LIVE PREEXISTING kenn-forge APP** This poses risks to leak sensitive information via screenshot

Reference session: `http://127.0.0.1:8080/sessions/opencode%3Ases_2826059aeffeEtdyCVsVwnKi6R`

## Workflow

1. Prefer the repo's existing Playwright config and startup flow. Only add a temporary script or spec if no existing path can capture the state; delete temporary capture code afterward.
2. Save artifacts under a temp path like `tmp/` or `artifacts/` unless the user explicitly wants them committed.
3. For screenshots, use Playwright directly:

```js
await page.screenshot({ path: "tmp/capture.png", fullPage: true });
```

4. For video, create a recording context, close it, then resolve the generated file:

```js
const context = await browser.newContext({
  recordVideo: { dir: "tmp/video", size: { width: 1440, height: 900 } },
});
const page = await context.newPage();
// ... drive the page ...
await context.close();
const videoPath = await page.video()?.path();
```

5. **Stop here by default.** Report the local artifact path to the user and open the image / video using `open` or `xdg-open` so that user can see the image.  Only proceed to upload if the user explicitly requests it.

6. **If the user approves upload**, confirm the target PR or issue number first. Never upload without attaching to a specific PR or issue. Upload the file with `gh image` (the command prints a markdown snippet whose links already point at the uploaded content), then immediately attach it to the PR or issue via a comment — `gh image` alone does not bind the upload to any target:

```bash
# Upload and capture the markdown link
IMAGE_MD=$(gh image --repo owner/repo "tmp/capture.png")

# Attach to a PR or issue so the image is not a standalone upload
gh pr comment <number> --repo owner/repo --body "$IMAGE_MD"
# or for issues:
gh issue comment <number> --repo owner/repo --body "$IMAGE_MD"
```

**`gh image --repo owner/repo <file>` alone is insufficient** — it uploads without binding to a PR or issue. Always follow up with a comment command to attach.

For screenshots, the emitted markdown can usually be pasted as-is.

For videos, `gh image` may still emit image-style markdown like `![demo.webm](...)`. GitHub PR descriptions and comments do not reliably inline `.webm` attachments from that syntax, so normalize it to a plain link such as `[demo.webm](...)` or `https://...` before pasting into a PR description or comment, video links need to be on their OWN line.

If video upload is rejected, keep the local video file, say that `gh image` appears image-only in this environment, and ask whether a screenshot link or a different upload path is preferred.

## Extension Setup

Check whether the extension is available:

```bash
gh image --help
```

If it is missing, install the extension used in the reference session:

```bash
gh extension install drogers0/gh-image
```

## Cookie Failure Mode

The reference session established that `gh image` may depend on GitHub web-upload cookies from a local browser profile. If errors mention cookies, browser profiles, `Local State`, `Cookies`, Chrome, Brave, Edge, or Chromium, do not assume `gh auth login` is enough.

Tell the user to sign in to GitHub in Chrome, Brave, Edge, or Chromium on that machine, then rerun `gh image`.

## Output

Return:
- the local artifact path (always)
- if uploaded: the markdown link(s) printed by `gh image` and the target PR/issue
- for video uploads, the normalized plain-link form to paste into a PR description or comment
- a brief note if video upload had to fall back to screenshots or another path

