screenci 0.0.86 → 0.0.88

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 (54) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +11 -4
  3. package/dist/cli.js.map +1 -1
  4. package/dist/docs/manifest.d.ts +67 -5
  5. package/dist/docs/manifest.d.ts.map +1 -1
  6. package/dist/docs/manifest.js +23 -1
  7. package/dist/docs/manifest.js.map +1 -1
  8. package/dist/docs/video-sources/installation.screenci.js +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/src/anonSession.d.ts +7 -0
  13. package/dist/src/anonSession.d.ts.map +1 -1
  14. package/dist/src/anonSession.js +14 -0
  15. package/dist/src/anonSession.js.map +1 -1
  16. package/dist/src/asset.d.ts +9 -8
  17. package/dist/src/asset.d.ts.map +1 -1
  18. package/dist/src/asset.js +23 -82
  19. package/dist/src/asset.js.map +1 -1
  20. package/dist/src/changeFocus.d.ts +22 -0
  21. package/dist/src/changeFocus.d.ts.map +1 -1
  22. package/dist/src/changeFocus.js +35 -0
  23. package/dist/src/changeFocus.js.map +1 -1
  24. package/dist/src/defaults.d.ts +10 -0
  25. package/dist/src/defaults.d.ts.map +1 -1
  26. package/dist/src/defaults.js +10 -0
  27. package/dist/src/defaults.js.map +1 -1
  28. package/dist/src/events.d.ts +10 -0
  29. package/dist/src/events.d.ts.map +1 -1
  30. package/dist/src/events.js.map +1 -1
  31. package/dist/src/init.d.ts +2 -0
  32. package/dist/src/init.d.ts.map +1 -1
  33. package/dist/src/init.js +127 -18
  34. package/dist/src/init.js.map +1 -1
  35. package/dist/src/instrument.d.ts.map +1 -1
  36. package/dist/src/instrument.js +70 -3
  37. package/dist/src/instrument.js.map +1 -1
  38. package/dist/src/manualZoom.d.ts.map +1 -1
  39. package/dist/src/manualZoom.js +9 -20
  40. package/dist/src/manualZoom.js.map +1 -1
  41. package/dist/src/mouse.d.ts +8 -0
  42. package/dist/src/mouse.d.ts.map +1 -1
  43. package/dist/src/mouse.js +8 -3
  44. package/dist/src/mouse.js.map +1 -1
  45. package/dist/src/runtimeContext.d.ts +0 -17
  46. package/dist/src/runtimeContext.d.ts.map +1 -1
  47. package/dist/src/runtimeContext.js +0 -3
  48. package/dist/src/runtimeContext.js.map +1 -1
  49. package/dist/src/types.d.ts +8 -0
  50. package/dist/src/types.d.ts.map +1 -1
  51. package/dist/tsconfig.tsbuildinfo +1 -1
  52. package/package.json +1 -1
  53. package/skills/playwright-cli/SKILL.md +41 -212
  54. package/skills/screenci/SKILL.md +48 -84
@@ -7,16 +7,31 @@ allowed-tools:
7
7
  - Bash(npm:*)
8
8
  ---
9
9
 
