screenci 0.0.4 → 0.0.5

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.
Files changed (94) hide show
  1. package/README.md +227 -0
  2. package/cli.ts +1111 -0
  3. package/dist/cli.d.ts +4 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +896 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/e2e/instrument.e2e.d.ts +2 -0
  8. package/dist/e2e/instrument.e2e.d.ts.map +1 -0
  9. package/dist/e2e/instrument.e2e.js +661 -0
  10. package/dist/e2e/instrument.e2e.js.map +1 -0
  11. package/dist/index.d.ts +18 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +15 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/playwright.config.d.ts +3 -0
  16. package/dist/playwright.config.d.ts.map +1 -0
  17. package/dist/playwright.config.js +21 -0
  18. package/dist/playwright.config.js.map +1 -0
  19. package/dist/reporter.d.ts +9 -0
  20. package/dist/reporter.d.ts.map +1 -0
  21. package/dist/reporter.js +49 -0
  22. package/dist/reporter.js.map +1 -0
  23. package/dist/src/asset.d.ts +90 -0
  24. package/dist/src/asset.d.ts.map +1 -0
  25. package/dist/src/asset.js +74 -0
  26. package/dist/src/asset.js.map +1 -0
  27. package/dist/src/autoZoom.d.ts +40 -0
  28. package/dist/src/autoZoom.d.ts.map +1 -0
  29. package/dist/src/autoZoom.js +88 -0
  30. package/dist/src/autoZoom.js.map +1 -0
  31. package/dist/src/caption.d.ts +152 -0
  32. package/dist/src/caption.d.ts.map +1 -0
  33. package/dist/src/caption.js +240 -0
  34. package/dist/src/caption.js.map +1 -0
  35. package/dist/src/caption.test-d.d.ts +2 -0
  36. package/dist/src/caption.test-d.d.ts.map +1 -0
  37. package/dist/src/caption.test-d.js +50 -0
  38. package/dist/src/caption.test-d.js.map +1 -0
  39. package/dist/src/config.d.ts +42 -0
  40. package/dist/src/config.d.ts.map +1 -0
  41. package/dist/src/config.js +147 -0
  42. package/dist/src/config.js.map +1 -0
  43. package/dist/src/defaults.d.ts +63 -0
  44. package/dist/src/defaults.d.ts.map +1 -0
  45. package/dist/src/defaults.js +66 -0
  46. package/dist/src/defaults.js.map +1 -0
  47. package/dist/src/dimensions.d.ts +29 -0
  48. package/dist/src/dimensions.d.ts.map +1 -0
  49. package/dist/src/dimensions.js +47 -0
  50. package/dist/src/dimensions.js.map +1 -0
  51. package/dist/src/events.d.ts +203 -0
  52. package/dist/src/events.d.ts.map +1 -0
  53. package/dist/src/events.js +227 -0
  54. package/dist/src/events.js.map +1 -0
  55. package/dist/src/hide.d.ts +27 -0
  56. package/dist/src/hide.d.ts.map +1 -0
  57. package/dist/src/hide.js +49 -0
  58. package/dist/src/hide.js.map +1 -0
  59. package/dist/src/instrument.d.ts +15 -0
  60. package/dist/src/instrument.d.ts.map +1 -0
  61. package/dist/src/instrument.js +910 -0
  62. package/dist/src/instrument.js.map +1 -0
  63. package/dist/src/logger.d.ts +7 -0
  64. package/dist/src/logger.d.ts.map +1 -0
  65. package/dist/src/logger.js +13 -0
  66. package/dist/src/logger.js.map +1 -0
  67. package/dist/src/reporter.d.ts +9 -0
  68. package/dist/src/reporter.d.ts.map +1 -0
  69. package/dist/src/reporter.js +50 -0
  70. package/dist/src/reporter.js.map +1 -0
  71. package/dist/src/sanitize.d.ts +5 -0
  72. package/dist/src/sanitize.d.ts.map +1 -0
  73. package/dist/src/sanitize.js +11 -0
  74. package/dist/src/sanitize.js.map +1 -0
  75. package/dist/src/types.d.ts +544 -0
  76. package/dist/src/types.d.ts.map +1 -0
  77. package/dist/src/types.js +2 -0
  78. package/dist/src/types.js.map +1 -0
  79. package/dist/src/video.d.ts +138 -0
  80. package/dist/src/video.d.ts.map +1 -0
  81. package/dist/src/video.js +415 -0
  82. package/dist/src/video.js.map +1 -0
  83. package/dist/src/voices.d.ts +60 -0
  84. package/dist/src/voices.d.ts.map +1 -0
  85. package/dist/src/voices.js +42 -0
  86. package/dist/src/voices.js.map +1 -0
  87. package/dist/src/xvfb.d.ts +22 -0
  88. package/dist/src/xvfb.d.ts.map +1 -0
  89. package/dist/src/xvfb.js +87 -0
  90. package/dist/src/xvfb.js.map +1 -0
  91. package/dist/tsconfig.tsbuildinfo +1 -0
  92. package/package.json +45 -4
  93. package/bin/index.js +0 -3
  94. package/index.js +0 -1
