feat(screenci): update config and docs

This commit is contained in:
Olli Paloviita
2026-05-22 22:26:31 +03:00
parent ad82f0ce09
commit 0558752b61
9 changed files with 70 additions and 32 deletions
+1 -8
View File
@@ -2,7 +2,7 @@
Your UI changed. Your demo videos didn't. screenci fixes that.
Record product walkthroughs as code. When the UI ships, run `screenci record` and your videos regenerate. No clicky re-recordings, no stale screenshots, no passive-aggressive Slack messages from the docs team.
Record product walkthroughs as code. When the UI ships, run `npx screenci record` and your videos regenerate. No clicky re-recordings, no stale screenshots, no passive-aggressive Slack messages from the docs team.
## Install
@@ -82,13 +82,6 @@ npx screenci test --ui
npx screenci record
```
Or via the package scripts scaffolded by `init`:
```bash
npm run test # → npx screenci test
npm run record # → npx screenci record
```
Recordings land in `.screenci/<video-name>/recording.mp4` alongside a `data.json` with all the interaction events.
## Configure
+10 -2
View File
@@ -1472,7 +1472,7 @@ describe('CLI', () => {
)
expect(mockWriteFile).toHaveBeenCalledWith(
expect.stringContaining(`my-project/package.json`),
expect.stringContaining('"record": "screenci record"')
expect.stringContaining('"@playwright/test": "^1.59.0"')
)
expect(mockWriteFile).toHaveBeenCalledWith(
expect.stringContaining(`my-project/tsconfig.json`),
@@ -1517,9 +1517,13 @@ describe('CLI', () => {
const pkg = JSON.parse(String(pkgCall?.[1])) as {
dependencies: Record<string, string>
devDependencies: Record<string, string>
scripts?: Record<string, string>
}
expect(pkg.dependencies['@playwright/test']).toBe('^1.59.0')
expect(pkg.devDependencies['@playwright/test']).toBeUndefined()
expect(pkg.scripts).toBeUndefined()
expect(pkgCall?.[1]).not.toContain('"test": "screenci test"')
expect(pkgCall?.[1]).not.toContain('"record": "screenci record"')
expect(pkgCall?.[1]).toContain('"@playwright/cli": "latest"')
})
@@ -1539,9 +1543,13 @@ describe('CLI', () => {
const pkg = JSON.parse(String(pkgCall?.[1])) as {
dependencies: Record<string, string>
devDependencies: Record<string, string>
scripts?: Record<string, string>
}
expect(pkg.dependencies['@playwright/test']).toBe('^1.59.0')
expect(pkg.devDependencies['@playwright/test']).toBeUndefined()
expect(pkg.scripts).toBeUndefined()
expect(pkgCall?.[1]).not.toContain('"test": "screenci test"')
expect(pkgCall?.[1]).not.toContain('"record": "screenci record"')
expect(pkgCall?.[1]).not.toContain('"@playwright/cli": "latest"')
})
@@ -1620,7 +1628,7 @@ describe('CLI', () => {
expect(workflowCall?.[1]).toContain(
'npx playwright install chromium --with-deps'
)
expect(workflowCall?.[1]).toContain('npm run record')
expect(workflowCall?.[1]).toContain('npx screenci record')
expect(workflowCall?.[1]).toContain(
'Copy it from https://app.screenci.com/secrets or ./.env, add it under Settings → Secrets and variables → Actions → Repository secrets, and then rerun this action.'
)
+1 -5
View File
@@ -1472,10 +1472,6 @@ function generatePackageJson(
JSON.stringify(
{
type: 'module',
scripts: {
record: 'screenci record',
test: 'screenci test',
},
dependencies: {
screenci: screenciDependency,
'@playwright/test': '^1.59.0',
@@ -1628,7 +1624,7 @@ jobs:
working-directory: ${workingDirectory}
env:
SCREENCI_SECRET: \${{ secrets.SCREENCI_SECRET }}
run: npm run record
run: npx screenci record
`
}
+4 -4
View File
@@ -31,7 +31,7 @@ Create a ScreenCI video that shows the onboarding flow.
Use the screenci skill.
Look at @src/routes/onboarding, @src/components/signup-form.tsx, and @screenci/videos/.
Start from the real UI in the source code, create or update a .video.ts file, add narration, and keep setup hidden.
Run npm run test until the video is ready, then run npm run record to get the final video output.
Run npx screenci test until the video is ready, then run npx screenci record to get the final video output.
```
This flow is usually faster and more reliable than browser-only exploration because the agent can inspect routes, labels, component names, and state logic directly from source.
@@ -65,7 +65,7 @@ Create a ScreenCI video for https://www.screenci.com/ that shows how to find the
First inspect the live site with playwright-cli. Figure out the cleanest visible path to the docs, including any cookie banner handling that should stay inside hide().
Then use the screenci skill to create a narrated video script in videos/ that starts on the requested page, explains what the user is doing, and uses visible clicks for navigation.
Run npm run test until the video is ready, then run npm run record to get the final video output.
Run npx screenci test until the video is ready, then run npx screenci record to get the final video output.
```
## Recommended setup
@@ -131,7 +131,7 @@ Use the screenci skill.
Inspect @src/routes/pricing.tsx and @src/components/pricing-selector.tsx.
Create or update a video in @screenci/videos/.
Explain the flow with narration, keep initial setup hidden, and use visible clicks after setup.
Run npm run test until the video is ready, then run npm run record to get the final video output.
Run npx screenci test until the video is ready, then run npx screenci record to get the final video output.
```
Example prompt for a deployed-site workflow:
@@ -141,7 +141,7 @@ Use playwright-cli to inspect https://www.screenci.com/ and create a ScreenCI vi
After inspection, use the screenci skill and write the final video in videos/find-docs.video.ts with clear narration.
Keep cookie handling and initial setup inside hide().
Use visible clicks for the demo. Run npm run test until the video is ready, then run npm run record to get the final video output.
Use visible clicks for the demo. Run npx screenci test until the video is ready, then run npx screenci record to get the final video output.
```
## Docs access for agents
+5 -7
View File
@@ -5,7 +5,7 @@ description: Understand the files created by screenci init and the normal workfl
# Create Videos
After `npx screenci@latest init`, ScreenCI gives you a small ready-to-edit project. This guide explains what each generated file is for and how to go from the starter example to your own final video.
After following [Getting Started](/guides/getting-started), ScreenCI gives you a small ready-to-edit project. This guide explains what each generated file is for and how to go from the starter example to your own final video.
## What init creates
@@ -24,10 +24,8 @@ screenci/
.github/workflows/screenci.yaml (optional)
```
## What each file does
- `screenci.config.ts` defines the ScreenCI project name, where video files live, which `.env` file to read, and default recording settings like aspect ratio, quality, and FPS. See the [configuration reference](/reference/configuration).
- `package.json` gives you the main scripts: `npm run test` runs `screenci test`, and `npm run record` runs `screenci record`.
- `package.json` declares the ScreenCI and Playwright dependencies used by the generated project.
- `tsconfig.json` enables strict TypeScript for your video scripts.
- `README.md` summarizes the normal workflow for the generated project.
- `.gitignore` keeps generated output, dependencies, and secrets out of git.
@@ -55,7 +53,7 @@ That workflow:
- can also be started manually with `workflow_dispatch`
- installs dependencies with `npm ci`
- installs Chromium for Playwright when needed
- runs `npm run record`
- runs `npx screenci record`
- uses `SCREENCI_SECRET` from GitHub Actions secrets so recordings can be uploaded from CI
This means the same final recording command works both locally and in CI.
@@ -80,7 +78,7 @@ For manual authoring, the usual pattern is:
Before recording, make sure the script works locally:
```bash
npm run test
npx screenci test
```
This runs the video script without the full recording pipeline, so it is the fastest way to confirm selectors, timing, and navigation.
@@ -90,7 +88,7 @@ This runs the video script without the full recording pipeline, so it is the fas
When the script looks correct, record the final result:
```bash
npm run record
npx screenci record
```
This is the same command used by the optional GitHub Actions workflow.
+2 -2
View File
@@ -46,7 +46,7 @@ Next, continue with [Create Videos](/guides/creating-videos) to understand the g
Inside the ScreenCI project directory, verify the starter video script works before recording:
```bash
npm run test
npx screenci test
```
This is similar to running `playwright test`: it executes the `.video.ts` script without recording, so you can quickly check that the video script works before recording.
@@ -56,7 +56,7 @@ This is similar to running `playwright test`: it executes the `.video.ts` script
Inside the ScreenCI project directory, record the final video when the script is working:
```bash
npm run record
npx screenci record
```
ScreenCI records the browser and sends the raw video to `app.screenci.com` for final rendering and optional deployment.
+1 -1
View File
@@ -30,5 +30,5 @@ npx --yes skills add screenci/screenci --skill screenci --skill playwright-cli -
After updating, verify your project still works:
```bash
npm run test
npx screenci test
```
+17 -2
View File
@@ -269,7 +269,7 @@ describe('defineConfig', () => {
}
})
it('preserves reporter config while recording', () => {
it('forces html reporter to never open while recording', () => {
process.env.SCREENCI_RECORDING = 'true'
try {
@@ -278,7 +278,22 @@ describe('defineConfig', () => {
reporter: 'html',
})
expect(config.reporter).toBe('html')
expect(config.reporter).toEqual([['html', { open: 'never' }]])
} finally {
delete process.env.SCREENCI_RECORDING
}
})
it('preserves non-html reporter config while recording', () => {
process.env.SCREENCI_RECORDING = 'true'
try {
const config = defineConfig({
projectName: 'Test',
reporter: 'list',
})
expect(config.reporter).toBe('list')
} finally {
delete process.env.SCREENCI_RECORDING
}
+29 -1
View File
@@ -45,6 +45,32 @@ import {
*/
export function defineConfig(config: ScreenCIConfig): ExtendedScreenCIConfig {
const isRecording = process.env.SCREENCI_RECORDING === 'true'
const normalizeReporter = (
reporter: NonNullable<ScreenCIConfig['reporter']>
): NonNullable<ScreenCIConfig['reporter']> => {
if (!isRecording) return reporter
// Keep the HTML report generated, but never auto-open it while recording.
if (reporter === 'html') {
return [['html', { open: 'never' }]]
}
if (Array.isArray(reporter)) {
return reporter.map((entry) => {
if (
Array.isArray(entry) &&
entry[0] === 'html' &&
(entry[1] === undefined || typeof entry[1] === 'object')
) {
return ['html', { ...(entry[1] ?? {}), open: 'never' }]
}
return entry
}) as NonNullable<ScreenCIConfig['reporter']>
}
return reporter
}
// Runtime check for viewport (check before testDir since test objects may not have testDir defined)
if (config.use && 'viewport' in config.use) {
@@ -98,6 +124,8 @@ export function defineConfig(config: ScreenCIConfig): ExtendedScreenCIConfig {
}
const { videoDir, record, ...rest } = config
const reporter =
rest.reporter !== undefined ? normalizeReporter(rest.reporter) : undefined
// recording does not need tracing, also it takes resources so that is why forced off
const trace = isRecording ? 'off' : rest.use?.trace
@@ -126,7 +154,7 @@ export function defineConfig(config: ScreenCIConfig): ExtendedScreenCIConfig {
record: {
upload: record?.upload ?? DEFAULT_RECORD_UPLOAD_POLICY,
},
...(rest.reporter !== undefined ? { reporter: rest.reporter } : {}),
...(reporter !== undefined ? { reporter } : {}),
use,
...(projects ? { projects } : {}),
timeout: rest.timeout ?? DEFAULT_TIMEOUT,