{"_id":"testreel","_rev":"4-8981ec13b5b6b87b9df1b1589105b2b4","name":"testreel","dist-tags":{"latest":"0.2.0"},"versions":{"0.0.0":{"name":"testreel","version":"0.0.0","keywords":["video","recording","browser","playwright","demo","screenshot","automation","pr-demo"],"license":"MIT","_id":"testreel@0.0.0","maintainers":[{"name":"greentfrapp","email":"limsweekiat@gmail.com"}],"homepage":"https://github.com/greentfrapp/fipplet#readme","bugs":{"url":"https://github.com/greentfrapp/fipplet/issues"},"bin":{"fipplet":"dist/cli.cjs"},"dist":{"shasum":"59c13561380982614b4fd8c5d9aec8e759ac19e1","tarball":"https://registry.npmjs.org/testreel/-/testreel-0.0.0.tgz","fileCount":16,"integrity":"sha512-VcHj64Uci8f4VY0hAvHKNZMsF3dtPbAntGXqrNBMPxFJeEBAMhCxJUSPUYvZd94ph2BoPdVU1VO5Lpv3bROzUg==","signatures":[{"sig":"MEQCIGoVX7mI8Vfpm0o7pL7tob1e3DGe6kD9XV7eb5/yOoRNAiBsVQDN0CEMD3fz8SHAqj543czAKf5+t2ZvbRY1ywV/vw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":302110},"main":"./dist/index.cjs","pnpm":{"onlyBuiltDependencies":["ffmpeg-static"]},"type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./playwright":{"types":"./dist/fixture.d.ts","import":"./dist/fixture.js","require":"./dist/fixture.cjs"}},"gitHead":"1262be6cd041ca46ca897b6ec5c726abe95c7b60","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","format":"prettier --write 'src/**/*.ts'","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:examples":"playwright test --config examples/playwright.config.ts","prepublishOnly":"tsup"},"_npmUser":{"name":"greentfrapp","email":"limsweekiat@gmail.com"},"repository":{"url":"git+https://github.com/greentfrapp/fipplet.git","type":"git"},"_npmVersion":"11.5.1","description":"Programmatic video infrastructure for web apps","directories":{},"_nodeVersion":"24.7.0","dependencies":{"ws":"^8.19.0","yaml":"^2.8.3","commander":"^14.0.3","jsonc-parser":"^3.3.1","ffmpeg-static":"^5.2.0","@inquirer/prompts":"^8.3.2"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^4.1.0","prettier":"^3.8.1","@types/ws":"^8.18.1","typescript":"^5.5.0","@types/node":"^25.5.0","playwright-core":"^1.58.2","@playwright/test":"^1.58.2","@trivago/prettier-plugin-sort-imports":"^6.0.2"},"peerDependencies":{"playwright-core":">=1.51.0","@playwright/test":">=1.51.0"},"peerDependenciesMeta":{"@playwright/test":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/testreel_0.0.0_1774512897606_0.696990021955513","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"testreel","version":"0.1.0","keywords":["video","recording","browser","playwright","demo","screenshot","automation","pr-demo"],"license":"MIT","_id":"testreel@0.1.0","maintainers":[{"name":"greentfrapp","email":"limsweekiat@gmail.com"}],"homepage":"https://github.com/greentfrapp/testreel#readme","bugs":{"url":"https://github.com/greentfrapp/testreel/issues"},"bin":{"testreel":"dist/cli.cjs"},"dist":{"shasum":"c0cce632f4a3fe2d93c54242bdfefefa5c0b55e3","tarball":"https://registry.npmjs.org/testreel/-/testreel-0.1.0.tgz","fileCount":16,"integrity":"sha512-C5c5pvsx2uPJzTbK1+sDSZQdWavN25Mbd4HiAdHuxJ6PM+pLdw8WLwSBvr86HBKnG7dg589CqrEka9leWPL3ow==","signatures":[{"sig":"MEUCIFJE7cnxqk44cBHbh9JRvptlpCxNCaKu/roMQn3BraaMAiEAqmB8x4xUJihwhG5f8wDnFsejDoo7uI6pCBMNSOy3e1o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":302197},"main":"./dist/index.cjs","pnpm":{"onlyBuiltDependencies":["ffmpeg-static"]},"type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./playwright":{"types":"./dist/fixture.d.ts","import":"./dist/fixture.js","require":"./dist/fixture.cjs"}},"gitHead":"1ee336e6ff3ee974bd402adcb8641d3282a81d94","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","format":"prettier --write 'src/**/*.ts'","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:examples":"playwright test --config examples/playwright.config.ts","prepublishOnly":"tsup"},"_npmUser":{"name":"greentfrapp","email":"limsweekiat@gmail.com"},"repository":{"url":"git+https://github.com/greentfrapp/testreel.git","type":"git"},"_npmVersion":"11.5.1","description":"Programmatic video infrastructure for web apps","directories":{},"_nodeVersion":"24.7.0","dependencies":{"ws":"^8.19.0","yaml":"^2.8.3","commander":"^14.0.3","jsonc-parser":"^3.3.1","ffmpeg-static":"^5.2.0","@inquirer/prompts":"^8.3.2"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^4.1.0","prettier":"^3.8.1","@types/ws":"^8.18.1","typescript":"^5.5.0","@types/node":"^25.5.0","playwright-core":"^1.58.2","@playwright/test":"^1.58.2","@trivago/prettier-plugin-sort-imports":"^6.0.2"},"peerDependencies":{"playwright-core":">=1.51.0","@playwright/test":">=1.51.0"},"peerDependenciesMeta":{"@playwright/test":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/testreel_0.1.0_1774532720910_0.059937886982642796","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"testreel","version":"0.1.1","keywords":["video","recording","browser","playwright","demo","screenshot","automation","pr-demo"],"license":"MIT","_id":"testreel@0.1.1","maintainers":[{"name":"greentfrapp","email":"limsweekiat@gmail.com"}],"homepage":"https://github.com/greentfrapp/testreel#readme","bugs":{"url":"https://github.com/greentfrapp/testreel/issues"},"bin":{"testreel":"dist/cli.cjs"},"dist":{"shasum":"1ced2a53adb2e9e3f12c6f020e3f4e3d865bd706","tarball":"https://registry.npmjs.org/testreel/-/testreel-0.1.1.tgz","fileCount":16,"integrity":"sha512-k1CVpQvHkH7lqIKu0lT9Ro31FMnTcS7aVNiyKx17twN05WdiOeQSmT5sZz9id6zFM4qtp2MnqGzSPfUgPDqp1A==","signatures":[{"sig":"MEQCIA5bvybhuuDoRl8fxKze8wlUAoT08lwTwKolWB1yFU0TAiBjiRzkvW8nmyVvKnQZJxuSC5Gdm4+bqq6XE33zED9bfA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":297009},"main":"./dist/index.cjs","pnpm":{"onlyBuiltDependencies":["ffmpeg-static"]},"type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./playwright":{"types":"./dist/fixture.d.ts","import":"./dist/fixture.js","require":"./dist/fixture.cjs"}},"gitHead":"18f829ea8b3649b58c6e4eadb450c01ad9b00b5d","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","format":"prettier --write 'src/**/*.ts'","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:examples":"playwright test --config examples/playwright.config.ts","prepublishOnly":"tsup"},"_npmUser":{"name":"greentfrapp","email":"limsweekiat@gmail.com"},"repository":{"url":"git+https://github.com/greentfrapp/testreel.git","type":"git"},"_npmVersion":"11.5.1","description":"Programmatic video infrastructure for web apps","directories":{},"_nodeVersion":"24.7.0","dependencies":{"ws":"^8.19.0","yaml":"^2.8.3","commander":"^14.0.3","jsonc-parser":"^3.3.1","ffmpeg-static":"^5.2.0","@inquirer/prompts":"^8.3.2"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^4.1.0","prettier":"^3.8.1","@types/ws":"^8.18.1","typescript":"^5.5.0","@types/node":"^25.5.0","playwright-core":"^1.58.2","@playwright/test":"^1.58.2","@trivago/prettier-plugin-sort-imports":"^6.0.2"},"peerDependencies":{"playwright-core":">=1.51.0","@playwright/test":">=1.51.0"},"peerDependenciesMeta":{"@playwright/test":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/testreel_0.1.1_1774944734400_0.7199847717279131","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"testreel","version":"0.2.0","description":"Programmatic video infrastructure for web apps","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./playwright":{"types":"./dist/fixture.d.ts","import":"./dist/fixture.js","require":"./dist/fixture.cjs"}},"bin":{"testreel":"dist/cli.cjs"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","test:examples":"playwright test --config examples/playwright.config.ts","test:integration":"playwright test --config tests/integration/playwright.config.ts","format":"prettier --write 'src/**/*.ts'","format:check":"prettier --check 'src/**/*.ts'","prepublishOnly":"tsup"},"keywords":["video","recording","browser","playwright","demo","screenshot","automation","pr-demo","screen-recording","demo-video","ci-recording","visual-testing"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/greentfrapp/testreel.git"},"homepage":"https://github.com/greentfrapp/testreel#readme","bugs":{"url":"https://github.com/greentfrapp/testreel/issues"},"engines":{"node":">=20"},"peerDependencies":{"playwright-core":">=1.51.0","@playwright/test":">=1.51.0"},"peerDependenciesMeta":{"@playwright/test":{"optional":true}},"devDependencies":{"@trivago/prettier-plugin-sort-imports":"^6.0.2","@playwright/test":"^1.58.2","@types/node":"^25.5.0","@types/ws":"^8.18.1","playwright-core":"^1.58.2","prettier":"^3.8.1","tsup":"^8.0.0","typescript":"^5.5.0","vitest":"^4.1.0"},"dependencies":{"ffmpeg-static":"^5.2.0","@inquirer/prompts":"^8.3.2","commander":"^14.0.3","jsonc-parser":"^3.3.1","ws":"^8.19.0","yaml":"^2.8.3"},"packageManager":"pnpm@10.30.3","pnpm":{"onlyBuiltDependencies":["ffmpeg-static"]},"gitHead":"6b685f10ec85ce5ac2fb41f84cd04d83f124f560","_id":"testreel@0.2.0","_nodeVersion":"22.22.2","_npmVersion":"11.12.1","dist":{"integrity":"sha512-/MPI77q2NH5bgp87J2pFVXOdV3NOvnOzfyTNc6yKcCDrTDYz0l5BZvSuksDIwDqt+nrIlhGejtJfvz9bwsre9A==","shasum":"eaed8bc601711c117bbe00ebbed44e211845a641","tarball":"https://registry.npmjs.org/testreel/-/testreel-0.2.0.tgz","fileCount":26,"unpackedSize":423443,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/testreel@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGakOJHZWqpevp/edv5Pyr9Bk3wmPmuWSQZkjVCnnYgoAiEAgJxmAInmyxbTYZXDXpzHgBCUT1m0glP8w/1IaLtZGcs="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7f9404ff-037a-4151-ac42-90faf192b823"}},"directories":{},"maintainers":[{"name":"greentfrapp","email":"limsweekiat@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/testreel_0.2.0_1775539826396_0.6780120085493786"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T08:14:57.606Z","modified":"2026-04-07T05:30:26.894Z","0.0.0":"2026-03-26T08:14:57.791Z","0.1.0":"2026-03-26T13:45:21.080Z","0.1.1":"2026-03-31T08:12:14.584Z","0.2.0":"2026-04-07T05:30:26.596Z"},"bugs":{"url":"https://github.com/greentfrapp/testreel/issues"},"license":"MIT","homepage":"https://github.com/greentfrapp/testreel#readme","keywords":["video","recording","browser","playwright","demo","screenshot","automation","pr-demo","screen-recording","demo-video","ci-recording","visual-testing"],"repository":{"type":"git","url":"git+https://github.com/greentfrapp/testreel.git"},"description":"Programmatic video infrastructure for web apps","maintainers":[{"name":"greentfrapp","email":"limsweekiat@gmail.com"}],"readme":"# testreel\n\n[![npm version](https://img.shields.io/npm/v/testreel)](https://www.npmjs.com/package/testreel)\n[![CI](https://github.com/greentfrapp/testreel/actions/workflows/ci.yml/badge.svg)](https://github.com/greentfrapp/testreel/actions/workflows/ci.yml)\n[![license](https://img.shields.io/npm/l/testreel)](https://github.com/greentfrapp/testreel/blob/main/LICENSE)\n\nProgrammatic video recordings for web apps. Define interactions in JSON, get polished screen recordings out.\n\n[Demo video generated with testreel](https://github.com/user-attachments/assets/77dcbbc3-0bde-49e7-99b8-a7cc249be39b)\n\n*Demo video generated with testreel*\n\n- **Let your LLM agent generate product videos** - Just point your agent at this repo and ask it to generate a demo video for your product. Testreel integrates with Playwright, which allows your agent to create recordings with mocks and demo data easily.\n- **Repeatable editable video config** - Instead of having to manually re-record a video because of a typo or a missed click, just edit the config and rerun the recording. Programmatically generate videos with polished background, and cursor and zoom animations.\n\n## Features\n\n- **Animated cursor** — configurable style, size, and click ripple effects\n- **Window chrome** — macOS-style title bar with traffic lights\n- **Background styling** — padding, rounded corners, solid or gradient backgrounds\n- **Multiple auth methods** — setup blocks, localStorage/cookies injection, storage state files, interactive login, Supabase provider\n- **Playwright integration** — test fixture and `recordPage()` API for existing test suites\n- **Output formats** — WebM (default), MP4, GIF\n\n## Install\n\n```bash\nnpm install testreel playwright\nnpx playwright install chromium\n```\n\n## Quick start\n\nCreate a recording definition (`recording.json`):\n\n```json\n{\n  \"url\": \"https://example.com\",\n  \"viewport\": { \"width\": 1280, \"height\": 720 },\n  \"steps\": [\n    { \"action\": \"click\", \"selector\": \"button.sign-in\" },\n    { \"action\": \"fill\", \"selector\": \"#email\", \"text\": \"user@example.com\" },\n    { \"action\": \"screenshot\", \"name\": \"filled-form\" },\n    { \"action\": \"click\", \"selector\": \"button[type=submit]\" },\n    { \"action\": \"wait\", \"ms\": 2000 }\n  ]\n}\n```\n\nRun it:\n\n```bash\nnpx testreel recording.json\n```\n\nOutput goes to `./testreel-output/` — a WebM video, PNG screenshots, and an `output.json` manifest.\n\n### CLI\n\n```bash\nnpx testreel recording.json                       # basic recording\nnpx testreel recording.json --headed              # visible browser\nnpx testreel recording.json --format gif          # GIF output\nnpx testreel recording.json --setup login.json    # separate setup file\nnpx testreel validate recording.json              # validate without recording\nnpx testreel login https://app.com --save-state state.json  # interactive login\nnpx testreel init                                 # create a definition interactively\n```\n\n### API\n\n```js\nimport { record, loadDefinition } from 'testreel'\n\nconst def = loadDefinition('recording.json')\nconst result = await record(def, { outputDir: './output' })\n\nconsole.log(result.video)       // path to .webm file\nconsole.log(result.screenshots) // array of .png paths\n```\n\n### Playwright test fixture\n\nAlready have a Playwright test suite? Add recording to any test — just change `test` to `recorded`:\n\n```js\nimport { test, expect } from '@playwright/test'\nimport { testreelFixtures, type TestreelFixtures } from 'testreel/playwright'\n\nconst recorded = test.extend<TestreelFixtures>({\n  ...testreelFixtures,\n})\n\n// This test is unchanged — no recording\ntest('health check', async ({ page }) => {\n  await page.goto('/health')\n  await expect(page.locator('.status')).toHaveText('OK')\n})\n\n// Just swap test → recorded — video is attached to the test report automatically\nrecorded('product demo', async ({ page }) => {\n  await page.goto('https://myapp.com')\n  await page.click('.login-button')\n  await page.fill('#email', 'user@example.com')\n})\n```\n\nRecordings are captured regardless of test outcome — partial videos are attached to the report for debugging. See [Playwright Integration](docs/playwright.md) for composing with custom fixtures, the `PageRecorder` API, and configuration options.\n\n### recordPage API\n\nFor manual control over recording within any Playwright script:\n\n```js\nimport { recordPage } from 'testreel'\n\n// page must belong to a context created with recordVideo\nconst recorder = await recordPage(page, { chrome: true })\nawait recorder.click('.button')\nawait recorder.type('#search', 'hello')\nconst result = await recorder.stop() // finalizes video + post-processing\nconsole.log(result.video)\n```\n\n## Documentation\n\n| Guide | Description |\n|-------|-------------|\n| [Getting Started](docs/getting-started.md) | Installation, first recording, output explanation |\n| [Recording Definitions](docs/recording-definitions.md) | Full reference for the JSON format |\n| [Actions](docs/actions.md) | All 13 step actions with examples |\n| [Authentication](docs/authentication.md) | Recording authenticated apps |\n| [CLI Reference](docs/cli.md) | All commands and flags |\n| [Playwright Integration](docs/playwright.md) | Test fixture and `recordPage()` API |\n| [Examples](docs/examples.md) | Common recording patterns |\n\n## License\n\n[MIT](LICENSE)\n","readmeFilename":"README.md"}