screenci 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +21 -0
- package/README.md +77 -195
- package/dist/cli.d.ts +22 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +640 -767
- package/dist/cli.js.map +1 -1
- package/dist/docs/manifest.d.ts +529 -0
- package/dist/docs/manifest.d.ts.map +1 -0
- package/dist/docs/manifest.js +243 -0
- package/dist/docs/manifest.js.map +1 -0
- package/dist/docs/video-sources/assets-and-overlays.video.d.ts +2 -0
- package/dist/docs/video-sources/assets-and-overlays.video.d.ts.map +1 -0
- package/dist/docs/video-sources/assets-and-overlays.video.js +40 -0
- package/dist/docs/video-sources/assets-and-overlays.video.js.map +1 -0
- package/dist/docs/video-sources/camera-and-zooming.video.d.ts +2 -0
- package/dist/docs/video-sources/camera-and-zooming.video.d.ts.map +1 -0
- package/dist/docs/video-sources/camera-and-zooming.video.js +37 -0
- package/dist/docs/video-sources/camera-and-zooming.video.js.map +1 -0
- package/dist/docs/video-sources/ci-setup.video.d.ts +2 -0
- package/dist/docs/video-sources/ci-setup.video.d.ts.map +1 -0
- package/dist/docs/video-sources/ci-setup.video.js +37 -0
- package/dist/docs/video-sources/ci-setup.video.js.map +1 -0
- package/dist/docs/video-sources/cli.video.d.ts +2 -0
- package/dist/docs/video-sources/cli.video.d.ts.map +1 -0
- package/dist/docs/video-sources/cli.video.js +37 -0
- package/dist/docs/video-sources/cli.video.js.map +1 -0
- package/dist/docs/video-sources/docs-shared.d.ts +5 -0
- package/dist/docs/video-sources/docs-shared.d.ts.map +1 -0
- package/dist/docs/video-sources/docs-shared.js +14 -0
- package/dist/docs/video-sources/docs-shared.js.map +1 -0
- package/dist/docs/video-sources/generating-videos.video.d.ts +2 -0
- package/dist/docs/video-sources/generating-videos.video.d.ts.map +1 -0
- package/dist/docs/video-sources/generating-videos.video.js +37 -0
- package/dist/docs/video-sources/generating-videos.video.js.map +1 -0
- package/dist/docs/video-sources/installation.video.d.ts +2 -0
- package/dist/docs/video-sources/installation.video.d.ts.map +1 -0
- package/dist/docs/video-sources/installation.video.js +24 -0
- package/dist/docs/video-sources/installation.video.js.map +1 -0
- package/dist/docs/video-sources/narration-and-localization.video.d.ts +2 -0
- package/dist/docs/video-sources/narration-and-localization.video.d.ts.map +1 -0
- package/dist/docs/video-sources/narration-and-localization.video.js +40 -0
- package/dist/docs/video-sources/narration-and-localization.video.js.map +1 -0
- package/dist/docs/video-sources/public-urls-and-embeds.video.d.ts +2 -0
- package/dist/docs/video-sources/public-urls-and-embeds.video.d.ts.map +1 -0
- package/dist/docs/video-sources/public-urls-and-embeds.video.js +37 -0
- package/dist/docs/video-sources/public-urls-and-embeds.video.js.map +1 -0
- package/dist/docs/video-sources/record-and-publish.video.d.ts +2 -0
- package/dist/docs/video-sources/record-and-publish.video.d.ts.map +1 -0
- package/dist/docs/video-sources/record-and-publish.video.js +37 -0
- package/dist/docs/video-sources/record-and-publish.video.js.map +1 -0
- package/dist/docs/video-sources/run-and-debug-videos.video.d.ts +2 -0
- package/dist/docs/video-sources/run-and-debug-videos.video.d.ts.map +1 -0
- package/dist/docs/video-sources/run-and-debug-videos.video.js +37 -0
- package/dist/docs/video-sources/run-and-debug-videos.video.js.map +1 -0
- package/dist/docs/video-sources/write-video-scripts.video.d.ts +2 -0
- package/dist/docs/video-sources/write-video-scripts.video.d.ts.map +1 -0
- package/dist/docs/video-sources/write-video-scripts.video.js +40 -0
- package/dist/docs/video-sources/write-video-scripts.video.js.map +1 -0
- package/dist/docs/videos.d.ts +94 -0
- package/dist/docs/videos.d.ts.map +1 -0
- package/dist/docs/videos.js +54 -0
- package/dist/docs/videos.js.map +1 -0
- package/dist/index.d.ts +4 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/src/asset.d.ts +10 -9
- package/dist/src/asset.d.ts.map +1 -1
- package/dist/src/asset.js +7 -13
- package/dist/src/asset.js.map +1 -1
- package/dist/src/autoZoom.d.ts +3 -33
- package/dist/src/autoZoom.d.ts.map +1 -1
- package/dist/src/autoZoom.js +46 -51
- package/dist/src/autoZoom.js.map +1 -1
- package/dist/src/changeFocus.d.ts.map +1 -1
- package/dist/src/changeFocus.js +3 -2
- package/dist/src/changeFocus.js.map +1 -1
- package/dist/src/config.d.ts +5 -7
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +44 -71
- package/dist/src/config.js.map +1 -1
- package/dist/src/cue.d.ts +13 -26
- package/dist/src/cue.d.ts.map +1 -1
- package/dist/src/cue.js +61 -97
- package/dist/src/cue.js.map +1 -1
- package/dist/src/customVoiceRef.d.ts +3 -0
- package/dist/src/customVoiceRef.d.ts.map +1 -0
- package/dist/src/customVoiceRef.js +7 -0
- package/dist/src/customVoiceRef.js.map +1 -0
- package/dist/src/defaults.d.ts +5 -5
- package/dist/src/defaults.d.ts.map +1 -1
- package/dist/src/defaults.js +13 -7
- package/dist/src/defaults.js.map +1 -1
- package/dist/src/events.d.ts +7 -6
- package/dist/src/events.d.ts.map +1 -1
- package/dist/src/events.js +17 -0
- package/dist/src/events.js.map +1 -1
- package/dist/src/fileSystemName.d.ts +2 -0
- package/dist/src/fileSystemName.d.ts.map +1 -0
- package/dist/src/fileSystemName.js +44 -0
- package/dist/src/fileSystemName.js.map +1 -0
- package/dist/src/hide.d.ts +1 -1
- package/dist/src/hide.d.ts.map +1 -1
- package/dist/src/hide.js +12 -15
- package/dist/src/hide.js.map +1 -1
- package/dist/src/init.d.ts +12 -0
- package/dist/src/init.d.ts.map +1 -0
- package/dist/src/init.js +674 -0
- package/dist/src/init.js.map +1 -0
- package/dist/src/instrument.d.ts +1 -0
- package/dist/src/instrument.d.ts.map +1 -1
- package/dist/src/instrument.js +29 -10
- package/dist/src/instrument.js.map +1 -1
- package/dist/src/manualZoom.d.ts.map +1 -1
- package/dist/src/manualZoom.js +13 -13
- package/dist/src/manualZoom.js.map +1 -1
- package/dist/src/mouse.d.ts.map +1 -1
- package/dist/src/mouse.js +4 -1
- package/dist/src/mouse.js.map +1 -1
- package/dist/src/recording.d.ts +2 -2
- package/dist/src/recording.d.ts.map +1 -1
- package/dist/src/runtimeContext.d.ts +81 -0
- package/dist/src/runtimeContext.d.ts.map +1 -0
- package/dist/src/runtimeContext.js +95 -0
- package/dist/src/runtimeContext.js.map +1 -0
- package/dist/src/runtimeMode.d.ts +8 -0
- package/dist/src/runtimeMode.d.ts.map +1 -0
- package/dist/src/runtimeMode.js +22 -0
- package/dist/src/runtimeMode.js.map +1 -0
- package/dist/src/titleValidation.d.ts +3 -0
- package/dist/src/titleValidation.d.ts.map +1 -0
- package/dist/src/titleValidation.js +19 -0
- package/dist/src/titleValidation.js.map +1 -0
- package/dist/src/types.d.ts +42 -15
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/video.d.ts +6 -1
- package/dist/src/video.d.ts.map +1 -1
- package/dist/src/video.js +94 -46
- package/dist/src/video.js.map +1 -1
- package/dist/src/voices.d.ts +8 -11
- package/dist/src/voices.d.ts.map +1 -1
- package/dist/src/voices.js +13 -8
- package/dist/src/voices.js.map +1 -1
- package/dist/src/zoom.d.ts +1 -1
- package/dist/src/zoom.d.ts.map +1 -1
- package/dist/test-fixtures/record-all-or-nothing.config.d.ts +8 -0
- package/dist/test-fixtures/record-all-or-nothing.config.d.ts.map +1 -0
- package/dist/test-fixtures/record-all-or-nothing.config.js +7 -0
- package/dist/test-fixtures/record-all-or-nothing.config.js.map +1 -0
- package/dist/test-fixtures/record-upload-all-or-nothing.config.d.ts +8 -0
- package/dist/test-fixtures/record-upload-all-or-nothing.config.d.ts.map +1 -0
- package/dist/test-fixtures/record-upload-all-or-nothing.config.js +7 -0
- package/dist/test-fixtures/record-upload-all-or-nothing.config.js.map +1 -0
- package/dist/test-fixtures/record-upload.config.d.ts +5 -0
- package/dist/test-fixtures/record-upload.config.d.ts.map +1 -0
- package/dist/test-fixtures/record-upload.config.js +4 -0
- package/dist/test-fixtures/record-upload.config.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -2
- package/skills/screenci/SKILL.md +6 -1
- package/skills/screenci/references/init.md +10 -12
- package/dist/src/reporter.d.ts +0 -9
- package/dist/src/reporter.d.ts.map +0 -1
- package/dist/src/reporter.js +0 -50
- package/dist/src/reporter.js.map +0 -1
- package/dist/src/sanitize.d.ts +0 -5
- package/dist/src/sanitize.d.ts.map +0 -1
- package/dist/src/sanitize.js +0 -11
- package/dist/src/sanitize.js.map +0 -1
package/LICENCE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ScreenCI Ltd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,94 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
Your UI changed. Your demo videos didn't. screenci fixes that.
|
|
4
4
|
|
|
5
|
-
Record product walkthroughs as code. When the UI ships, run
|
|
5
|
+
Record product walkthroughs as code. When the UI ships, run
|
|
6
|
+
`npx screenci record` and your videos regenerate.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
ScreenCI keeps the Playwright mental model, but the output is a maintainable
|
|
9
|
+
product video instead of a test report.
|
|
10
|
+
|
|
11
|
+
## Install and scaffold
|
|
8
12
|
|
|
9
13
|
```bash
|
|
10
|
-
npm
|
|
14
|
+
npm init screenci@latest
|
|
15
|
+
pnpm create screenci
|
|
11
16
|
```
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
`init` creates a ready-to-run project in the current directory, installs
|
|
19
|
+
dependencies, and installs Chromium by default. When using `npm init`, pass
|
|
20
|
+
extra initializer flags after `--`, for example
|
|
21
|
+
`npm init screenci@latest -- --yes --package-manager pnpm`.
|
|
14
22
|
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
```text
|
|
24
|
+
screenci.config.ts
|
|
25
|
+
package.json
|
|
26
|
+
tsconfig.json
|
|
27
|
+
README.md
|
|
28
|
+
.gitignore
|
|
29
|
+
.env
|
|
30
|
+
videos/
|
|
31
|
+
example.video.ts
|
|
32
|
+
.github/workflows/screenci.yaml
|
|
19
33
|
```
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
Docs:
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
screenci/
|
|
25
|
-
|
|
26
|
-
videos/
|
|
27
|
-
example.video.ts ← your first video script
|
|
28
|
-
package.json
|
|
29
|
-
.gitignore
|
|
30
|
-
```
|
|
37
|
+
- Getting started: `https://screenci.com/docs`
|
|
38
|
+
- Writing scripts: `https://screenci.com/docs/write-video-scripts`
|
|
39
|
+
- CLI reference: `https://screenci.com/docs/reference/cli`
|
|
31
40
|
|
|
32
41
|
## Write a video
|
|
33
42
|
|
|
34
|
-
Video scripts are Playwright
|
|
43
|
+
Video scripts are Playwright-style files with a `.video.ts` extension. If you
|
|
44
|
+
already know Playwright locators, navigation, and waiting, you already know
|
|
45
|
+
most of the automation layer.
|
|
35
46
|
|
|
36
47
|
```ts
|
|
37
48
|
// videos/onboarding.video.ts
|
|
38
|
-
import { video } from 'screenci'
|
|
49
|
+
import { hide, video } from 'screenci'
|
|
39
50
|
|
|
40
51
|
video('Onboarding flow', async ({ page }) => {
|
|
41
|
-
await
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
await hide(async () => {
|
|
53
|
+
await page.goto('https://app.example.com/signup')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
await page.getByLabel('Email').fill('jane@example.com')
|
|
57
|
+
await page.getByRole('button', { name: 'Create account' }).click()
|
|
58
|
+
await page.getByRole('heading', { name: 'Dashboard' }).waitFor()
|
|
45
59
|
})
|
|
46
60
|
```
|
|
47
61
|
|
|
48
|
-
Each `video()` call
|
|
49
|
-
|
|
50
|
-
> **Full reference:** [Writing Video Tests](http://localhost:4321/reference/video-tests)
|
|
51
|
-
|
|
52
|
-
### `ScreenCIPage` — animated interactions
|
|
53
|
-
|
|
54
|
-
Inside `video()`, `page` is a `ScreenCIPage` — a Playwright `Page` with animated cursor and typing. You don't need to change anything; the animations happen automatically:
|
|
62
|
+
Each `video()` call becomes one output video. The title becomes the filename
|
|
63
|
+
and the remote video identity.
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
| `fill()` | Character-by-character typing |
|
|
60
|
-
| `hover()` | Animated cursor move |
|
|
61
|
-
| `dragTo()` | Animated move → mouseDown → drag → mouseUp |
|
|
62
|
-
| `page.mouse` | Smooth bezier moves instead of instant teleport |
|
|
63
|
-
| Everything else | Standard Playwright — unchanged |
|
|
65
|
+
Inside `video()`, `page` is a `ScreenCIPage`: a Playwright `Page` with animated
|
|
66
|
+
cursor movement and visible typing layered on top of normal Playwright
|
|
67
|
+
behavior.
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`fill()` already moves to the field, clicks it, and types, so you do not need a separate `click()` first:
|
|
68
|
-
|
|
69
|
-
```ts
|
|
70
|
-
const searchBox = page.getByPlaceholder('Search')
|
|
71
|
-
|
|
72
|
-
await searchBox.fill('Item 1')
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Run it
|
|
69
|
+
## Run locally
|
|
76
70
|
|
|
77
71
|
```bash
|
|
78
|
-
|
|
72
|
+
npx screenci test
|
|
79
73
|
npx screenci test --ui
|
|
80
|
-
|
|
81
|
-
# Record: captures the screen and writes .screenci/<name>/recording.mp4
|
|
82
|
-
npx screenci record
|
|
83
74
|
```
|
|
84
75
|
|
|
85
|
-
|
|
76
|
+
Use `test` for the normal authoring loop. It runs the video scripts through
|
|
77
|
+
Playwright without starting the final recording and upload path.
|
|
78
|
+
|
|
79
|
+
## Record the final output
|
|
86
80
|
|
|
87
81
|
```bash
|
|
88
|
-
|
|
89
|
-
npm run record # → npx screenci record
|
|
82
|
+
npx screenci record
|
|
90
83
|
```
|
|
91
84
|
|
|
92
|
-
|
|
85
|
+
`record` writes local artifacts into `.screenci/<video-name>/` and uploads them
|
|
86
|
+
when `SCREENCI_SECRET` is configured.
|
|
93
87
|
|
|
94
88
|
## Configure
|
|
95
89
|
|
|
@@ -99,159 +93,47 @@ import { defineConfig } from 'screenci'
|
|
|
99
93
|
|
|
100
94
|
export default defineConfig({
|
|
101
95
|
projectName: 'my-project',
|
|
96
|
+
envFile: '.env',
|
|
102
97
|
videoDir: './videos',
|
|
103
98
|
use: {
|
|
104
99
|
baseURL: 'https://app.example.com',
|
|
105
100
|
recordOptions: {
|
|
106
|
-
aspectRatio: '16:9',
|
|
107
|
-
quality: '1080p',
|
|
108
|
-
fps:
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
})
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
screenci enforces `workers: 1`, `retries: 0`, and `fullyParallel: false` so each generated video has one deterministic timeline. Don't fight it.
|
|
115
|
-
|
|
116
|
-
## AI narration
|
|
117
|
-
|
|
118
|
-
`createNarration()` maps keys to narration text (or audio files). Define it once near the top of the file, then call `await narration.key()` for the common case where the full line should run before moving on. Use `await narration.key.start()` when narration should overlap with the next actions, and `await narration.key.end()` only to close that same active cue later.
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
import { video, createNarration, voices } from 'screenci'
|
|
122
|
-
|
|
123
|
-
const narration = createNarration({
|
|
124
|
-
voice: { name: voices.Aria },
|
|
125
|
-
languages: {
|
|
126
|
-
en: {
|
|
127
|
-
cues: {
|
|
128
|
-
intro: 'Welcome to the dashboard.',
|
|
129
|
-
addButton: 'Click here to create a new project.',
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
video('Dashboard walkthrough', async ({ page }) => {
|
|
136
|
-
await page.goto('/dashboard')
|
|
137
|
-
|
|
138
|
-
await narration.intro()
|
|
139
|
-
await page.locator('#reports').click()
|
|
140
|
-
|
|
141
|
-
await narration.addButton()
|
|
142
|
-
await page.locator('#new-project').click()
|
|
143
|
-
})
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Use this pattern:
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
const narration = createNarration({ ... })
|
|
150
|
-
|
|
151
|
-
video('Example', async ({ page }) => {
|
|
152
|
-
await narration.intro.start() // starts narration now
|
|
153
|
-
await page.click('#filters') // runs while intro audio is still playing
|
|
154
|
-
|
|
155
|
-
await narration.details.start() // auto-ends intro, then starts details
|
|
156
|
-
await narration.details.end() // use this before navigation or the next gated action
|
|
157
|
-
await page.click('#confirm')
|
|
158
|
-
})
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Multi-language (type-safe)
|
|
162
|
-
|
|
163
|
-
TypeScript enforces that every language has the same keys. Missing a translation is a compile error.
|
|
164
|
-
|
|
165
|
-
```ts
|
|
166
|
-
import { createNarration, voices } from 'screenci'
|
|
167
|
-
|
|
168
|
-
const narration = createNarration({
|
|
169
|
-
voice: { name: voices.Ava },
|
|
170
|
-
languages: {
|
|
171
|
-
en: {
|
|
172
|
-
cues: {
|
|
173
|
-
intro: 'Welcome to the dashboard.',
|
|
174
|
-
addButton: 'Click here to create a new project.',
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
fi: {
|
|
178
|
-
voice: { name: voices.Nora },
|
|
179
|
-
cues: {
|
|
180
|
-
intro: 'Tervetuloa hallintapaneeliin.',
|
|
181
|
-
addButton: 'Klikkaa tästä luodaksesi uuden projektin.',
|
|
182
|
-
},
|
|
101
|
+
aspectRatio: '16:9',
|
|
102
|
+
quality: '1080p',
|
|
103
|
+
fps: 60,
|
|
183
104
|
},
|
|
105
|
+
trace: 'retain-on-failure',
|
|
184
106
|
},
|
|
107
|
+
projects: [{ name: 'chromium' }],
|
|
185
108
|
})
|
|
186
109
|
```
|
|
187
110
|
|
|
188
|
-
|
|
111
|
+
ScreenCI manages `testDir`, `testMatch`, and `retries` for you. Most other
|
|
112
|
+
Playwright config still passes through.
|
|
189
113
|
|
|
190
|
-
|
|
114
|
+
## Authoring helpers
|
|
191
115
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
video
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
// video starts here — dashboard is already open
|
|
206
|
-
await page.locator('#reports').click()
|
|
207
|
-
})
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Zoom the camera
|
|
211
|
-
|
|
212
|
-
`autoZoom()` follows interactions with a smooth camera pan. Wrap a form or a page section, not individual clicks.
|
|
213
|
-
|
|
214
|
-
```ts
|
|
215
|
-
import { video, autoZoom } from 'screenci'
|
|
216
|
-
|
|
217
|
-
video('Profile settings', async ({ page }) => {
|
|
218
|
-
await page.goto('/settings/profile')
|
|
219
|
-
|
|
220
|
-
await autoZoom(
|
|
221
|
-
async () => {
|
|
222
|
-
await page.locator('#name').fill('Jane Doe')
|
|
223
|
-
await page.locator('#bio').fill('Engineer')
|
|
224
|
-
await page.locator('button[type="submit"]').click()
|
|
225
|
-
},
|
|
226
|
-
{ duration: 400, amount: 0.4, easing: 'ease-in-out' }
|
|
227
|
-
)
|
|
228
|
-
})
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
## API
|
|
232
|
-
|
|
233
|
-
| Export | What it does |
|
|
234
|
-
| ----------------- | ------------------------------------------------------------------ |
|
|
235
|
-
| `defineConfig` | Wraps Playwright config with screenci defaults |
|
|
236
|
-
| `video` | Declares a video recording test |
|
|
237
|
-
| `createNarration` | Creates typed narration controllers with AI-generated audio |
|
|
238
|
-
| `hide` | Cuts a section from the final video |
|
|
239
|
-
| `autoZoom` | Smooth camera pan that follows interactions |
|
|
240
|
-
| `voices` | Available voice constants (`voices.Ava`, `voices.elevenlabs(...)`) |
|
|
241
|
-
|
|
242
|
-
The `page` fixture inside `video()` is a `ScreenCIPage` — a Playwright `Page` with animated cursor support wired in on all locator methods.
|
|
116
|
+
| Export | What it does |
|
|
117
|
+
| ----------------- | -------------------------------------------------------- |
|
|
118
|
+
| `defineConfig` | Wraps Playwright config with ScreenCI defaults |
|
|
119
|
+
| `video` | Declares a video recording test |
|
|
120
|
+
| `createNarration` | Creates typed narration controllers |
|
|
121
|
+
| `hide` | Cuts setup or cleanup out of the visible recording |
|
|
122
|
+
| `autoZoom` | Smooth camera follow for an interaction block |
|
|
123
|
+
| `zoomTo` | Manual camera framing for a locator or point |
|
|
124
|
+
| `resetZoom` | Returns from manual framing to the full viewport |
|
|
125
|
+
| `createAssets` | Inserts timed media overlays into the recording timeline |
|
|
126
|
+
| `voices` | Available voice constants such as `voices.Ava` |
|
|
127
|
+
| `languageRegions` | Region constants such as `languageRegions.en.US` |
|
|
243
128
|
|
|
244
129
|
## Output
|
|
245
130
|
|
|
246
|
-
```
|
|
131
|
+
```text
|
|
247
132
|
.screenci/
|
|
248
133
|
<video-name>/
|
|
249
|
-
recording.mp4
|
|
250
|
-
data.json
|
|
134
|
+
recording.mp4
|
|
135
|
+
data.json
|
|
251
136
|
```
|
|
252
137
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
npm run retry
|
|
257
|
-
```
|
|
138
|
+
When `SCREENCI_SECRET` is configured, `screenci record` uploads the output to
|
|
139
|
+
ScreenCI for rendering, narration generation, and hosted delivery.
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { RecordingCustomVoiceRef, RecordingData } from './src/events.js';
|
|
2
2
|
import type { VoiceKey } from './src/voices.js';
|
|
3
|
+
import type { RecordUploadPolicy } from './src/types.js';
|
|
4
|
+
type PlaywrightListReportSuite = {
|
|
5
|
+
title?: string;
|
|
6
|
+
specs?: Array<{
|
|
7
|
+
title: string;
|
|
8
|
+
}>;
|
|
9
|
+
suites?: PlaywrightListReportSuite[];
|
|
10
|
+
};
|
|
11
|
+
export declare function collectPlaywrightListTitles(suites: readonly PlaywrightListReportSuite[]): string[];
|
|
3
12
|
type PreparedUploadAsset = {
|
|
4
13
|
fileHash: string;
|
|
5
14
|
path: string;
|
|
@@ -12,12 +21,24 @@ export declare function attachUploadAbortStdinListener(input: Pick<NodeJS.ReadSt
|
|
|
12
21
|
export declare function stripVoicePath(voice: VoiceKey | RecordingCustomVoiceRef): VoiceKey | RecordingCustomVoiceRef;
|
|
13
22
|
export declare function annotateRecordingDataWithAssetHashes(data: RecordingData, assets: PreparedUploadAsset[]): RecordingData;
|
|
14
23
|
export declare function formatUploadStartFailureMessage(videoName: string, status: number, responseText: string, secret: string): string;
|
|
24
|
+
export declare function formatFailedVideoMessage(videoName: string, message: string): string;
|
|
15
25
|
export declare function printUploadStartFailureMessage(videoName: string, status: number, responseText: string, secret: string): void;
|
|
26
|
+
export declare function uploadRecordings(screenciDir: string, projectName: string, apiUrl: string, secret: string, specificEntry?: string, verbose?: boolean): Promise<{
|
|
27
|
+
projectId: string | null;
|
|
28
|
+
hadFailures: boolean;
|
|
29
|
+
failedVideoNames: string[];
|
|
30
|
+
failedVideoMessages: Array<{
|
|
31
|
+
videoName: string;
|
|
32
|
+
message: string;
|
|
33
|
+
}>;
|
|
34
|
+
}>;
|
|
16
35
|
export declare function getDevBackendUrl(): string;
|
|
17
36
|
export declare function getDevFrontendUrl(): string;
|
|
18
37
|
export declare function extractConfigStringLiteral(configSource: string, property: 'projectName' | 'envFile'): string | undefined;
|
|
38
|
+
export declare function extractRecordUploadPolicyLiteral(configSource: string): RecordUploadPolicy | undefined;
|
|
39
|
+
export declare function extractMockRecordLiteral(configSource: string): boolean | undefined;
|
|
19
40
|
export declare function getConfigModuleSpecifier(resolvedConfigPath: string): string;
|
|
20
|
-
export declare function ensureScreenciSecret(): Promise<string | undefined>;
|
|
41
|
+
export declare function ensureScreenciSecret(resolvedConfigPath?: string): Promise<string | undefined>;
|
|
21
42
|
export declare function main(): Promise<void>;
|
|
22
43
|
export {};
|
|
23
44
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
|