screenci 0.0.85 → 0.0.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +16 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +49 -10
- package/dist/cli.js.map +1 -1
- package/dist/docs/video-sources/installation.screenci.js +1 -1
- package/dist/src/anonSession.d.ts +32 -5
- package/dist/src/anonSession.d.ts.map +1 -1
- package/dist/src/anonSession.js +46 -8
- package/dist/src/anonSession.js.map +1 -1
- package/dist/src/asset.d.ts +9 -8
- package/dist/src/asset.d.ts.map +1 -1
- package/dist/src/asset.js +23 -82
- package/dist/src/asset.js.map +1 -1
- package/dist/src/events.d.ts +10 -0
- package/dist/src/events.d.ts.map +1 -1
- package/dist/src/events.js.map +1 -1
- package/dist/src/init.d.ts.map +1 -1
- package/dist/src/init.js +28 -43
- package/dist/src/init.js.map +1 -1
- package/dist/src/runtimeContext.d.ts +0 -17
- package/dist/src/runtimeContext.d.ts.map +1 -1
- package/dist/src/runtimeContext.js +0 -3
- package/dist/src/runtimeContext.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
export declare const ANON_SESSION_FILE = "anon-session.json";
|
|
1
2
|
export declare const ANON_TOKEN_HEADER = "X-ScreenCI-Anon-Token";
|
|
2
3
|
export declare const SECRET_HEADER = "X-ScreenCI-Secret";
|
|
4
|
+
export declare const SCREENCI_TERMS_URL = "https://screenci.com/legal/tos";
|
|
5
|
+
/**
|
|
6
|
+
* Single-line browsewrap notice shown on the anonymous trial path. Kept pure
|
|
7
|
+
* (no logger dependency) so it is trivially unit-testable and reusable in both
|
|
8
|
+
* the up-front record gate and the post-upload summary.
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatAnonTermsNotice(): string;
|
|
3
11
|
export type CliCredential = {
|
|
4
12
|
header: typeof SECRET_HEADER;
|
|
5
13
|
value: string;
|
|
@@ -22,19 +30,38 @@ export type AnonSessionStatus = {
|
|
|
22
30
|
status: 'expired';
|
|
23
31
|
} | {
|
|
24
32
|
status: 'pending';
|
|
33
|
+
used: boolean;
|
|
25
34
|
} | {
|
|
26
35
|
status: 'claimed';
|
|
27
36
|
secret: string;
|
|
28
37
|
};
|
|
29
38
|
/**
|
|
30
|
-
* Checks the server-side status of a locally stored anon token
|
|
31
|
-
*
|
|
32
|
-
* should self-upgrade to the real secret), or expired/not
|
|
33
|
-
*
|
|
34
|
-
* outage doesn't block an otherwise-working anonymous upload.
|
|
39
|
+
* Checks the server-side status of a locally stored anon token: still pending
|
|
40
|
+
* (with `used` telling whether the one free trial recording is already spent),
|
|
41
|
+
* claimed (the CLI should self-upgrade to the real secret), or expired/not
|
|
42
|
+
* found. Defaults to a fresh, unused `pending` on a network failure so a
|
|
43
|
+
* transient outage doesn't block an otherwise-working first anonymous upload.
|
|
35
44
|
*/
|
|
36
45
|
export declare function checkAnonSessionStatus(token: string, options?: {
|
|
37
46
|
backendUrl?: string;
|
|
38
47
|
fetchImpl?: typeof fetch;
|
|
39
48
|
}): Promise<AnonSessionStatus>;
|
|
49
|
+
export type AnonRecordingGate = {
|
|
50
|
+
allowed: true;
|
|
51
|
+
} | {
|
|
52
|
+
allowed: false;
|
|
53
|
+
reason: 'used' | 'expired';
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Decides whether a fresh anonymous `record` is allowed to START, given the
|
|
57
|
+
* session's current status. An anonymous trial gets exactly one recording:
|
|
58
|
+
* once it is used (a pending session that already spent its trial) or the
|
|
59
|
+
* session has expired, a second recording is refused up front so the user is
|
|
60
|
+
* told to sign up before anything renders, rather than silently minting a new
|
|
61
|
+
* trial or only failing after the whole recording ran. A first-run token the
|
|
62
|
+
* server has not seen yet (`not_found`), a pending-but-unused session, and a
|
|
63
|
+
* `claimed` session (the upload path self-upgrades to the real secret) all
|
|
64
|
+
* proceed.
|
|
65
|
+
*/
|
|
66
|
+
export declare function evaluateAnonRecordingGate(status: AnonSessionStatus): AnonRecordingGate;
|
|
40
67
|
//# sourceMappingURL=anonSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anonSession.d.ts","sourceRoot":"","sources":["../../src/anonSession.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"anonSession.d.ts","sourceRoot":"","sources":["../../src/anonSession.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,iBAAiB,sBAAsB,CAAA;AAEpD,eAAO,MAAM,iBAAiB,0BAA0B,CAAA;AACxD,eAAO,MAAM,aAAa,sBAAsB,CAAA;AAOhD,eAAO,MAAM,kBAAkB,mCAAmC,CAAA;AAElE;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,OAAO,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,MAAM,EAAE,OAAO,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAE9D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAE3D;AA+BD,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GAErB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzC;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GAC9D,OAAO,CAAC,iBAAiB,CAAC,CAyB5B;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAElD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,iBAAiB,GACxB,iBAAiB,CAMnB"}
|
package/dist/src/anonSession.js
CHANGED
|
@@ -7,9 +7,28 @@ import { getDevBackendUrl } from './linkSession.js';
|
|
|
7
7
|
// under a locally generated token instead of requiring an account up front.
|
|
8
8
|
// The token lives only in `.screenci/anon-session.json` and, server-side, in
|
|
9
9
|
// the anonymousSessions table (never printed or embedded in any URL).
|
|
10
|
-
|
|
10
|
+
// The anon session token file lives directly inside `.screenci/`, alongside
|
|
11
|
+
// the per-recording directories. It must survive the per-run wipe of that
|
|
12
|
+
// directory (see clearRecordingDirectories), or every `record` would mint a
|
|
13
|
+
// fresh trial and the one-recording cap, claim, and auto-graduate would all
|
|
14
|
+
// break. Exported so the wipe can preserve it by name.
|
|
15
|
+
export const ANON_SESSION_FILE = 'anon-session.json';
|
|
11
16
|
export const ANON_TOKEN_HEADER = 'X-ScreenCI-Anon-Token';
|
|
12
17
|
export const SECRET_HEADER = 'X-ScreenCI-Secret';
|
|
18
|
+
// Canonical Terms of Service URL. Hardcoded like the docs links elsewhere in
|
|
19
|
+
// the CLI (the legal pages are not environment-specific). Anonymous trial
|
|
20
|
+
// recordings upload to our servers without an account, so the CLI surfaces this
|
|
21
|
+
// up front (before recording) and again in the post-upload summary. Signed-in
|
|
22
|
+
// users accept the versioned Terms server-side in the web app instead.
|
|
23
|
+
export const SCREENCI_TERMS_URL = 'https://screenci.com/legal/tos';
|
|
24
|
+
/**
|
|
25
|
+
* Single-line browsewrap notice shown on the anonymous trial path. Kept pure
|
|
26
|
+
* (no logger dependency) so it is trivially unit-testable and reusable in both
|
|
27
|
+
* the up-front record gate and the post-upload summary.
|
|
28
|
+
*/
|
|
29
|
+
export function formatAnonTermsNotice() {
|
|
30
|
+
return `By recording an anonymous ScreenCI trial you agree to the Terms: ${SCREENCI_TERMS_URL}`;
|
|
31
|
+
}
|
|
13
32
|
export function secretCredential(secret) {
|
|
14
33
|
return { header: SECRET_HEADER, value: secret };
|
|
15
34
|
}
|
|
@@ -59,11 +78,11 @@ export async function getOrCreateAnonToken(screenciDir) {
|
|
|
59
78
|
return token;
|
|
60
79
|
}
|
|
61
80
|
/**
|
|
62
|
-
* Checks the server-side status of a locally stored anon token
|
|
63
|
-
*
|
|
64
|
-
* should self-upgrade to the real secret), or expired/not
|
|
65
|
-
*
|
|
66
|
-
* outage doesn't block an otherwise-working anonymous upload.
|
|
81
|
+
* Checks the server-side status of a locally stored anon token: still pending
|
|
82
|
+
* (with `used` telling whether the one free trial recording is already spent),
|
|
83
|
+
* claimed (the CLI should self-upgrade to the real secret), or expired/not
|
|
84
|
+
* found. Defaults to a fresh, unused `pending` on a network failure so a
|
|
85
|
+
* transient outage doesn't block an otherwise-working first anonymous upload.
|
|
67
86
|
*/
|
|
68
87
|
export async function checkAnonSessionStatus(token, options = {}) {
|
|
69
88
|
const backendUrl = options.backendUrl ?? getDevBackendUrl();
|
|
@@ -82,10 +101,29 @@ export async function checkAnonSessionStatus(token, options = {}) {
|
|
|
82
101
|
return { status: 'expired' };
|
|
83
102
|
if (body.status === 'not_found')
|
|
84
103
|
return { status: 'not_found' };
|
|
85
|
-
return { status: 'pending' };
|
|
104
|
+
return { status: 'pending', used: body.used === true };
|
|
86
105
|
}
|
|
87
106
|
catch {
|
|
88
|
-
return { status: 'pending' };
|
|
107
|
+
return { status: 'pending', used: false };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Decides whether a fresh anonymous `record` is allowed to START, given the
|
|
112
|
+
* session's current status. An anonymous trial gets exactly one recording:
|
|
113
|
+
* once it is used (a pending session that already spent its trial) or the
|
|
114
|
+
* session has expired, a second recording is refused up front so the user is
|
|
115
|
+
* told to sign up before anything renders, rather than silently minting a new
|
|
116
|
+
* trial or only failing after the whole recording ran. A first-run token the
|
|
117
|
+
* server has not seen yet (`not_found`), a pending-but-unused session, and a
|
|
118
|
+
* `claimed` session (the upload path self-upgrades to the real secret) all
|
|
119
|
+
* proceed.
|
|
120
|
+
*/
|
|
121
|
+
export function evaluateAnonRecordingGate(status) {
|
|
122
|
+
if (status.status === 'expired')
|
|
123
|
+
return { allowed: false, reason: 'expired' };
|
|
124
|
+
if (status.status === 'pending' && status.used) {
|
|
125
|
+
return { allowed: false, reason: 'used' };
|
|
89
126
|
}
|
|
127
|
+
return { allowed: true };
|
|
90
128
|
}
|
|
91
129
|
//# sourceMappingURL=anonSession.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anonSession.js","sourceRoot":"","sources":["../../src/anonSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEnD,yEAAyE;AACzE,4EAA4E;AAC5E,6EAA6E;AAC7E,sEAAsE;AAEtE,MAAM,iBAAiB,GAAG,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"anonSession.js","sourceRoot":"","sources":["../../src/anonSession.ts"],"names":[],"mappings":"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"}
|
package/dist/src/asset.d.ts
CHANGED
|
@@ -111,15 +111,16 @@ type OverlayCommon = {
|
|
|
111
111
|
*/
|
|
112
112
|
pinToScreen?: boolean;
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
114
|
+
* Draw this overlay ABOVE the synthetic mouse cursor, so the cursor passes
|
|
115
|
+
* underneath it instead of on top. The cursor stays visible everywhere else in
|
|
116
|
+
* the frame; only where the overlay sits does the overlay cover it. Useful for
|
|
117
|
+
* full-screen intro or outro cards (the cursor disappears behind the card) and
|
|
118
|
+
* for HUD elements like a corner logo the cursor should slide under.
|
|
119
|
+
* Placement-agnostic, so it works for every overlay variant. Overlapping
|
|
120
|
+
* `overMouse` overlays each draw above the cursor. Has no effect on
|
|
120
121
|
* screenshots, whose cursor is hidden by default.
|
|
121
122
|
*/
|
|
122
|
-
|
|
123
|
+
overMouse?: boolean;
|
|
123
124
|
};
|
|
124
125
|
/** Fields that only apply to a `.mp4` video overlay (a file `path`). */
|
|
125
126
|
type OverlayVideoFields = {
|
|
@@ -230,7 +231,7 @@ export declare const MAX_AUDIO_LEVEL = 4;
|
|
|
230
231
|
* is a finished still or clip, so source-only fields (`over`/`margin`/`animate`/
|
|
231
232
|
* `css`/`capturePadding`) do not apply.
|
|
232
233
|
*/
|
|
233
|
-
export type DependencyOverlayOptions = Pick<OverlayCommon, 'relativeTo' | 'x' | 'y' | 'width' | 'height' | 'aspectRatio' | 'fill' | 'duration' | 'crop' | 'pinToScreen' | '
|
|
234
|
+
export type DependencyOverlayOptions = Pick<OverlayCommon, 'relativeTo' | 'x' | 'y' | 'width' | 'height' | 'aspectRatio' | 'fill' | 'duration' | 'crop' | 'pinToScreen' | 'overMouse'> & {
|
|
234
235
|
/**
|
|
235
236
|
* Late start into the embedded VIDEO (a `'2s'`/timecode/`'50%'` position).
|
|
236
237
|
* Video dependencies only; rejected when the target resolves to a screenshot.
|
package/dist/src/asset.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/asset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,WAAW,EAGjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/asset.ts"],"names":[],"mappings":"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"}
|
package/dist/src/asset.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { timelineAnchorFields, } from './events.js';
|
|
2
2
|
import { parseTimelineOffset } from './timelineOffset.js';
|
|
3
|
-
import { isMouseVisible } from './mouse.js';
|
|
4
3
|
import { validateCrop, resolveSourceTrim } from './sourceTrim.js';
|
|
5
4
|
import { overlayRect } from './overlayRect.js';
|
|
6
5
|
import { captureCallerFile } from './callerFile.js';
|
|
@@ -10,7 +9,7 @@ import { dirname, resolve } from 'path';
|
|
|
10
9
|
import { resolveRecordingTimingDuration } from './runtimeMode.js';
|
|
11
10
|
import { resolveOverlayCss, DEFAULT_OVERLAY_DEVICE_SCALE_FACTOR, DEFAULT_ANIMATION_FPS, } from './htmlRasterizer.js';
|
|
12
11
|
export { setOverlayCss } from './htmlRasterizer.js';
|
|
13
|
-
import { getScreenCIRuntimeContext, getRuntimeAssetRecorder, getRuntimePage, getRuntimeRecordingDir, setRuntimeAssetRecorder, resetAssetRuntimeState,
|
|
12
|
+
import { getScreenCIRuntimeContext, getRuntimeAssetRecorder, getRuntimePage, getRuntimeRecordingDir, setRuntimeAssetRecorder, resetAssetRuntimeState, } from './runtimeContext.js';
|
|
14
13
|
/**
|
|
15
14
|
* Upper bound for an audio level (linear gain). `4` is +12 dB, plenty of
|
|
16
15
|
* headroom for a boost while guarding against accidental extreme distortion.
|
|
@@ -277,7 +276,7 @@ function buildOverlayFromConfig(name, config) {
|
|
|
277
276
|
});
|
|
278
277
|
const fullScreen = config.fill === 'screen';
|
|
279
278
|
const pinToScreen = config.pinToScreen === true;
|
|
280
|
-
const
|
|
279
|
+
const overMouse = config.overMouse === true;
|
|
281
280
|
const animate = config.animate === true;
|
|
282
281
|
// Parse the relative `duration` string into ms once; reused by every branch.
|
|
283
282
|
const configDurationMs = resolveConfigDuration(name, config.duration);
|
|
@@ -313,9 +312,9 @@ function buildOverlayFromConfig(name, config) {
|
|
|
313
312
|
? () => renderElementToMarkup(name, config.element)
|
|
314
313
|
: () => Promise.resolve(config.html);
|
|
315
314
|
if (animate) {
|
|
316
|
-
return createAnimatedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen,
|
|
315
|
+
return createAnimatedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen, overMouse, config.fps, configDurationMs, renderOpts);
|
|
317
316
|
}
|
|
318
|
-
return createRenderedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen,
|
|
317
|
+
return createRenderedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen, overMouse, configDurationMs, renderOpts);
|
|
319
318
|
}
|
|
320
319
|
const path = config.path;
|
|
321
320
|
const extension = getAssetExtension(path);
|
|
@@ -346,9 +345,9 @@ function buildOverlayFromConfig(name, config) {
|
|
|
346
345
|
registerAssetPath(path);
|
|
347
346
|
const getMarkup = () => readHtmlOverlayFile(path);
|
|
348
347
|
if (animate) {
|
|
349
|
-
return createAnimatedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen,
|
|
348
|
+
return createAnimatedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen, overMouse, config.fps, configDurationMs, renderOpts);
|
|
350
349
|
}
|
|
351
|
-
return createRenderedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen,
|
|
350
|
+
return createRenderedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen, overMouse, configDurationMs, renderOpts);
|
|
352
351
|
}
|
|
353
352
|
// File-backed image / video overlays.
|
|
354
353
|
if (extension === '.svg' || extension === '.png') {
|
|
@@ -365,9 +364,10 @@ function buildOverlayFromConfig(name, config) {
|
|
|
365
364
|
...(placement !== undefined && { placement }),
|
|
366
365
|
fullScreen,
|
|
367
366
|
...(pinToScreen && { pinToScreen: true }),
|
|
367
|
+
...(overMouse && { overMouse: true }),
|
|
368
368
|
...(configDurationMs !== undefined && { durationMs: configDurationMs }),
|
|
369
369
|
...(config.crop !== undefined && { crop: config.crop }),
|
|
370
|
-
}
|
|
370
|
+
});
|
|
371
371
|
}
|
|
372
372
|
if (extension === '.mp4') {
|
|
373
373
|
if (config.duration !== undefined) {
|
|
@@ -391,13 +391,14 @@ function buildOverlayFromConfig(name, config) {
|
|
|
391
391
|
...(placement !== undefined && { placement }),
|
|
392
392
|
fullScreen,
|
|
393
393
|
...(pinToScreen && { pinToScreen: true }),
|
|
394
|
+
...(overMouse && { overMouse: true }),
|
|
394
395
|
...(config.volume !== undefined && { audio: config.volume }),
|
|
395
396
|
...(config.speed !== undefined && { speed: config.speed }),
|
|
396
397
|
...(config.time !== undefined && { time: config.time }),
|
|
397
398
|
...(config.crop !== undefined && { crop: config.crop }),
|
|
398
399
|
...(sourceStart !== undefined && { sourceStart }),
|
|
399
400
|
...(sourceEnd !== undefined && { sourceEnd }),
|
|
400
|
-
}
|
|
401
|
+
});
|
|
401
402
|
}
|
|
402
403
|
throw new Error(`[screenci] Overlay "${name}" must use one of: .html, .svg, .png, .mp4. Received: ${path}`);
|
|
403
404
|
}
|
|
@@ -628,7 +629,7 @@ function resolveConfigDuration(name, duration) {
|
|
|
628
629
|
return undefined;
|
|
629
630
|
return resolveRelativeDuration(duration, `Overlay "${name}" duration`);
|
|
630
631
|
}
|
|
631
|
-
function createActiveAssetRun(startedWithExplicitStart
|
|
632
|
+
function createActiveAssetRun(startedWithExplicitStart) {
|
|
632
633
|
let resolve;
|
|
633
634
|
const finished = new Promise((resolveFn) => {
|
|
634
635
|
resolve = resolveFn;
|
|
@@ -637,7 +638,6 @@ function createActiveAssetRun(startedWithExplicitStart, hideMouse) {
|
|
|
637
638
|
finished,
|
|
638
639
|
resolveFinished: resolve,
|
|
639
640
|
startedWithExplicitStart,
|
|
640
|
-
hideMouse,
|
|
641
641
|
};
|
|
642
642
|
}
|
|
643
643
|
/**
|
|
@@ -653,63 +653,10 @@ function endLiveAsset(name, reason) {
|
|
|
653
653
|
getRuntimeAssetRecorder().addAssetEnd(name, reason);
|
|
654
654
|
sleepForAssetFrameGap();
|
|
655
655
|
context.asset.activeRuns.delete(name);
|
|
656
|
-
if (run.hideMouse)
|
|
657
|
-
performOverlayMouseShow();
|
|
658
656
|
run.resolveFinished();
|
|
659
657
|
}
|
|
660
|
-
/**
|
|
661
|
-
* Hide the cursor for a `hideMouse` overlay, ref-counted so overlapping overlays
|
|
662
|
-
* only hide once. Reuses the instrumented `page.mouse.hide()`, which records the
|
|
663
|
-
* `mouseHide` event on the shared recorder. When emitted before a blocking
|
|
664
|
-
* overlay's `assetStart`, that event brackets the frozen hold in the rendered
|
|
665
|
-
* timeline (the show emitted after `assetStart` lands past the hold).
|
|
666
|
-
*/
|
|
667
|
-
function performOverlayMouseHide() {
|
|
668
|
-
// Stills hide the cursor by default (see renderOptions.screenshot.mouse.show)
|
|
669
|
-
// and have no timeline to bracket, so hideMouse is a no-op for screenshots.
|
|
670
|
-
if (isScreenshotCapture())
|
|
671
|
-
return;
|
|
672
|
-
const page = getRuntimePage();
|
|
673
|
-
if (page === null)
|
|
674
|
-
return;
|
|
675
|
-
const state = getScreenCIRuntimeContext().asset.mouseHide;
|
|
676
|
-
state.count += 1;
|
|
677
|
-
// Only the first overlay in an overlapping group changes visibility.
|
|
678
|
-
if (state.count !== 1)
|
|
679
|
-
return;
|
|
680
|
-
// A cursor already hidden (e.g. via page.mouse.hide()) is left as-is, and we
|
|
681
|
-
// remember not to force it back on when the overlay ends.
|
|
682
|
-
if (!isMouseVisible(page)) {
|
|
683
|
-
state.hiddenByOverlay = false;
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
state.hiddenByOverlay = true;
|
|
687
|
-
page.mouse.hide();
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Restore the cursor when a `hideMouse` overlay ends. Only acts once the
|
|
691
|
-
* ref-count returns to 0, and only if an overlay was the one that hid it (so a
|
|
692
|
-
* cursor that was already hidden stays hidden).
|
|
693
|
-
*/
|
|
694
|
-
function performOverlayMouseShow() {
|
|
695
|
-
if (isScreenshotCapture())
|
|
696
|
-
return;
|
|
697
|
-
const page = getRuntimePage();
|
|
698
|
-
if (page === null)
|
|
699
|
-
return;
|
|
700
|
-
const state = getScreenCIRuntimeContext().asset.mouseHide;
|
|
701
|
-
if (state.count === 0)
|
|
702
|
-
return;
|
|
703
|
-
state.count -= 1;
|
|
704
|
-
if (state.count !== 0)
|
|
705
|
-
return;
|
|
706
|
-
if (!state.hiddenByOverlay)
|
|
707
|
-
return;
|
|
708
|
-
state.hiddenByOverlay = false;
|
|
709
|
-
page.mouse.show();
|
|
710
|
-
}
|
|
711
658
|
function createAssetControllerCore(name, validate, emitStart, options = {}) {
|
|
712
|
-
const { prepare
|
|
659
|
+
const { prepare } = options;
|
|
713
660
|
const start = async (startedWithExplicitStart = true) => {
|
|
714
661
|
await validate();
|
|
715
662
|
await prepare?.({ type: 'live' });
|
|
@@ -718,10 +665,8 @@ function createAssetControllerCore(name, validate, emitStart, options = {}) {
|
|
|
718
665
|
if (context.asset.activeRuns.has(name)) {
|
|
719
666
|
throw new Error(`[screenci] Overlay "${name}" is already started. Call end() for it before starting it again.`);
|
|
720
667
|
}
|
|
721
|
-
const run = createActiveAssetRun(startedWithExplicitStart
|
|
668
|
+
const run = createActiveAssetRun(startedWithExplicitStart);
|
|
722
669
|
context.asset.activeRuns.set(name, run);
|
|
723
|
-
if (hideMouse)
|
|
724
|
-
performOverlayMouseHide();
|
|
725
670
|
emitStart(recorder, { type: 'live' });
|
|
726
671
|
};
|
|
727
672
|
const end = async () => {
|
|
@@ -740,14 +685,7 @@ function createAssetControllerCore(name, validate, emitStart, options = {}) {
|
|
|
740
685
|
await validate();
|
|
741
686
|
await prepare?.(mode);
|
|
742
687
|
const recorder = getRuntimeAssetRecorder();
|
|
743
|
-
// Order is load-bearing: the mouseHide must precede the assetStart and the
|
|
744
|
-
// mouseShow follow it, so the renderer's frozen hold (inserted at the
|
|
745
|
-
// assetStart) is bracketed by the hide/show in the final timeline.
|
|
746
|
-
if (hideMouse)
|
|
747
|
-
performOverlayMouseHide();
|
|
748
688
|
emitStart(recorder, mode);
|
|
749
|
-
if (hideMouse)
|
|
750
|
-
performOverlayMouseShow();
|
|
751
689
|
};
|
|
752
690
|
const controller = (async () => {
|
|
753
691
|
// Bare call: hold for the source's natural length. Length-less overlays
|
|
@@ -818,14 +756,15 @@ function createDependencyOverlayController(name, input) {
|
|
|
818
756
|
...timelineAnchorFields(until),
|
|
819
757
|
fullScreen,
|
|
820
758
|
...(pinToScreen && { pinToScreen: true }),
|
|
759
|
+
...(input.config.overMouse === true && { overMouse: true }),
|
|
821
760
|
...(placement !== undefined && { placement }),
|
|
822
761
|
...(input.config.crop !== undefined && { crop: input.config.crop }),
|
|
823
762
|
...(sourceStart !== undefined && { sourceStart }),
|
|
824
763
|
...(sourceEnd !== undefined && { sourceEnd }),
|
|
825
764
|
});
|
|
826
|
-
}
|
|
765
|
+
});
|
|
827
766
|
}
|
|
828
|
-
function createFileOverlayController(name, resolved
|
|
767
|
+
function createFileOverlayController(name, resolved) {
|
|
829
768
|
return createAssetControllerCore(name, async () => {
|
|
830
769
|
const testFilePath = getScreenCIRuntimeContext().testFilePath;
|
|
831
770
|
if (testFilePath !== null) {
|
|
@@ -833,13 +772,13 @@ function createFileOverlayController(name, resolved, hideMouse) {
|
|
|
833
772
|
}
|
|
834
773
|
}, (recorder, mode) => {
|
|
835
774
|
recorder.addAssetStart(name, toRecordedFileStart(name, resolved, mode));
|
|
836
|
-
}
|
|
775
|
+
});
|
|
837
776
|
}
|
|
838
777
|
/**
|
|
839
778
|
* An overlay rendered to a transparent PNG at recording time, from either an
|
|
840
779
|
* HTML file or a React element. `getMarkup` produces the HTML to rasterize.
|
|
841
780
|
*/
|
|
842
|
-
function createRenderedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen,
|
|
781
|
+
function createRenderedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen, overMouse, durationMs, renderOpts = {}) {
|
|
843
782
|
// The markup and placement are resolved during the test (cheap:
|
|
844
783
|
// renderToStaticMarkup / a string, plus a boundingBox read for `over`), but
|
|
845
784
|
// rasterization (a browser screenshot) is deferred to after the test so
|
|
@@ -875,6 +814,7 @@ function createRenderedOverlayController(name, getMarkup, placementSource, fullS
|
|
|
875
814
|
...timelineAnchorFields(until),
|
|
876
815
|
fullScreen,
|
|
877
816
|
...(pinToScreen && { pinToScreen: true }),
|
|
817
|
+
...(overMouse && { overMouse: true }),
|
|
878
818
|
...(resolvedPlacement !== undefined && {
|
|
879
819
|
placement: resolvedPlacement,
|
|
880
820
|
}),
|
|
@@ -904,7 +844,6 @@ function createRenderedOverlayController(name, getMarkup, placementSource, fullS
|
|
|
904
844
|
resolvedHtml =
|
|
905
845
|
sizePx !== undefined ? sizeWrapMarkup(markup, sizePx) : markup;
|
|
906
846
|
},
|
|
907
|
-
hideMouse,
|
|
908
847
|
});
|
|
909
848
|
}
|
|
910
849
|
/**
|
|
@@ -918,7 +857,7 @@ function createRenderedOverlayController(name, getMarkup, placementSource, fullS
|
|
|
918
857
|
* the recording, the old "hide block" that cut capture wall-clock from the
|
|
919
858
|
* timeline is no longer needed.
|
|
920
859
|
*/
|
|
921
|
-
function createAnimatedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen,
|
|
860
|
+
function createAnimatedOverlayController(name, getMarkup, placementSource, fullScreen, pinToScreen, overMouse, fps, configDurationMs, renderOpts = {}) {
|
|
922
861
|
let resolved;
|
|
923
862
|
let skipped = false;
|
|
924
863
|
const resolveDurationMs = (mode) => {
|
|
@@ -951,6 +890,7 @@ function createAnimatedOverlayController(name, getMarkup, placementSource, fullS
|
|
|
951
890
|
durationMs: resolved.durationMs,
|
|
952
891
|
fullScreen,
|
|
953
892
|
...(pinToScreen && { pinToScreen: true }),
|
|
893
|
+
...(overMouse && { overMouse: true }),
|
|
954
894
|
...(resolved.placement !== undefined && {
|
|
955
895
|
placement: resolved.placement,
|
|
956
896
|
}),
|
|
@@ -982,7 +922,6 @@ function createAnimatedOverlayController(name, getMarkup, placementSource, fullS
|
|
|
982
922
|
...(placement !== undefined && { placement }),
|
|
983
923
|
};
|
|
984
924
|
},
|
|
985
|
-
hideMouse,
|
|
986
925
|
});
|
|
987
926
|
}
|
|
988
927
|
function getAssetExtension(path) {
|
|
@@ -1205,6 +1144,7 @@ function toRecordedFileStart(name, resolved, mode) {
|
|
|
1205
1144
|
...timelineAnchorFields(until),
|
|
1206
1145
|
fullScreen: resolved.fullScreen,
|
|
1207
1146
|
...(resolved.pinToScreen && { pinToScreen: true }),
|
|
1147
|
+
...(resolved.overMouse && { overMouse: true }),
|
|
1208
1148
|
...(resolved.placement !== undefined && {
|
|
1209
1149
|
placement: resolved.placement,
|
|
1210
1150
|
}),
|
|
@@ -1223,6 +1163,7 @@ function toRecordedFileStart(name, resolved, mode) {
|
|
|
1223
1163
|
audio: resolved.audio ?? 1,
|
|
1224
1164
|
fullScreen: resolved.fullScreen,
|
|
1225
1165
|
...(resolved.pinToScreen && { pinToScreen: true }),
|
|
1166
|
+
...(resolved.overMouse && { overMouse: true }),
|
|
1226
1167
|
...(resolved.placement !== undefined && { placement: resolved.placement }),
|
|
1227
1168
|
...(resolved.speed !== undefined && { speed: resolved.speed }),
|
|
1228
1169
|
...(resolved.time !== undefined && { time: resolved.time }),
|