screenci 0.0.75 → 0.0.78

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 (226) hide show
  1. package/dist/cli.d.ts +62 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +699 -229
  4. package/dist/cli.js.map +1 -1
  5. package/dist/docs/manifest.d.ts +277 -91
  6. package/dist/docs/manifest.d.ts.map +1 -1
  7. package/dist/docs/manifest.js +101 -30
  8. package/dist/docs/manifest.js.map +1 -1
  9. package/dist/docs/video-sources/camera-and-zooming.screenci.d.ts +2 -0
  10. package/dist/docs/video-sources/camera-and-zooming.screenci.d.ts.map +1 -0
  11. package/dist/docs/video-sources/camera-and-zooming.screenci.js +57 -0
  12. package/dist/docs/video-sources/camera-and-zooming.screenci.js.map +1 -0
  13. package/dist/docs/video-sources/installation.screenci.js +19 -10
  14. package/dist/docs/video-sources/installation.screenci.js.map +1 -1
  15. package/dist/docs/video-sources/landing.screenci.js +6 -8
  16. package/dist/docs/video-sources/landing.screenci.js.map +1 -1
  17. package/dist/docs/video-sources/languages.screenci.d.ts +2 -0
  18. package/dist/docs/video-sources/languages.screenci.d.ts.map +1 -0
  19. package/dist/docs/video-sources/languages.screenci.js +68 -0
  20. package/dist/docs/video-sources/languages.screenci.js.map +1 -0
  21. package/dist/docs/video-sources/locator-highlight-animated.screenci.js +4 -5
  22. package/dist/docs/video-sources/locator-highlight-animated.screenci.js.map +1 -1
  23. package/dist/docs/video-sources/locator-highlight-still.screenci.js +3 -4
  24. package/dist/docs/video-sources/locator-highlight-still.screenci.js.map +1 -1
  25. package/dist/docs/video-sources/narration.screenci.d.ts +2 -0
  26. package/dist/docs/video-sources/narration.screenci.d.ts.map +1 -0
  27. package/dist/docs/video-sources/narration.screenci.js +71 -0
  28. package/dist/docs/video-sources/narration.screenci.js.map +1 -0
  29. package/dist/docs/video-sources/public-urls-and-embeds.screenci.d.ts +2 -0
  30. package/dist/docs/video-sources/public-urls-and-embeds.screenci.d.ts.map +1 -0
  31. package/dist/docs/video-sources/public-urls-and-embeds.screenci.js +60 -0
  32. package/dist/docs/video-sources/public-urls-and-embeds.screenci.js.map +1 -0
  33. package/dist/docs/video-sources/speaking-style.screenci.d.ts +2 -0
  34. package/dist/docs/video-sources/speaking-style.screenci.d.ts.map +1 -0
  35. package/dist/docs/video-sources/speaking-style.screenci.js +76 -0
  36. package/dist/docs/video-sources/speaking-style.screenci.js.map +1 -0
  37. package/dist/docs/video-sources/studio.screenci.js +8 -10
  38. package/dist/docs/video-sources/studio.screenci.js.map +1 -1
  39. package/dist/docs/video-sources/vertical-video.screenci.d.ts +2 -0
  40. package/dist/docs/video-sources/vertical-video.screenci.d.ts.map +1 -0
  41. package/dist/docs/video-sources/vertical-video.screenci.js +58 -0
  42. package/dist/docs/video-sources/vertical-video.screenci.js.map +1 -0
  43. package/dist/docs/videos.d.ts +20 -0
  44. package/dist/docs/videos.d.ts.map +1 -1
  45. package/dist/docs/videos.js +25 -0
  46. package/dist/docs/videos.js.map +1 -1
  47. package/dist/e2e/instrument.e2e.js +60 -1
  48. package/dist/e2e/instrument.e2e.js.map +1 -1
  49. package/dist/e2e/redact.e2e.d.ts +2 -0
  50. package/dist/e2e/redact.e2e.d.ts.map +1 -0
  51. package/dist/e2e/redact.e2e.js +161 -0
  52. package/dist/e2e/redact.e2e.js.map +1 -0
  53. package/dist/index.d.ts +12 -6
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +8 -2
  56. package/dist/index.js.map +1 -1
  57. package/dist/src/asset.d.ts +174 -14
  58. package/dist/src/asset.d.ts.map +1 -1
  59. package/dist/src/asset.js +320 -39
  60. package/dist/src/asset.js.map +1 -1
  61. package/dist/src/assetHash.d.ts +27 -0
  62. package/dist/src/assetHash.d.ts.map +1 -0
  63. package/dist/src/assetHash.js +0 -0
  64. package/dist/src/assetHash.js.map +1 -0
  65. package/dist/src/audio.d.ts +20 -1
  66. package/dist/src/audio.d.ts.map +1 -1
  67. package/dist/src/audio.js +126 -24
  68. package/dist/src/audio.js.map +1 -1
  69. package/dist/src/autoZoom.d.ts.map +1 -1
  70. package/dist/src/autoZoom.js +3 -1
  71. package/dist/src/autoZoom.js.map +1 -1
  72. package/dist/src/browserLaunchOptions.d.ts +24 -2
  73. package/dist/src/browserLaunchOptions.d.ts.map +1 -1
  74. package/dist/src/browserLaunchOptions.js +57 -3
  75. package/dist/src/browserLaunchOptions.js.map +1 -1
  76. package/dist/src/builder.d.ts +229 -136
  77. package/dist/src/builder.d.ts.map +1 -1
  78. package/dist/src/builder.js +264 -77
  79. package/dist/src/builder.js.map +1 -1
  80. package/dist/src/callerFile.d.ts +12 -0
  81. package/dist/src/callerFile.d.ts.map +1 -0
  82. package/dist/src/callerFile.js +46 -0
  83. package/dist/src/callerFile.js.map +1 -0
  84. package/dist/src/changeFocus.d.ts.map +1 -1
  85. package/dist/src/changeFocus.js +109 -36
  86. package/dist/src/changeFocus.js.map +1 -1
  87. package/dist/src/config.d.ts.map +1 -1
  88. package/dist/src/config.js +15 -0
  89. package/dist/src/config.js.map +1 -1
  90. package/dist/src/cue.d.ts +29 -17
  91. package/dist/src/cue.d.ts.map +1 -1
  92. package/dist/src/cue.js +138 -61
  93. package/dist/src/cue.js.map +1 -1
  94. package/dist/src/declare.d.ts +63 -0
  95. package/dist/src/declare.d.ts.map +1 -0
  96. package/dist/src/declare.js +111 -0
  97. package/dist/src/declare.js.map +1 -0
  98. package/dist/src/defaults.d.ts +23 -0
  99. package/dist/src/defaults.d.ts.map +1 -1
  100. package/dist/src/defaults.js +27 -3
  101. package/dist/src/defaults.js.map +1 -1
  102. package/dist/src/events.d.ts +339 -25
  103. package/dist/src/events.d.ts.map +1 -1
  104. package/dist/src/events.js +250 -26
  105. package/dist/src/events.js.map +1 -1
  106. package/dist/src/htmlRasterizer.d.ts +10 -0
  107. package/dist/src/htmlRasterizer.d.ts.map +1 -1
  108. package/dist/src/htmlRasterizer.js +12 -2
  109. package/dist/src/htmlRasterizer.js.map +1 -1
  110. package/dist/src/init.d.ts +2 -0
  111. package/dist/src/init.d.ts.map +1 -1
  112. package/dist/src/init.js +81 -33
  113. package/dist/src/init.js.map +1 -1
  114. package/dist/src/instrument.d.ts.map +1 -1
  115. package/dist/src/instrument.js +164 -8
  116. package/dist/src/instrument.js.map +1 -1
  117. package/dist/src/locales.d.ts.map +1 -1
  118. package/dist/src/locales.js +1 -0
  119. package/dist/src/locales.js.map +1 -1
  120. package/dist/src/localize.d.ts +26 -17
  121. package/dist/src/localize.d.ts.map +1 -1
  122. package/dist/src/localize.js +19 -11
  123. package/dist/src/localize.js.map +1 -1
  124. package/dist/src/localizeRuntime.d.ts +29 -33
  125. package/dist/src/localizeRuntime.d.ts.map +1 -1
  126. package/dist/src/localizeRuntime.js +74 -49
  127. package/dist/src/localizeRuntime.js.map +1 -1
  128. package/dist/src/logger.d.ts +5 -0
  129. package/dist/src/logger.d.ts.map +1 -1
  130. package/dist/src/logger.js +7 -0
  131. package/dist/src/logger.js.map +1 -1
  132. package/dist/src/manualZoom.d.ts.map +1 -1
  133. package/dist/src/manualZoom.js +8 -5
  134. package/dist/src/manualZoom.js.map +1 -1
  135. package/dist/src/narrationVisibility.d.ts +19 -0
  136. package/dist/src/narrationVisibility.d.ts.map +1 -0
  137. package/dist/src/narrationVisibility.js +26 -0
  138. package/dist/src/narrationVisibility.js.map +1 -0
  139. package/dist/src/openBrowser.d.ts +34 -0
  140. package/dist/src/openBrowser.d.ts.map +1 -0
  141. package/dist/src/openBrowser.js +62 -0
  142. package/dist/src/openBrowser.js.map +1 -0
  143. package/dist/src/recordingData.d.ts +27 -0
  144. package/dist/src/recordingData.d.ts.map +1 -1
  145. package/dist/src/recordingSize.d.ts +32 -0
  146. package/dist/src/recordingSize.d.ts.map +1 -0
  147. package/dist/src/recordingSize.js +54 -0
  148. package/dist/src/recordingSize.js.map +1 -0
  149. package/dist/src/redact.d.ts +68 -0
  150. package/dist/src/redact.d.ts.map +1 -0
  151. package/dist/src/redact.js +138 -0
  152. package/dist/src/redact.js.map +1 -0
  153. package/dist/src/redactController.d.ts +61 -0
  154. package/dist/src/redactController.d.ts.map +1 -0
  155. package/dist/src/redactController.js +232 -0
  156. package/dist/src/redactController.js.map +1 -0
  157. package/dist/src/runtimeContext.d.ts +32 -0
  158. package/dist/src/runtimeContext.d.ts.map +1 -1
  159. package/dist/src/runtimeContext.js +21 -0
  160. package/dist/src/runtimeContext.js.map +1 -1
  161. package/dist/src/runtimeMode.d.ts +15 -7
  162. package/dist/src/runtimeMode.d.ts.map +1 -1
  163. package/dist/src/runtimeMode.js +17 -6
  164. package/dist/src/runtimeMode.js.map +1 -1
  165. package/dist/src/screenAudio.d.ts +88 -0
  166. package/dist/src/screenAudio.d.ts.map +1 -0
  167. package/dist/src/screenAudio.js +0 -0
  168. package/dist/src/screenAudio.js.map +1 -0
  169. package/dist/src/screenAudioSink.d.ts +46 -0
  170. package/dist/src/screenAudioSink.d.ts.map +1 -0
  171. package/dist/src/screenAudioSink.js +77 -0
  172. package/dist/src/screenAudioSink.js.map +1 -0
  173. package/dist/src/screenshot.d.ts +27 -29
  174. package/dist/src/screenshot.d.ts.map +1 -1
  175. package/dist/src/screenshot.js +39 -24
  176. package/dist/src/screenshot.js.map +1 -1
  177. package/dist/src/sourceTrim.d.ts +29 -0
  178. package/dist/src/sourceTrim.d.ts.map +1 -0
  179. package/dist/src/sourceTrim.js +76 -0
  180. package/dist/src/sourceTrim.js.map +1 -0
  181. package/dist/src/stillCapture.d.ts +5 -0
  182. package/dist/src/stillCapture.d.ts.map +1 -1
  183. package/dist/src/stillCapture.js +11 -1
  184. package/dist/src/stillCapture.js.map +1 -1
  185. package/dist/src/studio.d.ts +69 -57
  186. package/dist/src/studio.d.ts.map +1 -1
  187. package/dist/src/studio.js +16 -38
  188. package/dist/src/studio.js.map +1 -1
  189. package/dist/src/timelineOffset.d.ts +46 -0
  190. package/dist/src/timelineOffset.d.ts.map +1 -0
  191. package/dist/src/timelineOffset.js +66 -0
  192. package/dist/src/timelineOffset.js.map +1 -0
  193. package/dist/src/titleValidation.d.ts +38 -0
  194. package/dist/src/titleValidation.d.ts.map +1 -1
  195. package/dist/src/titleValidation.js +42 -0
  196. package/dist/src/titleValidation.js.map +1 -1
  197. package/dist/src/types.d.ts +218 -2
  198. package/dist/src/types.d.ts.map +1 -1
  199. package/dist/src/types.js +1 -1
  200. package/dist/src/types.js.map +1 -1
  201. package/dist/src/video.d.ts +74 -60
  202. package/dist/src/video.d.ts.map +1 -1
  203. package/dist/src/video.js +201 -39
  204. package/dist/src/video.js.map +1 -1
  205. package/dist/src/voiceSampleAudio.d.ts +34 -0
  206. package/dist/src/voiceSampleAudio.d.ts.map +1 -0
  207. package/dist/src/voiceSampleAudio.js +105 -0
  208. package/dist/src/voiceSampleAudio.js.map +1 -0
  209. package/dist/src/voices.d.ts +2 -2
  210. package/dist/src/voices.d.ts.map +1 -1
  211. package/dist/src/voices.js +8 -3
  212. package/dist/src/voices.js.map +1 -1
  213. package/dist/src/zoom.d.ts +1 -0
  214. package/dist/src/zoom.d.ts.map +1 -1
  215. package/dist/src/zoom.js +3 -0
  216. package/dist/src/zoom.js.map +1 -1
  217. package/dist/tsconfig.tsbuildinfo +1 -1
  218. package/package.json +3 -2
  219. package/skills/screenci/SKILL.md +2 -2
  220. package/skills/screenci/references/init.md +4 -3
  221. package/skills/screenci/references/record.md +1 -1
  222. package/templates/recordings/assets/logo.png +0 -0
  223. package/dist/docs/video-sources/public-urls.screenci.d.ts +0 -2
  224. package/dist/docs/video-sources/public-urls.screenci.d.ts.map +0 -1
  225. package/dist/docs/video-sources/public-urls.screenci.js +0 -41
  226. package/dist/docs/video-sources/public-urls.screenci.js.map +0 -1
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A dedicated PulseAudio/PipeWire null sink created for one recording worker.
3
+ * The worker's browser is routed into `sinkName` (so its audio is silent on the
4
+ * host and isolated from other apps), and the recorder captures `monitorSource`.
5
+ */
6
+ export type NullSink = {
7
+ /** `pactl` module id, used to unload the sink on teardown. */
8
+ moduleId: string;
9
+ /** Sink name the browser plays into (via `PULSE_SINK`). */
10
+ sinkName: string;
11
+ /** Monitor source the recorder captures (`<sinkName>.monitor`). */
12
+ monitorSource: string;
13
+ };
14
+ /** @internal - injected in tests */
15
+ export type SinkDeps = {
16
+ run: (cmd: string, args: string[]) => Promise<{
17
+ stdout: string;
18
+ }>;
19
+ };
20
+ /**
21
+ * Deterministic, per-process sink name. Each Playwright worker is its own
22
+ * process with a unique pid, so this gives one sink per worker that is trivial
23
+ * to clean up and cannot collide with a concurrent worker.
24
+ */
25
+ export declare function workerSinkName(pid?: number): string;
26
+ /**
27
+ * Creates a null sink via `pactl load-module module-null-sink`. Returns the
28
+ * parsed module id and sink/monitor names, or `null` when `pactl` is missing or
29
+ * the command fails (callers fall back to the default device and warn).
30
+ */
31
+ export declare function createNullSink(name?: string, deps?: SinkDeps): Promise<NullSink | null>;
32
+ /**
33
+ * Verifies that screen-audio capture can actually run on this machine: the
34
+ * `pactl` control tool is in PATH and a PulseAudio-compatible server is
35
+ * reachable. Throws an actionable error otherwise, so captureAudio fails fast
36
+ * instead of producing a recording that silently lacks the isolated audio it
37
+ * promises.
38
+ *
39
+ * Only `pactl` plus a running pulse server are required. The `pulseaudio` daemon
40
+ * binary itself is NOT needed: PipeWire systems provide the pulse server and
41
+ * `pactl` (via pipewire-pulse) without it, and capture works there.
42
+ */
43
+ export declare function assertScreenAudioCaptureReady(deps?: SinkDeps): Promise<void>;
44
+ /** Unloads a previously created null sink. Best effort: never throws. */
45
+ export declare function unloadNullSink(sink: NullSink, deps?: SinkDeps): Promise<void>;
46
+ //# sourceMappingURL=screenAudioSink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenAudioSink.d.ts","sourceRoot":"","sources":["../../src/screenAudioSink.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAA;IAChB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,oCAAoC;AACpC,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAClE,CAAA;AAMD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAoB,GAAG,MAAM,CAEhE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,GAAE,MAAyB,EAC/B,IAAI,GAAE,QAAsB,GAC3B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAgB1B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,GAAE,QAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,yEAAyE;AACzE,wBAAsB,cAAc,CAClC,IAAI,EAAE,QAAQ,EACd,IAAI,GAAE,QAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -0,0 +1,77 @@
1
+ import { execFile as nodeExecFile } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { SCREEN_AUDIO_DOCS_URL } from './screenAudio.js';
4
+ const execFileAsync = promisify(nodeExecFile);
5
+ const defaultDeps = {
6
+ run: (cmd, args) => execFileAsync(cmd, args),
7
+ };
8
+ /**
9
+ * Deterministic, per-process sink name. Each Playwright worker is its own
10
+ * process with a unique pid, so this gives one sink per worker that is trivial
11
+ * to clean up and cannot collide with a concurrent worker.
12
+ */
13
+ export function workerSinkName(pid = process.pid) {
14
+ return `screenci_${pid}`;
15
+ }
16
+ /**
17
+ * Creates a null sink via `pactl load-module module-null-sink`. Returns the
18
+ * parsed module id and sink/monitor names, or `null` when `pactl` is missing or
19
+ * the command fails (callers fall back to the default device and warn).
20
+ */
21
+ export async function createNullSink(name = workerSinkName(), deps = defaultDeps) {
22
+ try {
23
+ const { stdout } = await deps.run('pactl', [
24
+ 'load-module',
25
+ 'module-null-sink',
26
+ `sink_name=${name}`,
27
+ `sink_properties=device.description=${name}`,
28
+ ]);
29
+ const moduleId = stdout.trim();
30
+ if (!/^\d+$/.test(moduleId)) {
31
+ return null;
32
+ }
33
+ return { moduleId, sinkName: name, monitorSource: `${name}.monitor` };
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * Verifies that screen-audio capture can actually run on this machine: the
41
+ * `pactl` control tool is in PATH and a PulseAudio-compatible server is
42
+ * reachable. Throws an actionable error otherwise, so captureAudio fails fast
43
+ * instead of producing a recording that silently lacks the isolated audio it
44
+ * promises.
45
+ *
46
+ * Only `pactl` plus a running pulse server are required. The `pulseaudio` daemon
47
+ * binary itself is NOT needed: PipeWire systems provide the pulse server and
48
+ * `pactl` (via pipewire-pulse) without it, and capture works there.
49
+ */
50
+ export async function assertScreenAudioCaptureReady(deps = defaultDeps) {
51
+ try {
52
+ await deps.run('pactl', ['--version']);
53
+ }
54
+ catch {
55
+ throw new Error(`[screenci] captureAudio: "pactl" is not installed or not in PATH. ` +
56
+ `Install "pulseaudio-utils" (or "pipewire-pulse") and try again. ` +
57
+ `See ${SCREEN_AUDIO_DOCS_URL} for setup instructions.`);
58
+ }
59
+ try {
60
+ await deps.run('pactl', ['info']);
61
+ }
62
+ catch {
63
+ throw new Error(`[screenci] captureAudio: no PulseAudio/PipeWire server is reachable ` +
64
+ `(\`pactl info\` failed). Start one (for example "pulseaudio --start") ` +
65
+ `and try again. See ${SCREEN_AUDIO_DOCS_URL} for setup instructions.`);
66
+ }
67
+ }
68
+ /** Unloads a previously created null sink. Best effort: never throws. */
69
+ export async function unloadNullSink(sink, deps = defaultDeps) {
70
+ try {
71
+ await deps.run('pactl', ['unload-module', sink.moduleId]);
72
+ }
73
+ catch {
74
+ // Best effort: the server may already be gone (e.g. on shutdown).
75
+ }
76
+ }
77
+ //# sourceMappingURL=screenAudioSink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenAudioSink.js","sourceRoot":"","sources":["../../src/screenAudioSink.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAExD,MAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;AAqB7C,MAAM,WAAW,GAAa;IAC5B,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC;CAC7C,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,OAAO,CAAC,GAAG;IACtD,OAAO,YAAY,GAAG,EAAE,CAAA;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAe,cAAc,EAAE,EAC/B,OAAiB,WAAW;IAE5B,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;YACzC,aAAa;YACb,kBAAkB;YAClB,aAAa,IAAI,EAAE;YACnB,sCAAsC,IAAI,EAAE;SAC7C,CAAC,CAAA;QACF,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;QAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,IAAI,UAAU,EAAE,CAAA;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAiB,WAAW;IAE5B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,oEAAoE;YAClE,kEAAkE;YAClE,OAAO,qBAAqB,0BAA0B,CACzD,CAAA;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,sEAAsE;YACpE,wEAAwE;YACxE,sBAAsB,qBAAqB,0BAA0B,CACxE,CAAA;IACH,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAc,EACd,OAAiB,WAAW;IAE5B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;AACH,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import type { TestType, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestDetails, TestInfo } from '@playwright/test';
2
2
  import type { RecordOptions, RenderOptions, ScreenCIPage } from './types.js';
3
- import type { StudioDeclaration } from './studio.js';
4
- import { type OverlayController } from './asset.js';
3
+ import type { StudioMarker } from './studio.js';
4
+ import { type OverlayController, type OverlayInputOrFactory } from './asset.js';
5
5
  import type { CropTarget, CropOptions } from './crop.js';
6
- import type { VideoBuilder } from './builder.js';
7
- import type { NormalizedLocalize } from './localize.js';
8
- import { type TextValues } from './localizeRuntime.js';
6
+ import { type MediaBuilder } from './builder.js';
7
+ import type { NormalizedFeature } from './declare.js';
8
+ import { type Values } from './localizeRuntime.js';
9
9
  /**
10
10
  * The `crop` fixture argument. Call it inside a `screenshot()` body to crop the
11
11
  * implicit end-of-body capture to a locator or pixel region. Replaces the
@@ -13,21 +13,16 @@ import { type TextValues } from './localizeRuntime.js';
13
13
  */
14
14
  export type CropFixture = (target: CropTarget, options?: CropOptions) => Promise<void>;
15
15
  type ScreenshotFixtureOptions = {
16
- recordOptions: RecordOptions;
17
- renderOptions: RenderOptions | undefined;
16
+ recordOptions: RecordOptions | StudioMarker<Partial<RecordOptions>>;
17
+ renderOptions: RenderOptions | StudioMarker<Partial<RenderOptions>> | undefined;
18
18
  /** Active language for this pass; see {@link video} for details. Internal. */
19
19
  _screenciLanguage: string | undefined;
20
20
  /** Grouping name written to `metadata.videoName`. Internal. */
21
21
  _screenciVideoName: string | undefined;
22
- /** The normalized localize spec, set by `screenshot.localize(...)`. Internal. */
23
- _screenciLocalize: NormalizedLocalize | undefined;
24
- /**
25
- * The studio declaration, set by `screenshot.studio(...)`. Drives the
26
- * render/record deferral flags and the Studio-managed `text` and `overlays`
27
- * fixtures. A still is silent, so narration/audio declarations are ignored.
28
- * Internal.
29
- */
30
- _screenciStudio: StudioDeclaration | undefined;
22
+ /** Values-field declaration (`screenshot.values(...)`). Internal. */
23
+ _screenciValues: NormalizedFeature<string> | undefined;
24
+ /** Overlay declaration (`screenshot.overlays(...)`). Internal. */
25
+ _screenciOverlays: NormalizedFeature<OverlayInputOrFactory> | undefined;
31
26
  /**
32
27
  * Absolute path of the `.screenci` script that registered this test, captured
33
28
  * by the fan-out builder. Asset paths are resolved relative to it, since
@@ -40,16 +35,16 @@ type ScreenshotFixtures = {
40
35
  /** The language being captured in this pass; `undefined` outside per-language mode. */
41
36
  language: string | undefined;
42
37
  /**
43
- * Injected text field values for the active language, keyed by the field names
44
- * declared in `screenshot.localize(...)`. A still is silent, so there is no
38
+ * Injected values fields for the active language, keyed by the field names
39
+ * declared in `screenshot.values(...)`. A still is silent, so there is no
45
40
  * `narration` fixture.
46
41
  */
47
- text: TextValues;
42
+ values: Values;
48
43
  /**
49
- * Overlay controllers for the Studio-managed overlay names declared in
50
- * `screenshot.studio({ overlays: [...] })`. Empty when none are declared.
44
+ * Overlay controllers for the names declared in `screenshot.overlays(...)`.
45
+ * Empty when none are declared.
51
46
  */
52
- overlays: Record<string, OverlayController>;
47
+ overlays: Record<string, OverlayController | ((props: unknown) => OverlayController)>;
53
48
  };
54
49
  type ScreenshotType = TestType<PlaywrightTestArgs & PlaywrightTestOptions & ScreenshotFixtureOptions & ScreenshotFixtures & PlaywrightWorkerArgs & PlaywrightWorkerOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
55
50
  type ScreenshotArgs = Omit<PlaywrightTestArgs, 'page'> & {
@@ -99,21 +94,24 @@ interface Screenshot extends ScreenshotCallSignatures {
99
94
  /**
100
95
  * Capture one localized screenshot per declared language. By default each
101
96
  * language is captured in its own pass with the browser `locale` set from the
102
- * language, and the body receives the active `language` and `text` values.
97
+ * language, and the body receives the active `language` and `values` fields.
103
98
  * Chainable with `.each(...)`.
104
99
  */
105
- localize: VideoBuilder<ScreenshotArgs>['localize'];
100
+ /** Declare on-screen values fields (array = Studio-owned, object = code values). */
101
+ values: MediaBuilder<ScreenshotArgs>['values'];
102
+ /** Declare overlays (`studio([...])` = Studio-owned, object = code values/factories). */
103
+ overlays: MediaBuilder<ScreenshotArgs>['overlays'];
106
104
  /**
107
- * Defer render/record options and declare Studio-managed text and overlays,
108
- * configured in the ScreenCI web app. Stills are silent, so narration and
109
- * audio declarations are ignored. Chainable with `.localize(...)` / `.each(...)`.
105
+ * Declare the recorded language set / capture mode. Pass `studio()` to let the
106
+ * web app own the set (`studio(['en', 'fi'])` to seed it), an array
107
+ * `['en', 'fi']`, or an options object.
110
108
  */
111
- studio: VideoBuilder<ScreenshotArgs>['studio'];
109
+ languages: MediaBuilder<ScreenshotArgs>['languages'];
112
110
  /**
113
111
  * Produce a separate screenshot per variant (viewport, theme, ...). Each
114
112
  * variant has its own identity and history. Chainable with `.languages(...)`.
115
113
  */
116
- each: VideoBuilder<ScreenshotArgs>['each'];
114
+ each: MediaBuilder<ScreenshotArgs>['each'];
117
115
  beforeEach(inner: (args: ScreenshotArgs, testInfo: TestInfo) => Promise<void> | void): void;
118
116
  beforeEach(title: string, inner: (args: ScreenshotArgs, testInfo: TestInfo) => Promise<void> | void): void;
119
117
  afterEach(inner: (args: ScreenshotArgs, testInfo: TestInfo) => Promise<void> | void): void;
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,WAAW,EACX,QAAQ,EACT,MAAM,kBAAkB,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAmBxE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAQxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,sBAAsB,CAAA;AAG7B;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,WAAW,KAClB,OAAO,CAAC,IAAI,CAAC,CAAA;AAKlB,KAAK,wBAAwB,GAAG;IAC9B,aAAa,EAAE,aAAa,CAAA;IAC5B,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,8EAA8E;IAC9E,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,+DAA+D;IAC/D,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,iFAAiF;IACjF,iBAAiB,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACjD;;;;;OAKG;IACH,eAAe,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAC9C;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,WAAW,CAAA;IACjB,uFAAuF;IACvF,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B;;;;OAIG;IACH,IAAI,EAAE,UAAU,CAAA;IAChB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAC5C,CAAA;AAwRD,KAAK,cAAc,GAAG,QAAQ,CAC5B,kBAAkB,GAChB,qBAAqB,GACrB,wBAAwB,GACxB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,EACzB,oBAAoB,GAAG,uBAAuB,CAC/C,CAAA;AAED,KAAK,cAAc,GAAG,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG;IACvD,IAAI,EAAE,YAAY,CAAA;CACnB,GAAG,qBAAqB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,CAAA;AAEzB,KAAK,cAAc,GAAG,CACpB,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,QAAQ,KACf,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAEzB,0DAA0D;AAC1D,KAAK,oBAAoB,GAAG,CAAC,CAC3B,SAAS,CAAC,EAAE,OAAO,EACnB,WAAW,CAAC,EAAE,MAAM,KACjB,IAAI,CAAC,GACR,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC,CAAA;AAE1D,UAAU,wBAAwB;IAChC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;IAE3C;;;OAGG;IACH,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;CAClE;AAED;;;GAGG;AACH,UAAU,UAAW,SAAQ,wBAAwB;IACnD,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,UAAU,GAAG,oBAAoB,CAAA;IACvC,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAAA;IACxC,IAAI,EAAE,UAAU,GAAG,oBAAoB,CAAA;IACvC,IAAI,EAAE,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,CAAA;IAExE;;;;;OAKG;IACH,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,CAAA;IAElD;;;;OAIG;IACH,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAA;IAE9C;;;OAGG;IACH,IAAI,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;IAE1C,UAAU,CACR,KAAK,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACxE,IAAI,CAAA;IACP,UAAU,CACR,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACxE,IAAI,CAAA;IACP,SAAS,CACP,KAAK,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACxE,IAAI,CAAA;IACP,SAAS,CACP,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACxE,IAAI,CAAA;IAEP,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACpC,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,CAAA;IACtC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACpC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAC5B,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAC5B,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,UAAU,EAAE,cAAc,CAAC,YAAY,CAAC,CAAA;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,UAAU,EAAiC,UAAU,CAAA"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/screenshot.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  import { test as base } from '@playwright/test';
2
2
  import { mkdir, rm } from 'fs/promises';
3
3
  import { join, relative } from 'path';
4
- import { studioOptionFlags } from './studio.js';
5
- import { buildStudioOverlays } from './asset.js';
4
+ import { buildOverlays, } from './asset.js';
6
5
  import { getDimensions } from './dimensions.js';
7
6
  import { DEFAULT_VIDEO_OPTIONS, DEFAULT_ASPECT_RATIO, DEFAULT_QUALITY, DEFAULT_SCREENSHOT_DEVICE_SCALE_FACTOR, } from './defaults.js';
8
7
  import { EventRecorder } from './events.js';
@@ -12,12 +11,13 @@ import { createScreenCIRuntimeContext } from './runtimeContext.js';
12
11
  import { escapeFileSystemPathSegment } from './fileSystemName.js';
13
12
  import { buildScreenCIContextOptions, resolveDeviceScaleFactor, } from './contextOptions.js';
14
13
  import { resolveCrop } from './crop.js';
14
+ import { getMousePosition } from './mouse.js';
15
15
  import { getRuntimePage, setRuntimeCrop } from './runtimeContext.js';
16
16
  import { ScreenciError } from './errors.js';
17
- import { withActiveRecordingContext, resolveEffectiveRecordOptions, } from './video.js';
18
- import { createVideoBuilder } from './builder.js';
19
- import { buildTextDeclaration, buildTextValues, } from './localizeRuntime.js';
20
- import { parseTextOverrides } from './runtimeMode.js';
17
+ import { withActiveRecordingContext, resolveEffectiveRecordOptions, resolveStudioRecordOptions, resolveStudioRenderOptions, } from './video.js';
18
+ import { createVideoBuilder, SCREENSHOT_FEATURES, } from './builder.js';
19
+ import { buildValuesDeclaration, buildValues, } from './localizeRuntime.js';
20
+ import { parseValuesOverrides } from './runtimeMode.js';
21
21
  /** File name of the raw page capture written beside `data.json`. */
22
22
  const SCREENSHOT_FILE_NAME = 'screenshot.png';
23
23
  const _screenshotBase = base.extend({
@@ -25,17 +25,17 @@ const _screenshotBase = base.extend({
25
25
  renderOptions: [undefined, { option: true }],
26
26
  _screenciLanguage: [undefined, { option: true }],
27
27
  _screenciVideoName: [undefined, { option: true }],
28
- _screenciLocalize: [undefined, { option: true }],
29
- _screenciStudio: [undefined, { option: true }],
28
+ _screenciValues: [undefined, { option: true }],
29
+ _screenciOverlays: [undefined, { option: true }],
30
30
  _screenciSourceFile: [undefined, { option: true }],
31
31
  language: async ({ _screenciLanguage }, use) => {
32
32
  await use(_screenciLanguage);
33
33
  },
34
- text: async ({ _screenciLocalize, _screenciStudio, _screenciLanguage }, use) => {
35
- await use(buildTextValues(_screenciLocalize, _screenciLanguage, parseTextOverrides(), _screenciStudio?.text ?? []));
34
+ values: async ({ _screenciValues, _screenciLanguage }, use) => {
35
+ await use(buildValues(_screenciValues, _screenciLanguage, parseValuesOverrides()));
36
36
  },
37
- overlays: async ({ _screenciStudio }, use) => {
38
- await use(buildStudioOverlays(_screenciStudio?.overlays ?? []));
37
+ overlays: async ({ _screenciOverlays, _screenciLanguage }, use) => {
38
+ await use(buildOverlays(_screenciOverlays, _screenciLanguage));
39
39
  },
40
40
  crop: async ({}, use) => {
41
41
  await use(async (target, options) => {
@@ -56,8 +56,9 @@ const _screenshotBase = base.extend({
56
56
  await browser.close();
57
57
  }
58
58
  },
59
- context: async ({ browser, recordOptions, _screenciStudio, _screenciVideoName, colorScheme, locale, timezoneId, userAgent, geolocation, permissions, extraHTTPHeaders, httpCredentials, ignoreHTTPSErrors, offline, storageState, baseURL, bypassCSP, acceptDownloads, javaScriptEnabled, hasTouch, isMobile, deviceScaleFactor, }, use, testInfo) => {
60
- const effectiveRecordOptions = resolveEffectiveRecordOptions(recordOptions, _screenciStudio, _screenciVideoName ?? testInfo.title);
59
+ context: async ({ browser, recordOptions, _screenciVideoName, colorScheme, locale, timezoneId, userAgent, geolocation, permissions, extraHTTPHeaders, httpCredentials, ignoreHTTPSErrors, offline, storageState, baseURL, bypassCSP, acceptDownloads, javaScriptEnabled, hasTouch, isMobile, deviceScaleFactor, }, use, testInfo) => {
60
+ const { base: baseRecordOptions, studio: studioRecord } = resolveStudioRecordOptions(recordOptions);
61
+ const effectiveRecordOptions = resolveEffectiveRecordOptions(baseRecordOptions, studioRecord, _screenciVideoName ?? testInfo.title);
61
62
  const aspectRatio = effectiveRecordOptions.aspectRatio ?? DEFAULT_ASPECT_RATIO;
62
63
  const quality = effectiveRecordOptions.quality ?? DEFAULT_QUALITY;
63
64
  const dimensions = getDimensions(aspectRatio, quality);
@@ -95,14 +96,19 @@ const _screenshotBase = base.extend({
95
96
  await context.close();
96
97
  }
97
98
  },
98
- page: async ({ context, recordOptions: codeRecordOptions, renderOptions, deviceScaleFactor, _screenciLanguage, _screenciLocalize, _screenciStudio, _screenciVideoName, _screenciSourceFile, }, use, testInfo) => {
99
+ page: async ({ context, recordOptions: codeRecordOptions, renderOptions, deviceScaleFactor, _screenciLanguage, _screenciValues, _screenciVideoName, _screenciSourceFile, }, use, testInfo) => {
99
100
  const shouldRecord = process.env.SCREENCI_RECORDING === 'true';
100
- const recordOptions = resolveEffectiveRecordOptions(codeRecordOptions, _screenciStudio, _screenciVideoName ?? testInfo.title);
101
- const recorder = new EventRecorder(renderOptions, recordOptions, studioOptionFlags(_screenciStudio));
101
+ const { base: baseRecordOptions, studio: studioRecord } = resolveStudioRecordOptions(codeRecordOptions);
102
+ const { obj: renderOptionsObj, studio: studioRender } = resolveStudioRenderOptions(renderOptions);
103
+ const recordOptions = resolveEffectiveRecordOptions(baseRecordOptions, studioRecord, _screenciVideoName ?? testInfo.title);
104
+ const recorder = new EventRecorder(renderOptionsObj, recordOptions, {
105
+ renderOptions: studioRender,
106
+ recordOptions: studioRecord,
107
+ });
102
108
  recorder.setActiveLanguage(_screenciLanguage ?? null);
103
- // Declared `text` fields (and the active language's seeds) emitted once at
109
+ // Declared `values` fields (and the active language's seeds) emitted once at
104
110
  // recording start so the backend/Studio learn them.
105
- const textDeclaration = buildTextDeclaration(_screenciLocalize, _screenciLanguage, _screenciStudio?.text ?? []);
111
+ const valuesDeclaration = buildValuesDeclaration(_screenciValues, _screenciLanguage);
106
112
  const videoName = _screenciVideoName ?? testInfo.title;
107
113
  // Asset paths are authored relative to the user's script. Playwright reports
108
114
  // `testInfo.file` as the builder module that registered the test, so prefer
@@ -123,7 +129,7 @@ const _screenshotBase = base.extend({
123
129
  page,
124
130
  recorder,
125
131
  unendedOverlays: 'autoEnd',
126
- textDeclaration,
132
+ valuesDeclaration,
127
133
  fn: async () => {
128
134
  await use(page);
129
135
  },
@@ -160,7 +166,7 @@ const _screenshotBase = base.extend({
160
166
  page,
161
167
  recorder,
162
168
  unendedOverlays: 'autoEnd',
163
- textDeclaration,
169
+ valuesDeclaration,
164
170
  fn: async () => {
165
171
  await use(page);
166
172
  },
@@ -172,11 +178,19 @@ const _screenshotBase = base.extend({
172
178
  path: join(screenshotDir, SCREENSHOT_FILE_NAME),
173
179
  });
174
180
  const crop = runtimeContext.crop ?? undefined;
181
+ // The cursor lands at its final position even for a still (the move is
182
+ // instant). Record it so the renderer can draw the cursor on the still
183
+ // when `renderOptions.screenshot.mouse.show` is set. Absent when the body
184
+ // never moved the cursor, so no cursor is ever shown for such a still.
185
+ const mousePosition = getMousePosition(page);
175
186
  const screenshot = {
176
187
  path: SCREENSHOT_FILE_NAME,
177
188
  width: Math.round(dimensions.width * dsf),
178
189
  height: Math.round(dimensions.height * dsf),
179
190
  deviceScaleFactor: dsf,
191
+ ...(mousePosition !== undefined && {
192
+ mousePosition: { x: mousePosition.x, y: mousePosition.y },
193
+ }),
180
194
  };
181
195
  const configDir = process.env.SCREENCI_CONFIG_DIR ?? process.cwd();
182
196
  // The crop (from the `crop` fixture) is a render option, so it goes into
@@ -220,8 +234,9 @@ const _screenshotBase = base.extend({
220
234
  */
221
235
  export const screenshot = _screenshotBase;
222
236
  // Attach the chainable fan-out builders, mirroring `video`.
223
- const _screenshotRootBuilder = createVideoBuilder(_screenshotBase);
224
- screenshot.localize = _screenshotRootBuilder.localize;
225
- screenshot.studio = _screenshotRootBuilder.studio;
237
+ const _screenshotRootBuilder = createVideoBuilder(_screenshotBase, SCREENSHOT_FEATURES);
238
+ screenshot.values = _screenshotRootBuilder.values;
239
+ screenshot.overlays = _screenshotRootBuilder.overlays;
240
+ screenshot.languages = _screenshotRootBuilder.languages;
226
241
  screenshot.each = _screenshotRootBuilder.each;
227
242
  //# sourceMappingURL=screenshot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/screenshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAU/C,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAGrC,OAAO,EACL,aAAa,GAGd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,sCAAsC,GACvC,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,sBAAsB,EACtB,WAAW,GAEZ,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAYvD,oEAAoE;AACpE,MAAM,oBAAoB,GAAG,gBAAgB,CAAA;AA4C7C,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAEjC;IACA,aAAa,EAAE,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACxD,aAAa,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5C,iBAAiB,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACjD,eAAe,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC9C,iBAAiB,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAChD,mBAAmB,EAAE,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAElD,QAAQ,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,EAAE,GAAG,EAAE,EAAE;QAC7C,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,EAAE,eAAe,EAAE,iBAAiB,EAAE,EAAE,GAAG,EAAE,EAAE;QAC5D,MAAM,GAAG,CACP,WAAW,CAAC,eAAe,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,CAAC,CACxE,CAAA;IACH,CAAC;IAED,QAAQ,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,EAAE,GAAG,EAAE,EAAE;QAChE,MAAM,GAAG,CAAC,aAAa,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;QACtB,MAAM,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,cAAc,EAAE,CAAA;YAC7B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,IAAI,aAAa,CACrB,8EAA8E,CAC/E,CAAA;YACH,CAAC;YACD,cAAc,CAAC,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE;QACrC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAA;QAC9D,MAAM,aAAa,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAA;QAE5D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAC/D,iBAAiB,CAAC,OAAO,CAAC,CAAA;QAC1B,MAAM,GAAG,CAAC,OAAO,CAAC,CAAA;QAClB,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAC1B,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EACZ,EACE,OAAO,EACP,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,OAAO,EACP,YAAY,EACZ,OAAO,EACP,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,iBAAiB,GAClB,EACD,GAAG,EACH,QAAQ,EACR,EAAE;QACF,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,EAAE,GACrD,0BAA0B,CAAC,aAAa,CAAC,CAAA;QAC3C,MAAM,sBAAsB,GAAG,6BAA6B,CAC1D,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,IAAI,QAAQ,CAAC,KAAK,CACrC,CAAA;QACD,MAAM,WAAW,GACf,sBAAsB,CAAC,WAAW,IAAI,oBAAoB,CAAA;QAC5D,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,IAAI,eAAe,CAAA;QACjE,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QACtD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAA;QAE9D,6DAA6D;QAC7D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,2BAA2B,CAAC;YAC1B,UAAU;YACV,kBAAkB,EAAE,YAAY;YAChC,iBAAiB,EAAE,wBAAwB,CACzC,sBAAsB,EACtB,iBAAiB,EACjB,sCAAsC,CACvC;YACD,SAAS,EAAE;gBACT,WAAW;gBACX,MAAM;gBACN,UAAU;gBACV,SAAS;gBACT,WAAW;gBACX,WAAW;gBACX,gBAAgB;gBAChB,eAAe;gBACf,iBAAiB;gBACjB,OAAO;gBACP,YAAY;gBACZ,OAAO;gBACP,SAAS;gBACT,eAAe;gBACf,iBAAiB;gBACjB,QAAQ;gBACR,QAAQ;aACT;SACF,CAAC,CACH,CAAA;QAED,iBAAiB,CAAC,OAAO,CAAC,CAAA;QAE1B,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,OAAO,CAAC,CAAA;QACpB,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;IACH,CAAC;IAED,IAAI,EAAE,KAAK,EACT,EACE,OAAO,EACP,aAAa,EAAE,iBAAiB,EAChC,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,GACpB,EACD,GAAG,EACH,QAAQ,EACR,EAAE;QACF,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAA;QAC9D,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,EAAE,GACrD,0BAA0B,CAAC,iBAAiB,CAAC,CAAA;QAC/C,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,EAAE,GACnD,0BAA0B,CAAC,aAAa,CAAC,CAAA;QAC3C,MAAM,aAAa,GAAG,6BAA6B,CACjD,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,IAAI,QAAQ,CAAC,KAAK,CACrC,CAAA;QACD,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,gBAAgB,EAAE,aAAa,EAAE;YAClE,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,YAAY;SAC5B,CAAC,CAAA;QACF,QAAQ,CAAC,iBAAiB,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAAA;QACrD,6EAA6E;QAC7E,oDAAoD;QACpD,MAAM,iBAAiB,GAAG,sBAAsB,CAC9C,eAAe,EACf,iBAAiB,CAClB,CAAA;QACD,MAAM,SAAS,GAAG,kBAAkB,IAAI,QAAQ,CAAC,KAAK,CAAA;QACtD,6EAA6E;QAC7E,4EAA4E;QAC5E,6CAA6C;QAC7C,MAAM,YAAY,GAAG,mBAAmB,IAAI,QAAQ,CAAC,IAAI,CAAA;QAEzD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,sEAAsE;YACtE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;YACpC,MAAM,cAAc,GAAG,4BAA4B,CAAC;gBAClD,QAAQ;gBACR,IAAI;gBACJ,YAAY;gBACZ,WAAW,EAAE,YAAY;aAC1B,CAAC,CAAA;YACF,QAAQ,CAAC,KAAK,EAAE,CAAA;YAChB,MAAM,0BAA0B,CAAC;gBAC/B,cAAc;gBACd,IAAI;gBACJ,QAAQ;gBACR,eAAe,EAAE,SAAS;gBAC1B,iBAAiB;gBACjB,EAAE,EAAE,KAAK,IAAI,EAAE;oBACb,MAAM,GAAG,CAAC,IAAI,CAAC,CAAA;gBACjB,CAAC;aACF,CAAC,CAAA;YACF,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;YAClB,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,aAAa,CAAC,WAAW,IAAI,oBAAoB,CAAA;QACrE,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,eAAe,CAAA;QACxD,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QACtD,MAAM,GAAG,GAAG,wBAAwB,CAClC,aAAa,EACb,iBAAiB,EACjB,sCAAsC,CACvC,CAAA;QAED,MAAM,aAAa,GAAG,2BAA2B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACjE,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;QAErE,eAAe;QACf,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;QACD,MAAM,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAE/C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;QACpC,MAAM,cAAc,GAAG,4BAA4B,CAAC;YAClD,QAAQ;YACR,IAAI;YACJ,YAAY;YACZ,YAAY,EAAE,aAAa;YAC3B,WAAW,EAAE,YAAY;SAC1B,CAAC,CAAA;QAEF,QAAQ,CAAC,KAAK,EAAE,CAAA;QAEhB,IAAI,CAAC;YACH,MAAM,0BAA0B,CAAC;gBAC/B,cAAc;gBACd,IAAI;gBACJ,QAAQ;gBACR,eAAe,EAAE,SAAS;gBAC1B,iBAAiB;gBACjB,EAAE,EAAE,KAAK,IAAI,EAAE;oBACb,MAAM,GAAG,CAAC,IAAI,CAAC,CAAA;gBACjB,CAAC;aACF,CAAC,CAAA;YAEF,2EAA2E;YAC3E,0EAA0E;YAC1E,kDAAkD;YAClD,MAAM,IAAI,CAAC,UAAU,CAAC;gBACpB,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC;aAChD,CAAC,CAAA;YAEF,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,IAAI,SAAS,CAAA;YAC7C,uEAAuE;YACvE,uEAAuE;YACvE,0EAA0E;YAC1E,uEAAuE;YACvE,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;YAC5C,MAAM,UAAU,GAAmB;gBACjC,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC;gBACzC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC;gBAC3C,iBAAiB,EAAE,GAAG;gBACtB,GAAG,CAAC,aAAa,KAAK,SAAS,IAAI;oBACjC,aAAa,EAAE,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE;iBAC1D,CAAC;aACH,CAAA;YAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;YAClE,yEAAyE;YACzE,0EAA0E;YAC1E,MAAM,QAAQ,CAAC,WAAW,CACxB,aAAa,EACb,SAAS,EACT,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC,EACjC;gBACE,MAAM,EAAE,YAAY;gBACpB,UAAU;gBACV,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC;aACpC,CACF,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC;IACH,CAAC;CACF,CAAC,CAAA;AA4HF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,eAAwC,CAAA;AAElE,4DAA4D;AAC5D,MAAM,sBAAsB,GAAG,kBAAkB,CAC/C,eAAsE,EACtE,mBAAmB,CACpB,CAAA;AACD,UAAU,CAAC,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAA;AACjD,UAAU,CAAC,QAAQ,GAAG,sBAAsB,CAAC,QAAQ,CAAA;AACrD,UAAU,CAAC,SAAS,GAAG,sBAAsB,CAAC,SAAS,CAAA;AACvD,UAAU,CAAC,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared validation and parsing for the source `crop` rectangle and the
3
+ * `start`/`end` source-trim positions accepted by file overlays, narration video
4
+ * cues, and `selected()` render dependencies.
5
+ *
6
+ * `crop` is a rectangle in the source file's own pixels. `start`/`end` are time
7
+ * strings (`'2s'`, `'0:02'`, `'50%'`): seconds/timecodes resolve to a concrete ms
8
+ * offset into the source, while a percentage stays symbolic (a fraction of the
9
+ * SOURCE duration) because the source length is not known until render time.
10
+ */
11
+ import { type TimelineOffset } from './timelineOffset.js';
12
+ import type { OverlayCrop, SourceTrimPoint } from './events.js';
13
+ /**
14
+ * Validates a {@link OverlayCrop}: every field finite, `x`/`y` non-negative, and
15
+ * `width`/`height` strictly positive. Returns the crop unchanged so callers can
16
+ * thread it inline.
17
+ */
18
+ export declare function validateCrop(label: string, crop: OverlayCrop): OverlayCrop;
19
+ /**
20
+ * Parses and validates the optional `start`/`end` source-trim pair. When both are
21
+ * concrete (ms or percent), `start` must come before `end`; a mixed ms/percent
22
+ * pair cannot be compared here (the source length is unknown) and is deferred to
23
+ * the renderer. Returns the parsed points to thread onto the recorded event.
24
+ */
25
+ export declare function resolveSourceTrim(label: string, start: TimelineOffset | undefined, end: TimelineOffset | undefined): {
26
+ sourceStart?: SourceTrimPoint;
27
+ sourceEnd?: SourceTrimPoint;
28
+ };
29
+ //# sourceMappingURL=sourceTrim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceTrim.d.ts","sourceRoot":"","sources":["../../src/sourceTrim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE/D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,CAgB1E;AA2BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,cAAc,GAAG,SAAS,EACjC,GAAG,EAAE,cAAc,GAAG,SAAS,GAC9B;IAAE,WAAW,CAAC,EAAE,eAAe,CAAC;IAAC,SAAS,CAAC,EAAE,eAAe,CAAA;CAAE,CAiChE"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Shared validation and parsing for the source `crop` rectangle and the
3
+ * `start`/`end` source-trim positions accepted by file overlays, narration video
4
+ * cues, and `selected()` render dependencies.
5
+ *
6
+ * `crop` is a rectangle in the source file's own pixels. `start`/`end` are time
7
+ * strings (`'2s'`, `'0:02'`, `'50%'`): seconds/timecodes resolve to a concrete ms
8
+ * offset into the source, while a percentage stays symbolic (a fraction of the
9
+ * SOURCE duration) because the source length is not known until render time.
10
+ */
11
+ import { parseTimelineOffset } from './timelineOffset.js';
12
+ /**
13
+ * Validates a {@link OverlayCrop}: every field finite, `x`/`y` non-negative, and
14
+ * `width`/`height` strictly positive. Returns the crop unchanged so callers can
15
+ * thread it inline.
16
+ */
17
+ export function validateCrop(label, crop) {
18
+ const { x, y, width, height } = crop;
19
+ const finite = (v) => typeof v === 'number' && Number.isFinite(v);
20
+ if (!finite(x) || !finite(y) || !finite(width) || !finite(height)) {
21
+ throw new Error(`[screenci] ${label} crop must have finite numeric x, y, width, and height (source pixels). Received: ${JSON.stringify(crop)}`);
22
+ }
23
+ if (x < 0 || y < 0) {
24
+ throw new Error(`[screenci] ${label} crop x and y must be >= 0.`);
25
+ }
26
+ if (width <= 0 || height <= 0) {
27
+ throw new Error(`[screenci] ${label} crop width and height must be > 0.`);
28
+ }
29
+ return crop;
30
+ }
31
+ /** Parses a single `start`/`end` time string into a {@link SourceTrimPoint}. */
32
+ function parseSourceTrimPoint(value, label) {
33
+ if (typeof value !== 'string') {
34
+ throw new Error(`[screenci] ${label} must be a time string such as '2s', '0:02', or '50%', got ${typeof value}.`);
35
+ }
36
+ const parsed = parseTimelineOffset(value);
37
+ if (parsed.kind === 'percent') {
38
+ if (parsed.fraction <= 0 || parsed.fraction > 1) {
39
+ throw new Error(`[screenci] ${label} percentage must be greater than 0% and at most 100%. Received: '${value}'.`);
40
+ }
41
+ return { percent: parsed.fraction };
42
+ }
43
+ if (parsed.ms < 0) {
44
+ throw new Error(`[screenci] ${label} must be >= 0. Received: '${value}'.`);
45
+ }
46
+ return { ms: parsed.ms };
47
+ }
48
+ /**
49
+ * Parses and validates the optional `start`/`end` source-trim pair. When both are
50
+ * concrete (ms or percent), `start` must come before `end`; a mixed ms/percent
51
+ * pair cannot be compared here (the source length is unknown) and is deferred to
52
+ * the renderer. Returns the parsed points to thread onto the recorded event.
53
+ */
54
+ export function resolveSourceTrim(label, start, end) {
55
+ const sourceStart = start !== undefined
56
+ ? parseSourceTrimPoint(start, `${label} start`)
57
+ : undefined;
58
+ const sourceEnd = end !== undefined ? parseSourceTrimPoint(end, `${label} end`) : undefined;
59
+ if (sourceStart !== undefined && sourceEnd !== undefined) {
60
+ if ('ms' in sourceStart &&
61
+ 'ms' in sourceEnd &&
62
+ sourceStart.ms >= sourceEnd.ms) {
63
+ throw new Error(`[screenci] ${label} start must be before end (got start ${start}, end ${end}).`);
64
+ }
65
+ if ('percent' in sourceStart &&
66
+ 'percent' in sourceEnd &&
67
+ sourceStart.percent >= sourceEnd.percent) {
68
+ throw new Error(`[screenci] ${label} start must be before end (got start ${start}, end ${end}).`);
69
+ }
70
+ }
71
+ return {
72
+ ...(sourceStart !== undefined && { sourceStart }),
73
+ ...(sourceEnd !== undefined && { sourceEnd }),
74
+ };
75
+ }
76
+ //# sourceMappingURL=sourceTrim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceTrim.js","sourceRoot":"","sources":["../../src/sourceTrim.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,11 @@ export declare function writeStillRecording(params: {
47
47
  };
48
48
  deviceScaleFactor: number;
49
49
  crop?: ScreenshotCropRecord;
50
+ /** Final cursor position in CSS px of the viewport, if the body moved it. */
51
+ mousePosition?: {
52
+ x: number;
53
+ y: number;
54
+ };
50
55
  testFilePath: string | null;
51
56
  configDir: string;
52
57
  recordOptions: RecordOptions | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"stillCapture.d.ts","sourceRoot":"","sources":["../../src/stillCapture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAI5C,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,aAAa,CAAA;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAOjE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK9D;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAQD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAChB,MAAM,CAqBR;AAED,kFAAkF;AAClF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gEAAgE;IAChE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7C,EAAE,CAAC,EAAE;QACH,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;QACnC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KACvC,CAAA;IACD,YAAY,CAAC,EAAE,CACb,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,aAAa,EAAE,aAAa,GAAG,SAAS,KACrC,cAAc,CAAA;CACpB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,IAAI,EAAE,gBAAgB,CAAA;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAyD7D"}
1
+ {"version":3,"file":"stillCapture.d.ts","sourceRoot":"","sources":["../../src/stillCapture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAI5C,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,aAAa,CAAA;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAQjE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK9D;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAQD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAChB,MAAM,CAqBR;AAED,kFAAkF;AAClF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gEAAgE;IAChE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7C,EAAE,CAAC,EAAE;QACH,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;QACnC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KACvC,CAAA;IACD,YAAY,CAAC,EAAE,CACb,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,aAAa,EAAE,aAAa,GAAG,SAAS,KACrC,cAAc,CAAA;CACpB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,6EAA6E;IAC7E,aAAa,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,aAAa,EAAE,aAAa,GAAG,SAAS,CAAA;IACxC,IAAI,EAAE,gBAAgB,CAAA;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAgE7D"}
@@ -4,6 +4,7 @@ import { getDimensions } from './dimensions.js';
4
4
  import { escapeFileSystemPathSegment } from './fileSystemName.js';
5
5
  import { EventRecorder } from './events.js';
6
6
  import { resolveCrop } from './crop.js';
7
+ import { getMousePosition } from './mouse.js';
7
8
  import { getScreenCIRuntimeContext } from './runtimeContext.js';
8
9
  import { DEFAULT_VIDEO_OPTIONS, DEFAULT_ASPECT_RATIO, DEFAULT_QUALITY, } from './defaults.js';
9
10
  /** File name of the raw page capture written beside a still's `data.json`. */
@@ -41,7 +42,7 @@ export function resolveStillName(name, path, used) {
41
42
  * Returns the captured bytes so the wrapped `page.screenshot()` can return them.
42
43
  */
43
44
  export async function writeStillRecording(params) {
44
- const { name, screenciDir, dimensions, deviceScaleFactor, crop, testFilePath, configDir, recordOptions, renderOptions, deps, } = params;
45
+ const { name, screenciDir, dimensions, deviceScaleFactor, crop, mousePosition, testFilePath, configDir, recordOptions, renderOptions, deps, } = params;
45
46
  const rm = deps.fs?.rm ??
46
47
  ((path) => fsRm(path, { recursive: true, force: true }));
47
48
  const mkdir = deps.fs?.mkdir ??
@@ -58,6 +59,9 @@ export async function writeStillRecording(params) {
58
59
  width: Math.round(dimensions.width * deviceScaleFactor),
59
60
  height: Math.round(dimensions.height * deviceScaleFactor),
60
61
  deviceScaleFactor,
62
+ ...(mousePosition !== undefined && {
63
+ mousePosition: { x: mousePosition.x, y: mousePosition.y },
64
+ }),
61
65
  };
62
66
  const recorder = makeRecorder(renderOptions, recordOptions);
63
67
  recorder.start();
@@ -103,6 +107,9 @@ export function bindStillCaptureToPage(page) {
103
107
  if (cropTarget !== undefined && ctx.page !== null) {
104
108
  crop = await resolveCrop(cropTarget, ctx.page);
105
109
  }
110
+ // The cursor's last position, so the renderer can draw it on the still when
111
+ // the show option is set. Undefined when the body never moved the cursor.
112
+ const mousePosition = getMousePosition(page);
106
113
  const configDir = process.env.SCREENCI_CONFIG_DIR ?? process.cwd();
107
114
  return writeStillRecording({
108
115
  name: resolvedName,
@@ -112,6 +119,9 @@ export function bindStillCaptureToPage(page) {
112
119
  // captured mid-recording is at the viewport resolution (DSF 1).
113
120
  deviceScaleFactor: 1,
114
121
  ...(crop !== undefined && { crop }),
122
+ ...(mousePosition !== undefined && {
123
+ mousePosition: { x: mousePosition.x, y: mousePosition.y },
124
+ }),
115
125
  testFilePath: ctx.testFilePath,
116
126
  configDir,
117
127
  recordOptions,