10
+ <!--
11
+ Adapted from the "playwright-cli" skill in the Microsoft Playwright CLI project
12
+ (https://github.com/microsoft/playwright-cli), Copyright (c) Microsoft Corporation,
13
+ licensed under the Apache License, Version 2.0. Modified by ScreenCI.
14
+ Full license and attribution: see THIRD_PARTY_NOTICES.md and
15
+ licenses/microsoft-playwright-cli-APACHE-2.0.txt in the screenci package.
16
+ -->
17
+
10
18
  # Browser Automation with playwright-cli
11
19
 
12
- ## When Inspecting Pages For ScreenCI
20
+ Use `playwright-cli` to inspect a live page and discover the real flow, stable
21
+ selectors, and cookie/consent steps before authoring a ScreenCI `.screenci.ts`
22
+ script. It drives a real browser from the CLI: navigate, snapshot, click, type.
13
23
 
14
- When `playwright-cli` is being used to inspect a page for a ScreenCI video flow:
24
+ ## When Inspecting Pages For ScreenCI
15
25
 
16
- - After the first navigation and snapshot, explicitly check whether a cookie consent or cookie policy banner appeared.
17
- - Try to identify the exact accept action the video script should use inside the initial `hide()` block, preferably with a stable Playwright locator such as `getByRole('button', { name: /accept|accept all|allow all|agree|ok/i })`.
18
- - If multiple consent actions exist, prefer the clear accept/allow action instead of a dismiss-only or settings action.
19
- - Report that cookie-consent click as part of the hidden initial navigation/setup, not as a visible demo step.
26
+ - After the first navigation and snapshot, check whether a cookie consent or
27
+ cookie policy banner appeared.
28
+ - Identify the exact accept action the video script should use inside its initial
29
+ `hide()` block, preferably a stable locator such as
30
+ `getByRole('button', { name: /accept|accept all|allow all|agree|ok/i })`.
31
+ - If multiple consent actions exist, prefer the clear accept/allow action over a
32
+ dismiss-only or settings action.
33
+ - Report that cookie-consent click as part of the hidden initial setup, not as a
34
+ visible demo step.
20
35
 
21
36
  ## Quick start
22
37
 
@@ -29,15 +44,11 @@ playwright-cli goto https://playwright.dev
29
44
  playwright-cli click e15
30
45
  playwright-cli type "page.click"
31
46
  playwright-cli press Enter
32
- # take a screenshot (rarely used, as snapshot is more common)
33
- playwright-cli screenshot
34
47
  # close the browser
35
48
  playwright-cli close
36
49
  ```
37
50
 
38
- ## Commands
39
-
40
- ### Core
51
+ ## Core commands
41
52
 
42
53
  ```bash
43
54
  playwright-cli open
@@ -49,22 +60,15 @@ playwright-cli click e3
49
60
  playwright-cli dblclick e7
50
61
  # --submit presses Enter after filling the element
51
62
  playwright-cli fill e5 "user@example.com" --submit
52
- playwright-cli drag e2 e8
53
63
  playwright-cli hover e4
54
64
  playwright-cli select e9 "option-value"
55
- playwright-cli upload ./document.pdf
56
65
  playwright-cli check e12
57
66
  playwright-cli uncheck e12
58
67
  playwright-cli snapshot
59
68
  playwright-cli eval "document.title"
60
69
  playwright-cli eval "el => el.textContent" e5
61
- # get element id, class, or any attribute not visible in the snapshot
62
- playwright-cli eval "el => el.id" e5
70
+ # get an attribute not visible in the snapshot
63
71
  playwright-cli eval "el => el.getAttribute('data-testid')" e5
64
- playwright-cli dialog-accept
65
- playwright-cli dialog-accept "confirmation text"
66
- playwright-cli dialog-dismiss
67
- playwright-cli resize 1920 1080
68
72
  playwright-cli close
69
73
  ```
70
74
 
@@ -74,146 +78,8 @@ playwright-cli close
74
78
  playwright-cli go-back
75
79
  playwright-cli go-forward
76
80
  playwright-cli reload
77
- ```
78
-
79
- ### Keyboard
80
-
81
- ```bash
82
81
  playwright-cli press Enter
83
82
  playwright-cli press ArrowDown
84
- playwright-cli keydown Shift
85
- playwright-cli keyup Shift
86
- ```
87
-
88
- ### Mouse
89
-
90
- ```bash
91
- playwright-cli mousemove 150 300
92
- playwright-cli mousedown
93
- playwright-cli mousedown right
94
- playwright-cli mouseup
95
- playwright-cli mouseup right
96
- playwright-cli mousewheel 0 100
97
- ```
98
-
99
- ### Save as
100
-
101
- ```bash
102
- playwright-cli screenshot
103
- playwright-cli screenshot e5
104
- playwright-cli screenshot --filename=page.png
105
- playwright-cli pdf --filename=page.pdf
106
- ```
107
-
108
- ### Tabs
109
-
110
- ```bash
111
- playwright-cli tab-list
112
- playwright-cli tab-new
113
- playwright-cli tab-new https://example.com/page
114
- playwright-cli tab-close
115
- playwright-cli tab-close 2
116
- playwright-cli tab-select 0
117
- ```
118
-
119
- ### Storage
120
-
121
- ```bash
122
- playwright-cli state-save
123
- playwright-cli state-save auth.json
124
- playwright-cli state-load auth.json
125
-
126
- # Cookies
127
- playwright-cli cookie-list
128
- playwright-cli cookie-list --domain=example.com
129
- playwright-cli cookie-get session_id
130
- playwright-cli cookie-set session_id abc123
131
- playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
132
- playwright-cli cookie-delete session_id
133
- playwright-cli cookie-clear
134
-
135
- # LocalStorage
136
- playwright-cli localstorage-list
137
- playwright-cli localstorage-get theme
138
- playwright-cli localstorage-set theme dark
139
- playwright-cli localstorage-delete theme
140
- playwright-cli localstorage-clear
141
-
142
- # SessionStorage
143
- playwright-cli sessionstorage-list
144
- playwright-cli sessionstorage-get step
145
- playwright-cli sessionstorage-set step 3
146
- playwright-cli sessionstorage-delete step
147
- playwright-cli sessionstorage-clear
148
- ```
149
-
150
- ### Network
151
-
152
- ```bash
153
- playwright-cli route "**/*.jpg" --status=404
154
- playwright-cli route "https://api.example.com/**" --body='{"mock": true}'
155
- playwright-cli route-list
156
- playwright-cli unroute "**/*.jpg"
157
- playwright-cli unroute
158
- ```
159
-
160
- ### DevTools
161
-
162
- ```bash
163
- playwright-cli console
164
- playwright-cli console warning
165
- playwright-cli network
166
- playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])"
167
- playwright-cli run-code --filename=script.js
168
- playwright-cli tracing-start
169
- playwright-cli tracing-stop
170
- playwright-cli video-start video.webm
171
- playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000
172
- playwright-cli video-stop
173
- ```
174
-
175
- ## Raw output
176
-
177
- The global `--raw` option strips page status, generated code, and snapshot sections from the output, returning only the result value.
178
- Use it to pipe command output into other tools. Commands that don't produce output return nothing.
179
-
180
- ```bash
181
- playwright-cli --raw eval "JSON.stringify(performance.timing)" | jq '.loadEventEnd - .navigationStart'
182
- playwright-cli --raw eval "JSON.stringify([...document.querySelectorAll('a')].map(a => a.href))" > links.json
183
- playwright-cli --raw snapshot > before.yml
184
- playwright-cli click e5
185
- playwright-cli --raw snapshot > after.yml
186
- diff before.yml after.yml
187
- TOKEN=$(playwright-cli --raw cookie-get session_id)
188
- playwright-cli --raw localstorage-get theme
189
- ```
190
-
191
- ## Open parameters
192
-
193
- ```bash
194
- # Use specific browser when creating session
195
- playwright-cli open --browser=chrome
196
- playwright-cli open --browser=firefox
197
- playwright-cli open --browser=webkit
198
- playwright-cli open --browser=msedge
199
-
200
- # Use persistent profile (by default profile is in-memory)
201
- playwright-cli open --persistent
202
-
203
- # Use persistent profile with custom directory
204
- playwright-cli open --profile=/path/to/profile
205
-
206
- # Connect to browser via extension
207
- playwright-cli attach --extension
208
-
209
- # Start with config file
210
- playwright-cli open --config=my-config.json
211
-
212
- # Close the browser
213
- playwright-cli close
214
-
215
- # Delete user data for the default session
216
- playwright-cli delete-data
217
83
  ```
218
84
 
219
85
  ## Snapshots
@@ -229,23 +95,30 @@ After each command, playwright-cli provides a snapshot of the current browser st
229
95
  [Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
230
96
  ```
231
97
 
232
- You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed.
98
+ You can also take a snapshot on demand. Options can be combined.
233
99
 
234
100
  ```bash
235
101
  # default - save to a file with timestamp-based name
236
102
  playwright-cli snapshot
237
103
 
238
- # save to file, use when snapshot is a part of the workflow result
239
- playwright-cli snapshot --filename=after-click.yaml
240
-
241
104
  # snapshot an element instead of the whole page
242
105
  playwright-cli snapshot "#main"
243
106
 
244
- # limit snapshot depth for efficiency, take a partial snapshot afterwards
107
+ # limit snapshot depth for efficiency
245
108
  playwright-cli snapshot --depth=4
246
109
  playwright-cli snapshot e34
247
110
  ```
248
111
 
112
+ The global `--raw` option strips page status and generated code, returning only
113
+ the result value. Use it to pipe output into other tools.
114
+
115
+ ```bash
116
+ playwright-cli --raw snapshot > before.yml
117
+ playwright-cli click e5
118
+ playwright-cli --raw snapshot > after.yml
119
+ diff before.yml after.yml
120
+ ```
121
+
249
122
  ## Targeting elements
250
123
 
251
124
  By default, use refs from the snapshot to interact with page elements.
@@ -274,36 +147,25 @@ playwright-cli click "getByTestId('submit-button')"
274
147
  ## Browser Sessions
275
148
 
276
149
  ```bash
277
- # create new browser session named "mysession" with persistent profile
278
- playwright-cli -s=mysession open example.com --persistent
279
-
280
- # same with manually specified profile directory (use when requested explicitly)
281
- playwright-cli -s=mysession open example.com --profile=/path/to/profile
150
+ # create a named browser session
151
+ playwright-cli -s=mysession open example.com
282
152
  playwright-cli -s=mysession click e6
283
153
  playwright-cli -s=mysession close
284
154
 
285
- # stop a named browser
286
- playwright-cli -s=mysession delete-data
287
-
288
- # delete user data for persistent session
289
155
  playwright-cli list
290
-
291
- # Close all browsers
156
+ # close all browsers
292
157
  playwright-cli close-all
293
-
294
- # Forcefully kill all browser processes
295
- playwright-cli kill-all
296
158
  ```
297
159
 
298
160
  ## Installation
299
161
 
300
- If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`:
162
+ If global `playwright-cli` is not available, try a local version:
301
163
 
302
164
  ```bash
303
165
  npx --no-install playwright-cli --version
304
166
  ```
305
167
 
306
- Otherwise, install `playwright-cli` as a global command:
168
+ Otherwise install it globally:
307
169
 
308
170
  ```bash
309
171
  npm install -g @playwright/cli@latest
@@ -321,37 +183,4 @@ playwright-cli snapshot
321
183
  playwright-cli close
322
184
  ```
323
185
 
324
- ## Example: Multi-tab workflow
325
-
326
- ```bash
327
- playwright-cli open https://example.com
328
- playwright-cli tab-new https://example.com/other
329
- playwright-cli tab-list
330
- playwright-cli tab-select 0
331
- playwright-cli snapshot
332
- playwright-cli close
333
- ```
334
-
335
- ## Example: Debugging with DevTools
336
-
337
- ```bash
338
- playwright-cli open https://example.com
339
- playwright-cli click e4
340
- playwright-cli fill e7 "test"
341
- playwright-cli console
342
- playwright-cli network
343
- playwright-cli close
344
- ```
345
-
346
- ```bash
347
- playwright-cli open https://example.com
348
- playwright-cli tracing-start
349
- playwright-cli click e4
350
- playwright-cli fill e7 "test"
351
- playwright-cli tracing-stop
352
- playwright-cli close
353
- ```
354
-
355
- ## Specific tasks
356
-
357
- Later revisions can add the upstream `references/` files here as needed.
186
+ </content>
@@ -9,56 +9,45 @@ allowed-tools:
9
9
 
10
10
  # ScreenCI Video and Guide Skill
11
11
 
12
- Use this skill when the task is about ScreenCI video recording workflows in an existing project, or updating `.screenci.ts` files and `screenci.config.ts`.
12
+ Use this skill when the task is about ScreenCI video recording in an existing project: creating a video, showing a flow as a video, or editing `.screenci.ts` / `screenci.config.ts` files.
13
13
 
14
- Trigger this skill when the user asks to:
14
+ Routing:
15
15
 
16
- - create a video
17
- - show a flow as a video
18
- - create a guide/demo video
19
-
20
- Routing rules:
21
-
22
- - If the user provides a URL for video context, always use the `playwright-cli` skill first. It drives a real browser from the CLI (navigate, snapshot, click, type) so you can discover the actual page flow, stable selectors, and cookie/consent steps before editing the ScreenCI script.
23
- - If the user provides source code for the target page/component, that usually means browser exploration is not required first.
24
- - If the request is only about application/source-code changes (not recording or `.screenci.ts` updates), do not use this skill.
16
+ - If the user gives a URL for video context, use the `playwright-cli` skill first to discover the real page flow, stable selectors, and cookie/consent steps before editing the script.
17
+ - If the user gives source code for the target page, browser exploration is usually not needed first.
18
+ - If the request is only about application/source-code changes (not recording), do not use this skill.
25
19
 
26
20
  ## Quick Start
27
21
 
28
- Assume the project is already initialized. Add or edit video scripts in `recordings/`.
29
-
30
- If you are creating new videos, remove the starter `recordings/example.screenci.ts` file.
22
+ The project is already initialized. Add or edit scripts in `recordings/`. If you are creating new videos, remove the starter `recordings/example.screenci.ts`.
31
23
 
32
24
  ```bash
33
25
  # verify repeatedly until green
34
26
  npx screenci test
35
27
 
36
- # run only some tests with normal Playwright filters
28
+ # run a subset with normal Playwright filters
37
29
  npx screenci test recordings/signup.screenci.ts --grep "fills billing details"
38
30
 
39
31
  # only record after tests pass
40
32
  npx screenci record
41
33
  ```
42
34
 
43
- `npx screenci test` accepts normal `playwright test` argument syntax after `test`. ScreenCI still injects its resolved `screenci.config.ts` automatically. `--config` / `-c` and `--verbose` / `-v` are reserved for the ScreenCI CLI itself rather than being forwarded to Playwright.
35
+ `test` forwards normal `playwright test` arguments and still injects the resolved `screenci.config.ts`. `--config`/`-c` and `--verbose`/`-v` are reserved for the ScreenCI CLI, not forwarded to Playwright.
44
36
 
45
37
  ## What ScreenCI Adds
46
38
 
47
- ScreenCI uses Playwright-style `.screenci.ts` files and adds recording-specific helpers:
39
+ ScreenCI uses Playwright-style `.screenci.ts` files plus recording helpers:
48
40
 
49
41
  - `video()` declares one output video per test.
50
- - `hide()` removes setup and loading sections from the final recording.
51
- - `autoZoom()` follows navigation, click-driven, and broader interaction sequences with smooth camera motion. Use it sparingly, and start with its default options unless the user explicitly asks for different zoom behavior or the flow clearly needs a targeted override.
52
- - `zoomTo()` and `resetZoom()` are better for forms and other steady editing sections where the camera should stay fixed while the user types, selects, toggles, and confirms within one area.
53
- - `video.narration({ ... })` is mandatory for every video: declare narration in every `.screenci.ts` file and include spoken narration throughout the demo. Pass either a flat object of cue name to text (shared across all languages) or an object keyed by language (`en`, `es`, ...) of cue name to text. The opening narration should first state the purpose of the video, then continue with the explanation or walkthrough. The body receives the `narration` marker object: 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 action, and `await narration.key.end()` only to close that same active cue later, especially before visible navigation or route changes. Voice is a render option, not part of the narration spec: set a default (and optional per-language overrides) with `video.use({ renderOptions: { narration: { voice: { name: voices.Ava } } } })` or in `screenci.config.ts`.
54
- - Narration text can include inline speech-control tags such as `[pronounce: screen see eye]`, `[short pause]`, `[medium pause]`, and `[long pause]` when a word needs guided pronunciation or an intentional pause. When narration includes a URL or domain name, add a pronunciation guide or rewrite the line so it will be spoken clearly. Example: `screenci.com [pronounce: screen see eye dot com]`.
55
-
56
- Example:
42
+ - `hide()` cuts setup and loading sections from the final recording.
43
+ - `autoZoom()` follows navigation and click-driven flows with smooth camera motion. Use it for movement between targets.
44
+ - `zoomTo()` / `resetZoom()` hold a fixed frame for forms and steady editing sections.
45
+ - `video.narration({ ... })` is mandatory (see below).
57
46
 
58
47
  ```ts
59
48
  import { video, voices } from 'screenci'
60
49
 
61
- // Voice is a render option (how narration is spoken).
50
+ // Voice is a render option (how narration is spoken), not part of the narration spec.
62
51
  video.use({ renderOptions: { narration: { voice: { name: voices.Ava } } } })
63
52
 
64
53
  video.narration({
@@ -82,40 +71,39 @@ video.narration({
82
71
  })
83
72
  ```
84
73
 
74
+ ### Narration
75
+
76
+ - Declare `video.narration({ ... })` on every video and speak throughout the demo. Pass a flat `cue -> text` object (shared across languages) or one keyed by language (`en`, `es`, ...).
77
+ - The opening line must state the video's purpose, then continue with the walkthrough.
78
+ - Trigger cues from the `narration` fixture: `await narration.key()` runs the full line before moving on. Use `await narration.key.start()` when narration should overlap the next action, and `await narration.key.end()` to close that cue later, especially before visible navigation or route changes.
79
+ - Use inline speech tags when needed: `[pronounce: ...]`, `[short pause]`, `[medium pause]`, `[long pause]`. Always guide pronunciation for URLs and domains, e.g. `screenci.com [pronounce: screen see eye dot com]`.
80
+
85
81
  ## Required Conventions
86
82
 
87
- **Every video MUST follow these conventions:**
83
+ Every video MUST follow these:
88
84
 
89
- - **Narration on every video (required, no exceptions)** — always declare `video.narration({ ... })` and add narration to every `.screenci.ts` file. Videos without narration are not acceptable.
90
- - **Open with the video's purpose** — the first spoken narration should clearly state what the video is for before moving into the step-by-step explanation.
91
- - **Guide pronunciation for URLs and domains** if narration says a URL, domain, product name, or other term that a voice model might read incorrectly, add a `[pronounce: ...]` hint or phrase it in a clearly spoken way.
92
- - **Start on the requested page** the visible video should always begin on the page the user requested.
93
- - **Hide initial setup** the initial page load should almost always be wrapped in `hide()`. Keep authentication, navigation to the starting page, loading spinners, cookie banner dismissal, and any other non-demo boilerplate inside that hidden block so they are cut from the final recording. After the initial navigation, explicitly try to find and click any cookie consent or cookie policy accept button there if one appears.
94
- - **Navigate visibly with clicks** after hidden setup, move through the demo by clicking real links and buttons instead of calling `page.goto()`.
95
- - **Prefer mouse-driven selection after typing** — when typing into search boxes, comboboxes, autocomplete fields, command menus, or similar UI, prefer clicking the visible result or CTA with the mouse instead of submitting with keyboard actions like `press('Enter')` when a clickable target is available. Example: after `await searchBox.fill('product')`, prefer `await page.getByRole('link', { name: 'Specific Product' }).click()`.
96
- - **Prefer native Playwright APIs over `page.evaluate()`** when Playwright or locator methods already support an interaction, use them directly instead of DOM scripting. For example, prefer `await locator.blur()` over `await page.evaluate(() => { if (document.activeElement instanceof HTMLElement) { document.activeElement.blur() } })`.
97
- - **Prefer manual zoom for forms and steady editing sections** — when the demo focuses on filling a form, editing settings, or working within one stable panel, prefer `zoomTo()` before the sequence and `resetZoom()` after it instead of `autoZoom()`. This keeps the framing stable while the user types, selects, toggles, and saves.
98
- - **Use autoZoom for navigation and click-driven flows** — prefer `autoZoom()` for visible navigation, opening menus, moving across lists, stepping through dialogs, clicking through dashboards, or other flows where the camera should follow movement between targets.
99
- - **Use autoZoom sparingly on large page areas** — do not default to `autoZoom()` for every form or page section. Keep usage sparse, and make sure each `autoZoom()` block is justified by movement between targets rather than by simple text entry alone.
100
- - **End autoZoom before page changes** — it is better to let an `autoZoom()` block finish before a navigation/page change. Staying zoomed during navigation is confusing. Start a new `autoZoom()` block on the next page/section when needed.
101
- - **Prefer default action options** — for `autoZoom()` and locator actions such as `click()`, `fill()`, `pressSequentially()`, `check()`, `uncheck()`, `selectOption()`, `selectText()`, and similar helpers, start with ScreenCI's default options. In particular, do not add a separate `locator.click()` before `locator.fill()` or `locator.pressSequentially()` just to focus the field: those actions already move to the field, click it, and then type by default. Do not add custom `zoom`, `click`, `position`, timing, or other locator-action overrides unless the user asks for them or the recording flow clearly needs a specific adjustment.
85
+ - **Narration on every video, no exceptions.** Videos without narration are not acceptable.
86
+ - **Open with the video's purpose** before the step-by-step.
87
+ - **Start on the requested page.** The visible video begins on the page the user asked for.
88
+ - **Hide initial setup.** Wrap page load, auth, navigation to the start page, loading spinners, and cookie-banner dismissal in `hide()`. After the initial navigation, find and click any cookie consent accept button inside that hidden block.
89
+ - **Navigate visibly with clicks** after hidden setup, not `page.goto()`.
90
+ - **Prefer mouse-driven selection after typing** into search boxes, comboboxes, autocomplete, or command menus: click the visible result rather than `press('Enter')` when a clickable target exists.
91
+ - **Prefer native Playwright APIs over `page.evaluate()`** when a locator method already covers the interaction (e.g. `locator.blur()`).
92
+ - **Prefer default action options.** For `autoZoom()` and locator actions (`click`, `fill`, `pressSequentially`, `check`, `selectOption`, ...), start with ScreenCI's defaults. Do not add a separate `click()` before `fill()`/`pressSequentially()` just to focus, and do not add `zoom`/`click`/`position`/timing overrides unless the user asks or the flow clearly needs it.
102
93
 
103
- ## Zooming Guide
94
+ ## Zooming
104
95
 
105
- Prefer stable manual zoom for edit-heavy sections:
96
+ Prefer stable manual zoom for edit-heavy sections; use `autoZoom()` for movement between targets, and let each `autoZoom()` block finish before a navigation or page change (start a new block on the next page). Keep `autoZoom()` usage sparse: justify each block by movement between targets, not simple text entry.
106
97
 
107
98
  ```ts
99
+ // Forms and steady editing: fixed frame.
108
100
  await zoomTo(page.getByRole('form', { name: /profile settings/i }))
109
101
  await page.getByLabel('Name').fill('Jane Doe')
110
- await page.getByLabel('Email').fill('jane@example.com')
111
102
  await page.getByRole('checkbox', { name: 'Email notifications' }).check()
112
103
  await page.getByRole('button', { name: 'Save changes' }).click()
113
104
  await resetZoom()
114
- ```
115
-
116
- Prefer `autoZoom()` for movement between targets:
117
105
 
118
- ```ts
106
+ // Navigation and click-driven flows: follow the movement.
119
107
  await autoZoom(async () => {
120
108
  await page.getByRole('link', { name: 'Reports' }).click()
121
109
  await page.getByRole('button', { name: 'Open filters' }).click()
@@ -124,53 +112,29 @@ await autoZoom(async () => {
124
112
  })
125
113
  ```
126
114
 
127
- ## Command Notes
115
+ ## Connecting to an Account (optional)
128
116
 
129
- - `screenci init` (or `npm init screenci`) scaffolds a new project. It can be run at any time, but if the project is already initialized it fails on purpose: it exits with an error like `screenci/ already exists`. That is expected, not a problem to fix. Do not delete the existing project to force a re-init. Continue working with the project that is already there. No account is needed. If the user gives you an existing `SCREENCI_SECRET`, pass it as the first argument (`npm init screenci@latest <SCREENCI_SECRET> -- --yes`) and init connects the project by writing it into `screenci/.env`.
130
- - `screenci record` runs the recording flow with local Playwright.
131
- - `screenci test <playwright args...>` forwards most Playwright test arguments unchanged, while still using `screenci.config.ts`.
117
+ `record` needs no account: without a `SCREENCI_SECRET` it uploads under a local, anonymous trial session and prints a link to view the result. Mention this and keep going.
132
118
 
133
- ### Connecting to an account (optional)
119
+ To upload straight to an existing organization, get `SCREENCI_SECRET` into `screenci/.env` before the final `record` (it does not block authoring or testing):
134
120
 
135
- `screenci record` needs no account or setup step: without a `SCREENCI_SECRET`, it uploads under a local, anonymous trial session and prints a link to view the result. Mention this to the user and keep going.
136
-
137
- To upload straight to an existing organization instead, connect the project one of two ways:
138
-
139
- 1. **Pass the secret to init.** If the user gave you their `SCREENCI_SECRET`, run `npm init screenci@latest <SCREENCI_SECRET> -- --yes`. Init writes it into `screenci/.env`.
140
- 2. **Secrets page.** Otherwise ask the user to copy `SCREENCI_SECRET` from their **secrets page** into `screenci/.env`. The org secret is shared across projects. Relay this and keep building and testing the video while they do it; only the final `record` needs it.
121
+ 1. **Pass it to init:** `npm init screenci@latest <SCREENCI_SECRET> -- --yes` writes it into `screenci/.env`.
122
+ 2. **Secrets page:** ask the user to copy `SCREENCI_SECRET` from their secrets page into `screenci/.env`. The org secret is shared across projects. Keep building and testing while they do it; only `record` needs it.
141
123
 
142
124
  Renders without an account, and renders on the free tier, include a ScreenCI watermark. Mention that signing up (or upgrading) removes it.
143
125
 
144
126
  ## Recording Workflow
145
127
 
146
- 1. Start from the existing initialized ScreenCI package. No connection step is required: `record` works immediately, uploading under an anonymous trial session unless `SCREENCI_SECRET` is set. If the user gave you a secret, make sure it is in `screenci/.env`.
147
- 2. Add or edit `.screenci.ts` files in `recordings/`.
148
- Remove `recordings/example.screenci.ts` if you are creating new videos and do not need the starter video.
149
- For narration, declare it on the test with `video.narration({ en: { ... } })` and trigger lines from the `narration` fixture with `await narration.someKey()` when the full line should finish before moving on. Use `await narration.someKey.start()` only when narration should overlap with the next action, and `await narration.someKey.end()` only to close that same active cue later. This is especially important before visible navigation or page changes. Use inline tags like `[pronounce: ...]` and `[short pause]` inside cue text when needed, especially for URLs and domains such as `screenci.com [pronounce: screen see eye dot com]`.
150
- Example:
151
-
152
- ```ts
153
- video.narration({
154
- en: {
155
- intro: 'This video shows how to export a monthly sales report.',
156
- filters:
157
- 'First, we set the report range and select the sales channel filters.',
158
- export: 'Then we export the report and wait for the download to start.',
159
- },
160
- })('Export sales report', async ({ page, narration }) => {
161
- await narration.intro()
162
- await narration.filters()
163
- await narration.export.start()
164
- await page.getByRole('button', { name: 'Export CSV' }).click()
165
- await narration.export.end()
166
- })
167
- ```
168
-
169
- 3. Run `npx screenci test` until it passes.
170
- 4. For the final recording, run `npx screenci record` yourself. It records and uploads immediately, with or without `SCREENCI_SECRET` set.
171
- 5. ScreenCI writes `.screenci/<video-name>/recording.mp4` and `data.json` for each recorded video.
172
- 6. Report the URL `record` printed (it starts with the app's domain, e.g. `https://app.screenci.com/record/...`) back to the user so they can open it. Without a `SCREENCI_SECRET`, this is also how they view and claim the anonymous trial recording.
128
+ 1. Add or edit `.screenci.ts` files in `recordings/` (remove `example.screenci.ts` if creating new videos).
129
+ 2. Run `npx screenci test` until it passes. Fix selectors/flow/narration and rerun until green.
130
+ 3. Run `npx screenci record` yourself once tests pass. Do not stop and ask the user to record. It uploads immediately, with or without `SCREENCI_SECRET`.
131
+ 4. ScreenCI writes `.screenci/<video-name>/recording.mp4` and `data.json` per video.
132
+ 5. Report the URL `record` printed (starts with the app's domain, e.g. `https://app.screenci.com/record/...`) so the user can open it. Without a `SCREENCI_SECRET`, this is also how they view and claim the anonymous trial recording.
133
+
134
+ `screenci init` (or `npm init screenci`) scaffolds a new project and fails on purpose if one already exists (`screenci/ already exists`). That is expected: keep working with the existing project, do not delete it to re-init.
173
135
 
174
136
  ## Specific Tasks
175
137
 
176
138
  - **Recording videos** [references/record.md](references/record.md)
139
+ </content>
140
+ </invoke>