package/README.md ADDED
@@ -0,0 +1,227 @@
1
+ # screenci
2
+
3
+ Your UI changed. Your demo videos didn't. screenci fixes that.
4
+
5
+ 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.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install screenci
11
+ ```
12
+
13
+ ## Init a new project
14
+
15
+ ```bash
16
+ npx screenci init my-project
17
+ cd my-project
18
+ npm install
19
+ ```
20
+
21
+ This scaffolds a ready-to-run project:
22
+
23
+ ```
24
+ my-project/
25
+ screenci.config.ts ← video settings
26
+ videos/
27
+ example.video.ts ← your first video script
28
+ Dockerfile ← container image for CI recording
29
+ package.json
30
+ .gitignore
31
+ ```
32
+
33
+ ## Write a video
34
+
35
+ Video scripts are Playwright test files with a `.video.ts` extension. If you already know Playwright, you already know 90% of this.
36
+
37
+ ```ts
38
+ // videos/onboarding.video.ts
39
+ import { video } from 'screenci'
40
+
41
+ video('Onboarding flow', async ({ page }) => {
42
+ await page.goto('https://app.example.com/signup')
43
+ await page.fill('input[name="email"]', 'jane@example.com')
44
+ await page.click('button[type="submit"]')
45
+ await page.waitForURL('**/dashboard')
46
+ })
47
+ ```
48
+
49
+ Each `video()` call → one `.mp4`. The title becomes the filename.
50
+
51
+ ## Run it
52
+
53
+ ```bash
54
+ # Dry-run: opens Playwright UI so you can see what you're recording
55
+ npm run dev
56
+
57
+ # Record: actually captures the screen
58
+ cd my-project && npm run record
59
+ ```
60
+
61
+ Recordings land in `.screenci/<video-name>/recording.mp4` alongside a `data.json` with all the interaction events.
62
+
63
+ ## Configure
64
+
65
+ ```ts
66
+ // screenci.config.ts
67
+ import { defineConfig } from 'screenci'
68
+
69
+ export default defineConfig({
70
+ projectName: 'my-project',
71
+ videoDir: './videos',
72
+ use: {
73
+ baseURL: 'https://app.example.com',
74
+ recordOptions: {
75
+ aspectRatio: '16:9', // '16:9' | '9:16' | '1:1' | '4:3' | ...
76
+ quality: '1080p', // '720p' | '1080p' | '1440p' | '2160p'
77
+ fps: 30, // 24 | 30 | 60
78
+ },
79
+ },
80
+ })
81
+ ```
82
+
83
+ screenci enforces `workers: 1`, `retries: 0`, and `fullyParallel: false` — FFmpeg records one screen at a time. Don't fight it.
84
+
85
+ ## Captions & AI voiceovers
86
+
87
+ `createCaptions()` maps caption keys to text. At render time screenci sends the text through ElevenLabs and lines up the audio with your recording.
88
+
89
+ ```ts
90
+ import { video, createCaptions } from 'screenci'
91
+
92
+ const captions = createCaptions({
93
+ intro: 'Welcome to the dashboard.',
94
+ addButton: 'Click here to create a new project.',
95
+ })
96
+
97
+ video('Dashboard walkthrough', async ({ page }) => {
98
+ await page.goto('/dashboard')
99
+
100
+ await captions.intro.start()
101
+ // ...anything you do here plays over the voiceover...
102
+ await captions.intro.end()
103
+
104
+ await page.locator('#new-project').click()
105
+ await captions.addButton.start()
106
+ await captions.addButton.end()
107
+ })
108
+ ```
109
+
110
+ ### With a voice
111
+
112
+ ```ts
113
+ import { createCaptions, voices } from 'screenci'
114
+
115
+ const captions = createCaptions(
116
+ { voice: voices.en.Jude },
117
+ {
118
+ intro: 'Welcome to the dashboard.',
119
+ addButton: 'Click here to create a new project.',
120
+ }
121
+ )
122
+ ```
123
+
124
+ ### Multi-language (type-safe)
125
+
126
+ TypeScript will yell at you if any language is missing a key. That's a feature.
127
+
128
+ ```ts
129
+ import { createCaptions, voices } from 'screenci'
130
+
131
+ const captions = createCaptions({
132
+ en: {
133
+ voice: voices.en.Jude,
134
+ captions: {
135
+ intro: 'Welcome to the dashboard.',
136
+ addButton: 'Click here to create a new project.',
137
+ },
138
+ },
139
+ fi: {
140
+ voice: voices.fi.Martti,
141
+ captions: {
142
+ intro: 'Tervetuloa hallintapaneeliin.',
143
+ addButton: 'Klikkaa tästä luodaksesi uuden projektin.',
144
+ },
145
+ },
146
+ })
147
+ ```
148
+
149
+ ### Sync actions to audio
150
+
151
+ ```ts
152
+ // Wait until the voiceover is 60% done, then perform the action
153
+ await captions.intro.waitUntil('60%')
154
+ await page.locator('#cta').click()
155
+ await captions.intro.end()
156
+ ```
157
+
158
+ ## Hide the boring parts
159
+
160
+ `hide()` cuts a section from the final video. Perfect for logins, page loads, and test setup.
161
+
162
+ ```ts
163
+ import { video, hide } from 'screenci'
164
+
165
+ video('Dashboard demo', async ({ page }) => {
166
+ await hide(async () => {
167
+ // viewer never sees this
168
+ await page.goto('/login')
169
+ await page.fill('input[name="email"]', 'admin@example.com')
170
+ await page.fill('input[name="password"]', 'hunter2')
171
+ await page.click('button[type="submit"]')
172
+ await page.waitForURL('**/dashboard')
173
+ })
174
+
175
+ // video starts here — dashboard is already open
176
+ await page.locator('#reports').click()
177
+ })
178
+ ```
179
+
180
+ ## Zoom the camera
181
+
182
+ `autoZoom()` follows interactions with a smooth camera pan. Wrap a form or a page section, not individual clicks.
183
+
184
+ ```ts
185
+ import { video, autoZoom } from 'screenci'
186
+
187
+ video('Profile settings', async ({ page }) => {
188
+ await page.goto('/settings/profile')
189
+
190
+ await autoZoom(
191
+ async () => {
192
+ await page.locator('#name').fill('Jane Doe')
193
+ await page.locator('#bio').fill('Engineer')
194
+ await page.locator('button[type="submit"]').click()
195
+ },
196
+ { duration: 400, amount: 0.4, easing: 'ease-in-out' }
197
+ )
198
+ })
199
+ ```
200
+
201
+ ## API
202
+
203
+ | Export | What it does |
204
+ | ---------------- | ---------------------------------------------------- |
205
+ | `defineConfig` | Wraps Playwright config with screenci defaults |
206
+ | `video` | Declares a video recording test |
207
+ | `createCaptions` | Creates typed caption controllers with AI voiceovers |
208
+ | `hide` | Cuts a section from the final video |
209
+ | `autoZoom` | Smooth camera pan that follows interactions |
210
+ | `voices` | Available voice constants (`voices.en.Jude`, etc.) |
211
+
212
+ The `page` fixture inside `video()` is a `ScreenCIPage` — a Playwright `Page` with animated cursor support wired in on all locator methods.
213
+
214
+ ## Output
215
+
216
+ ```
217
+ .screenci/
218
+ <video-name>/
219
+ recording.mp4 ← the raw screen capture
220
+ data.json ← interaction events + caption metadata
221
+ ```
222
+
223
+ Upload to screenci.com for rendering, voiceover generation, and the permanent embed link:
224
+
225
+ ```bash
226
+ npm run upload-latest
227
+ ```