doc-detective 4.10.0 → 4.11.0
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/common/src/schemas/schemas.json +2254 -28
- package/dist/common/src/types/generated/record_v3.d.ts +25 -2
- package/dist/common/src/types/generated/record_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/step_v3.d.ts +25 -2
- package/dist/common/src/types/generated/step_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/test_v3.d.ts +50 -4
- package/dist/common/src/types/generated/test_v3.d.ts.map +1 -1
- package/dist/core/tests/ffmpegRecorder.d.ts +62 -0
- package/dist/core/tests/ffmpegRecorder.d.ts.map +1 -0
- package/dist/core/tests/ffmpegRecorder.js +385 -0
- package/dist/core/tests/ffmpegRecorder.js.map +1 -0
- package/dist/core/tests/startRecording.d.ts.map +1 -1
- package/dist/core/tests/startRecording.js +144 -16
- package/dist/core/tests/startRecording.js.map +1 -1
- package/dist/core/tests/stopRecording.d.ts.map +1 -1
- package/dist/core/tests/stopRecording.js +158 -60
- package/dist/core/tests/stopRecording.js.map +1 -1
- package/dist/core/tests.d.ts.map +1 -1
- package/dist/core/tests.js +111 -13
- package/dist/core/tests.js.map +1 -1
- package/dist/hints/context.d.ts.map +1 -1
- package/dist/hints/context.js +3 -0
- package/dist/hints/context.js.map +1 -1
- package/dist/hints/hints.d.ts.map +1 -1
- package/dist/hints/hints.js +17 -0
- package/dist/hints/hints.js.map +1 -1
- package/dist/hints/types.d.ts +7 -0
- package/dist/hints/types.d.ts.map +1 -1
- package/dist/index.cjs +2911 -185
- package/package.json +1 -1
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import crypto from "node:crypto";
|
|
6
|
+
import { loadHeavyDep } from "../../runtime/loader.js";
|
|
7
|
+
import { sanitizeFilesystemName } from "../utils.js";
|
|
8
|
+
// Fixed virtual-display size for the Linux Xvfb recording path. Used both to
|
|
9
|
+
// start Xvfb and as the x11grab `-video_size`, so the capture matches the
|
|
10
|
+
// display exactly (and window/viewport crops fit within it).
|
|
11
|
+
const XVFB_SCREEN_SIZE = "1920x1080";
|
|
12
|
+
export { resolveRecordPlan, coerceRecordContextBrowser, safeContextId, browserCaptureTitle, browserDownloadDir, buildCaptureArgs, resolveCropGeometry, jobIsFfmpegRecording, computeEffectiveConcurrency, getFfmpegPath, detectMacScreenIndex, parseMacScreenIndex, checkSystemBinary, xvfbDisplay, startXvfb, XVFB_SCREEN_SIZE, detectX11ScreenSize, };
|
|
13
|
+
// The browser engine drives getDisplayMedia's auto-select via a per-context
|
|
14
|
+
// window title and downloads the .webm to a per-context dir. tests.ts (which
|
|
15
|
+
// builds Chrome's launch flag + download pref) and startRecording.ts (which
|
|
16
|
+
// sets document.title + reads the download) must agree, so both derive these
|
|
17
|
+
// from the contextId here. Unique-per-context titles are what make concurrent
|
|
18
|
+
// Chrome recordings safe — each browser auto-selects only its own window.
|
|
19
|
+
// contextId can be author-supplied (a spec may set it), so it must be
|
|
20
|
+
// sanitized before going into a filesystem path or a launch-flag value —
|
|
21
|
+
// otherwise a value like "../x" could escape the temp dir.
|
|
22
|
+
function safeContextId(contextId) {
|
|
23
|
+
const raw = String(contextId ?? "ctx");
|
|
24
|
+
const base = sanitizeFilesystemName(raw, "ctx");
|
|
25
|
+
// If sanitization didn't change anything, the id is already filesystem-safe
|
|
26
|
+
// and unique. If it did, distinct raw ids (e.g. "a/b" and "a\\b") could
|
|
27
|
+
// collapse to the same value — which would reintroduce the concurrency bug
|
|
28
|
+
// (shared capture title / download dir). Disambiguate with a short stable
|
|
29
|
+
// hash of the raw id so uniqueness survives sanitization.
|
|
30
|
+
if (base === raw)
|
|
31
|
+
return base;
|
|
32
|
+
const hash = crypto.createHash("sha1").update(raw).digest("hex").slice(0, 8);
|
|
33
|
+
return `${base}-${hash}`;
|
|
34
|
+
}
|
|
35
|
+
function browserCaptureTitle(contextId) {
|
|
36
|
+
return `RECORD_ME_${safeContextId(contextId)}`;
|
|
37
|
+
}
|
|
38
|
+
function browserDownloadDir(contextId) {
|
|
39
|
+
return path.join(os.tmpdir(), "doc-detective", "recordings", safeContextId(contextId));
|
|
40
|
+
}
|
|
41
|
+
// Pull the engine fields out of a `record` step value. `record` may be a
|
|
42
|
+
// boolean, a string path, or a detailed object; only the object form can
|
|
43
|
+
// carry an `engine`, which itself is either a string shorthand or an object.
|
|
44
|
+
function engineFields(record) {
|
|
45
|
+
const engine = record && typeof record === "object" ? record.engine : undefined;
|
|
46
|
+
if (typeof engine === "string")
|
|
47
|
+
return { name: engine };
|
|
48
|
+
if (engine && typeof engine === "object")
|
|
49
|
+
return { name: engine.name, target: engine.target, fps: engine.fps };
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
// Normalize a record step into a concrete plan. An explicit engine always
|
|
53
|
+
// wins; otherwise auto-resolve: a visible Chrome context uses the
|
|
54
|
+
// concurrency-safe browser engine, everything else falls back to ffmpeg. The
|
|
55
|
+
// context handed in here is already coerced (see coerceRecordContextBrowser),
|
|
56
|
+
// so this stays a pure read.
|
|
57
|
+
function resolveRecordPlan({ step, context, }) {
|
|
58
|
+
const { name, target, fps } = engineFields(step?.record);
|
|
59
|
+
let engineName = name;
|
|
60
|
+
if (!engineName) {
|
|
61
|
+
const b = context?.browser;
|
|
62
|
+
engineName =
|
|
63
|
+
b?.name === "chrome" && b?.headless === false ? "browser" : "ffmpeg";
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
name: engineName,
|
|
67
|
+
target: target || "display",
|
|
68
|
+
fps: fps ?? 30,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function hasRecordStepWithoutEngine(context) {
|
|
72
|
+
const steps = Array.isArray(context?.steps) ? context.steps : [];
|
|
73
|
+
return steps.some((s) => {
|
|
74
|
+
// Falsy record (undefined, or an explicit `record: false`) is not an
|
|
75
|
+
// active recording step.
|
|
76
|
+
if (!s?.record)
|
|
77
|
+
return false;
|
|
78
|
+
return engineFields(s.record).name === undefined;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// When a context has a record step with no explicit engine and the user
|
|
82
|
+
// never chose a browser, prefer to make the browser engine viable by
|
|
83
|
+
// coercing to headed Chrome (the browser engine can't record headless).
|
|
84
|
+
// Returns the browser to assign, or null when no coercion applies.
|
|
85
|
+
function coerceRecordContextBrowser({ context, availableApps, }) {
|
|
86
|
+
if (context?.browser)
|
|
87
|
+
return null; // user specified a browser
|
|
88
|
+
if (!hasRecordStepWithoutEngine(context))
|
|
89
|
+
return null;
|
|
90
|
+
const chromeAvailable = Array.isArray(availableApps) &&
|
|
91
|
+
availableApps.some((a) => a?.name === "chrome");
|
|
92
|
+
if (!chromeAvailable)
|
|
93
|
+
return null;
|
|
94
|
+
return { name: "chrome", headless: false };
|
|
95
|
+
}
|
|
96
|
+
// Build the ffmpeg argument list for a full-display capture on the given
|
|
97
|
+
// platform. window/viewport targets are realized later by cropping during
|
|
98
|
+
// transcode, so capture is always full-screen here. Input options
|
|
99
|
+
// (`-framerate`, `-f`, device) precede `-i`; output options follow it.
|
|
100
|
+
function buildCaptureArgs({ platform, fps, displayEnv, outputPath, screenIndex, screenSize, }) {
|
|
101
|
+
const rate = String(fps ?? 30);
|
|
102
|
+
let input;
|
|
103
|
+
switch (platform) {
|
|
104
|
+
case "win32":
|
|
105
|
+
input = ["-f", "gdigrab", "-framerate", rate, "-i", "desktop"];
|
|
106
|
+
break;
|
|
107
|
+
case "darwin":
|
|
108
|
+
// Default to screen index 0 (a camera-less host — e.g. CI — lists the
|
|
109
|
+
// screen at 0). startRecording detects the real index when it can.
|
|
110
|
+
input = [
|
|
111
|
+
"-f",
|
|
112
|
+
"avfoundation",
|
|
113
|
+
"-framerate",
|
|
114
|
+
rate,
|
|
115
|
+
"-i",
|
|
116
|
+
`${screenIndex ?? "0"}:none`,
|
|
117
|
+
];
|
|
118
|
+
break;
|
|
119
|
+
case "linux":
|
|
120
|
+
// x11grab in the bundled ffmpeg defaults to a 640x480 grab when
|
|
121
|
+
// -video_size is omitted, capturing only a corner of the display. Pass
|
|
122
|
+
// the real screen size so the full display (and any window/viewport
|
|
123
|
+
// crop within it) is captured.
|
|
124
|
+
input = [
|
|
125
|
+
"-f",
|
|
126
|
+
"x11grab",
|
|
127
|
+
"-framerate",
|
|
128
|
+
rate,
|
|
129
|
+
...(screenSize ? ["-video_size", screenSize] : []),
|
|
130
|
+
"-i",
|
|
131
|
+
displayEnv || ":0.0",
|
|
132
|
+
];
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
throw new Error(`Screen recording isn't supported on platform '${platform}'.`);
|
|
136
|
+
}
|
|
137
|
+
return ["-y", ...input, "-pix_fmt", "yuv420p", outputPath];
|
|
138
|
+
}
|
|
139
|
+
// Resolve the crop rectangle (in physical pixels) for a window/viewport
|
|
140
|
+
// target. Returns null for the full-display target (no crop). Best-effort:
|
|
141
|
+
// viewport geometry is derived from in-page metrics scaled by devicePixelRatio,
|
|
142
|
+
// window geometry from the WebDriver window rect.
|
|
143
|
+
async function resolveCropGeometry({ driver, target, }) {
|
|
144
|
+
if (target === "viewport") {
|
|
145
|
+
const m = await driver.execute(() => {
|
|
146
|
+
return {
|
|
147
|
+
sx: window.screenX,
|
|
148
|
+
sy: window.screenY,
|
|
149
|
+
iw: window.innerWidth,
|
|
150
|
+
ih: window.innerHeight,
|
|
151
|
+
ow: window.outerWidth,
|
|
152
|
+
oh: window.outerHeight,
|
|
153
|
+
dpr: window.devicePixelRatio || 1,
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
const dpr = m.dpr || 1;
|
|
157
|
+
// screenX/screenY is the window's outer top-left, which sits above the
|
|
158
|
+
// browser chrome (tabs, address bar, infobars). Offset to the content
|
|
159
|
+
// area: by the side border on X, and by the top chrome height on Y
|
|
160
|
+
// (outerHeight - innerHeight, minus one border for the matching bottom
|
|
161
|
+
// edge). Otherwise the crop captures the chrome instead of the page.
|
|
162
|
+
const border = Math.max(0, (m.ow - m.iw) / 2);
|
|
163
|
+
const topChrome = Math.max(0, m.oh - m.ih - border);
|
|
164
|
+
return {
|
|
165
|
+
x: Math.round((m.sx + border) * dpr),
|
|
166
|
+
y: Math.round((m.sy + topChrome) * dpr),
|
|
167
|
+
w: Math.round(m.iw * dpr),
|
|
168
|
+
h: Math.round(m.ih * dpr),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (target === "window") {
|
|
172
|
+
const r = await driver.getWindowRect();
|
|
173
|
+
// getWindowRect is in CSS pixels; the crop filter is in physical pixels,
|
|
174
|
+
// so scale by devicePixelRatio (as the viewport branch does). Falls back
|
|
175
|
+
// to 1 if the page can't report it.
|
|
176
|
+
let dpr;
|
|
177
|
+
try {
|
|
178
|
+
dpr = (await driver.execute(() => window.devicePixelRatio || 1)) || 1;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
dpr = 1;
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
x: Math.round(r.x * dpr),
|
|
185
|
+
y: Math.round(r.y * dpr),
|
|
186
|
+
w: Math.round(r.width * dpr),
|
|
187
|
+
h: Math.round(r.height * dpr),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
function jobIsFfmpegRecording(job) {
|
|
193
|
+
const steps = Array.isArray(job?.context?.steps) ? job.context.steps : [];
|
|
194
|
+
return steps.some((s) => {
|
|
195
|
+
if (!s?.record)
|
|
196
|
+
return false; // skip undefined / `record: false`
|
|
197
|
+
return resolveRecordPlan({ step: s, context: job.context }).name === "ffmpeg";
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
// Decide the effective worker-pool limit given recording constraints. ffmpeg
|
|
201
|
+
// screen capture needs exclusive use of the physical display, so concurrent
|
|
202
|
+
// ffmpeg recordings are only safe on Linux with per-runner Xvfb displays;
|
|
203
|
+
// elsewhere the run is forced serial. forcedSerial is true only when a
|
|
204
|
+
// requested limit > 1 was actually capped (so callers warn precisely once).
|
|
205
|
+
function computeEffectiveConcurrency({ requestedLimit, jobs, platform, xvfbAvailable, }) {
|
|
206
|
+
const ffmpegJobs = (jobs || []).filter(jobIsFfmpegRecording);
|
|
207
|
+
if (ffmpegJobs.length === 0) {
|
|
208
|
+
return { limit: requestedLimit, xvfbContexts: [], forcedSerial: false };
|
|
209
|
+
}
|
|
210
|
+
if (platform === "linux" && xvfbAvailable) {
|
|
211
|
+
return {
|
|
212
|
+
limit: requestedLimit,
|
|
213
|
+
xvfbContexts: ffmpegJobs.map((j) => j.context),
|
|
214
|
+
forcedSerial: false,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return { limit: 1, xvfbContexts: [], forcedSerial: requestedLimit > 1 };
|
|
218
|
+
}
|
|
219
|
+
// Resolve the ffmpeg binary path lazily — @ffmpeg-installer/ffmpeg is a heavy
|
|
220
|
+
// runtime dep that should only load when a recording step actually runs. The
|
|
221
|
+
// ctx threads a user-overridden cacheDir through, matching the JIT installer.
|
|
222
|
+
async function getFfmpegPath(ctx = {}) {
|
|
223
|
+
const mod = await loadHeavyDep("@ffmpeg-installer/ffmpeg", { ctx });
|
|
224
|
+
// The package's CJS entry exports an object with a .path field; under an
|
|
225
|
+
// ESM dynamic import we may get { default: { path }, path? }. Try both, then
|
|
226
|
+
// guard before handing it to a child process so a malformed install fails
|
|
227
|
+
// with an actionable message instead of a confusing deep node error.
|
|
228
|
+
const candidate = mod && (mod.path ?? mod.default?.path);
|
|
229
|
+
if (typeof candidate !== "string" || candidate.length === 0) {
|
|
230
|
+
throw new Error("ffmpeg binary path is missing or malformed in the installed @ffmpeg-installer/ffmpeg package. Try `doc-detective install runtime --force` to reinstall.");
|
|
231
|
+
}
|
|
232
|
+
return candidate;
|
|
233
|
+
}
|
|
234
|
+
// Parse the stderr of `ffmpeg -f avfoundation -list_devices true -i ""` for
|
|
235
|
+
// the screen-capture device index. Only the video-devices section labels an
|
|
236
|
+
// entry "Capture screen N", so this won't match audio devices. Returns the
|
|
237
|
+
// index string (e.g. "0") or null if not found.
|
|
238
|
+
function parseMacScreenIndex(listing) {
|
|
239
|
+
const m = /\[(\d+)\]\s+Capture screen/i.exec(listing || "");
|
|
240
|
+
return m ? m[1] : null;
|
|
241
|
+
}
|
|
242
|
+
// macOS only: discover the avfoundation device index of the screen. Indices
|
|
243
|
+
// shift with attached cameras (a camera-less host such as a CI runner lists
|
|
244
|
+
// the screen at 0, not 1), so a hardcoded value frequently opens the wrong
|
|
245
|
+
// device and ffmpeg exits immediately. Returns null if it can't be determined.
|
|
246
|
+
async function detectMacScreenIndex(ffmpegPath) {
|
|
247
|
+
return new Promise((resolve) => {
|
|
248
|
+
let out = "";
|
|
249
|
+
let settled = false;
|
|
250
|
+
let proc = null;
|
|
251
|
+
const done = (v) => {
|
|
252
|
+
if (settled)
|
|
253
|
+
return;
|
|
254
|
+
settled = true;
|
|
255
|
+
try {
|
|
256
|
+
proc?.kill();
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
/* ignore */
|
|
260
|
+
}
|
|
261
|
+
resolve(v);
|
|
262
|
+
};
|
|
263
|
+
try {
|
|
264
|
+
proc = spawn(ffmpegPath, ["-f", "avfoundation", "-list_devices", "true", "-i", ""], { stdio: ["ignore", "ignore", "pipe"] });
|
|
265
|
+
proc.stderr?.on("data", (d) => {
|
|
266
|
+
out += d.toString();
|
|
267
|
+
});
|
|
268
|
+
proc.on("error", () => done(null));
|
|
269
|
+
// ffmpeg exits non-zero for a list-only invocation; parse regardless.
|
|
270
|
+
proc.on("close", () => done(parseMacScreenIndex(out)));
|
|
271
|
+
// Bound the probe so a hung ffmpeg can't stall recording startup.
|
|
272
|
+
setTimeout(() => done(null), 5000);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
done(null);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// Best-effort detection of an X11 display's screen size via xdpyinfo, e.g.
|
|
280
|
+
// "1920x1080". Used to set x11grab's -video_size for a non-Xvfb (real
|
|
281
|
+
// desktop) Linux display. Returns null if xdpyinfo is unavailable or the
|
|
282
|
+
// output can't be parsed (the caller then omits -video_size).
|
|
283
|
+
async function detectX11ScreenSize(display) {
|
|
284
|
+
return new Promise((resolve) => {
|
|
285
|
+
let out = "";
|
|
286
|
+
let settled = false;
|
|
287
|
+
let proc = null;
|
|
288
|
+
const done = (v) => {
|
|
289
|
+
if (settled)
|
|
290
|
+
return;
|
|
291
|
+
settled = true;
|
|
292
|
+
try {
|
|
293
|
+
proc?.kill();
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
/* ignore */
|
|
297
|
+
}
|
|
298
|
+
resolve(v);
|
|
299
|
+
};
|
|
300
|
+
try {
|
|
301
|
+
const env = display ? { ...process.env, DISPLAY: display } : process.env;
|
|
302
|
+
proc = spawn("xdpyinfo", [], { env, stdio: ["ignore", "pipe", "ignore"] });
|
|
303
|
+
proc.stdout?.on("data", (d) => {
|
|
304
|
+
out += d.toString();
|
|
305
|
+
});
|
|
306
|
+
proc.on("error", () => done(null));
|
|
307
|
+
proc.on("close", () => {
|
|
308
|
+
const m = /dimensions:\s+(\d+x\d+)\s+pixels/i.exec(out);
|
|
309
|
+
done(m ? m[1] : null);
|
|
310
|
+
});
|
|
311
|
+
// Bound the probe so a hung xdpyinfo can't stall recording startup.
|
|
312
|
+
setTimeout(() => done(null), 5000);
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
done(null);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
// Probe for a system binary on PATH (e.g. Xvfb, which is not an npm package).
|
|
320
|
+
// Resolves true if the binary launches, false on ENOENT/spawn error.
|
|
321
|
+
async function checkSystemBinary(name) {
|
|
322
|
+
return new Promise((resolve) => {
|
|
323
|
+
try {
|
|
324
|
+
const proc = spawn(name, ["-help"], { stdio: "ignore" });
|
|
325
|
+
proc.on("error", () => resolve(false));
|
|
326
|
+
proc.on("close", () => resolve(true));
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
resolve(false);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// X11 display name for the Nth concurrent runner. Offset by 99 to stay clear
|
|
334
|
+
// of any real display (:0 = the desktop). Pure so it's unit-testable and the
|
|
335
|
+
// server-start and capture paths agree.
|
|
336
|
+
function xvfbDisplay(index) {
|
|
337
|
+
return `:${99 + index}`;
|
|
338
|
+
}
|
|
339
|
+
// Start an Xvfb virtual framebuffer on `display` and resolve once its X socket
|
|
340
|
+
// is up. Each concurrent ffmpeg-recording runner gets its own display so the
|
|
341
|
+
// browser renders there and x11grab captures only that runner's screen —
|
|
342
|
+
// making concurrent recording safe on Linux. Caller owns process teardown.
|
|
343
|
+
async function startXvfb(display, opts = {}) {
|
|
344
|
+
const num = display.replace(/^:/, "").split(".")[0];
|
|
345
|
+
const [defW, defH] = XVFB_SCREEN_SIZE.split("x").map(Number);
|
|
346
|
+
const w = opts.width ?? defW;
|
|
347
|
+
const h = opts.height ?? defH;
|
|
348
|
+
// Capture the spawn time so a stale `/tmp/.X<N>-lock` (left by a dead Xvfb
|
|
349
|
+
// or another server) can't false-ready us — we only accept a lock created
|
|
350
|
+
// at/after our own start.
|
|
351
|
+
const startMs = Date.now();
|
|
352
|
+
const proc = spawn("Xvfb", [display, "-screen", "0", `${w}x${h}x24`, "-nolisten", "tcp"], { stdio: "ignore" });
|
|
353
|
+
let spawnErr = null;
|
|
354
|
+
proc.on("error", (e) => {
|
|
355
|
+
spawnErr = e;
|
|
356
|
+
});
|
|
357
|
+
// Readiness signal: the X lock file `/tmp/.X<N>-lock`, which Xvfb creates
|
|
358
|
+
// once it owns the display. We don't watch `/tmp/.X11-unix/X<N>` because some
|
|
359
|
+
// environments (e.g. WSLg) back the display with an abstract socket that
|
|
360
|
+
// never appears there. If the display is already in use, Xvfb exits with an
|
|
361
|
+
// error (caught by the exitCode check) rather than acquiring the lock.
|
|
362
|
+
const lock = `/tmp/.X${num}-lock`;
|
|
363
|
+
for (let i = 0; i < 50; i++) {
|
|
364
|
+
if (spawnErr)
|
|
365
|
+
throw spawnErr;
|
|
366
|
+
if (proc.exitCode !== null)
|
|
367
|
+
throw new Error(`Xvfb exited early on ${display} (code ${proc.exitCode})`);
|
|
368
|
+
try {
|
|
369
|
+
if (fs.statSync(lock).mtimeMs >= startMs)
|
|
370
|
+
return proc;
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
/* lock not present yet */
|
|
374
|
+
}
|
|
375
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
proc.kill();
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
/* ignore */
|
|
382
|
+
}
|
|
383
|
+
throw new Error(`Xvfb did not become ready on ${display} within 5s.`);
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=ffmpegRecorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ffmpegRecorder.js","sourceRoot":"","sources":["../../../src/core/tests/ffmpegRecorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startRecording.d.ts","sourceRoot":"","sources":["../../../src/core/tests/startRecording.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"startRecording.d.ts","sourceRoot":"","sources":["../../../src/core/tests/startRecording.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,iBAAe,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,gBA+VrH"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { validate } from "../../common/src/validate.js";
|
|
2
2
|
import { log } from "../utils.js";
|
|
3
3
|
import { instantiateCursor } from "./moveTo.js";
|
|
4
|
+
import { resolveRecordPlan, safeContextId, browserCaptureTitle, browserDownloadDir, buildCaptureArgs, resolveCropGeometry, getFfmpegPath, detectMacScreenIndex, detectX11ScreenSize, } from "./ffmpegRecorder.js";
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
4
6
|
import path from "node:path";
|
|
5
7
|
import fs from "node:fs";
|
|
6
8
|
import os from "node:os";
|
|
@@ -19,6 +21,12 @@ async function startRecording({ config, context, step, driver }) {
|
|
|
19
21
|
}
|
|
20
22
|
// Accept coerced and defaulted values
|
|
21
23
|
step = isValidStep.object;
|
|
24
|
+
// `record: false` explicitly disables recording — don't start one.
|
|
25
|
+
if (step.record === false) {
|
|
26
|
+
result.status = "SKIPPED";
|
|
27
|
+
result.description = "Recording is disabled (record: false).";
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
22
30
|
// Convert boolean to string
|
|
23
31
|
if (typeof step.record === "boolean") {
|
|
24
32
|
step.record = { path: `${step.stepId}.mp4` };
|
|
@@ -40,12 +48,6 @@ async function startRecording({ config, context, step, driver }) {
|
|
|
40
48
|
...step.record,
|
|
41
49
|
overwrite: step.record.overwrite || "false",
|
|
42
50
|
};
|
|
43
|
-
// If headless is true, skip recording
|
|
44
|
-
if (context.browser?.headless) {
|
|
45
|
-
result.status = "SKIPPED";
|
|
46
|
-
result.description = `Recording isn't supported in headless mode.`;
|
|
47
|
-
return result;
|
|
48
|
-
}
|
|
49
51
|
// Set file name
|
|
50
52
|
let filePath = step.record.path;
|
|
51
53
|
const baseName = path.basename(filePath, path.extname(filePath));
|
|
@@ -62,14 +64,46 @@ async function startRecording({ config, context, step, driver }) {
|
|
|
62
64
|
result.description = `File already exists: ${filePath}`;
|
|
63
65
|
return result;
|
|
64
66
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
// Resolve which engine to use. The context's browser is already coerced by
|
|
68
|
+
// the runner (headed Chrome preferred when nothing was specified), so this
|
|
69
|
+
// is a pure read.
|
|
70
|
+
const plan = resolveRecordPlan({ step, context });
|
|
71
|
+
if (plan.name === "browser") {
|
|
72
|
+
// Browser engine: capture the Chrome viewport via getDisplayMedia +
|
|
73
|
+
// MediaRecorder. Concurrency-safe — each context auto-selects its own
|
|
74
|
+
// window by a unique title. Requires headed Chrome.
|
|
75
|
+
if (context.browser?.headless) {
|
|
76
|
+
result.status = "SKIPPED";
|
|
77
|
+
result.description = `Recording isn't supported in headless mode with the browser engine. Use the ffmpeg engine to record headless.`;
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
if (context.browser?.name !== "chrome") {
|
|
81
|
+
result.status = "SKIPPED";
|
|
82
|
+
result.description = `The browser recording engine requires Chrome. Use the ffmpeg engine for '${context.browser?.name}'.`;
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
const captureTitle = browserCaptureTitle(context.contextId);
|
|
86
|
+
const downloadDir = browserDownloadDir(context.contextId);
|
|
87
|
+
if (!fs.existsSync(downloadDir)) {
|
|
88
|
+
fs.mkdirSync(downloadDir, { recursive: true });
|
|
89
|
+
}
|
|
90
|
+
const downloadPath = path.join(downloadDir, `${baseName}.webm`);
|
|
91
|
+
// Remove any stale download from a previous crashed run — otherwise Chrome
|
|
92
|
+
// saves as "<name> (1).webm" and stopRecording waits on the wrong path.
|
|
93
|
+
if (fs.existsSync(downloadPath)) {
|
|
94
|
+
try {
|
|
95
|
+
fs.unlinkSync(downloadPath);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* best-effort */
|
|
99
|
+
}
|
|
100
|
+
}
|
|
68
101
|
// Get document title
|
|
69
102
|
const documentTitle = await driver.getTitle();
|
|
70
103
|
const originalTab = await driver.getWindowHandle();
|
|
71
|
-
// Set document title to
|
|
72
|
-
|
|
104
|
+
// Set document title to the per-context capture title so the launch flag
|
|
105
|
+
// --auto-select-desktop-capture-source picks exactly this window.
|
|
106
|
+
await driver.execute((title) => (document.title = title), captureTitle);
|
|
73
107
|
// Instantiate cursor
|
|
74
108
|
await instantiateCursor(driver, { position: "center" });
|
|
75
109
|
// Create new tab
|
|
@@ -177,17 +211,111 @@ async function startRecording({ config, context, step, driver }) {
|
|
|
177
211
|
result.recording = {
|
|
178
212
|
type: "MediaRecorder",
|
|
179
213
|
tab: recorderTab.handle,
|
|
180
|
-
downloadPath
|
|
214
|
+
downloadPath, // Where the recording will be downloaded.
|
|
181
215
|
targetPath: filePath, // Where the recording will be saved.
|
|
182
216
|
};
|
|
217
|
+
return result;
|
|
183
218
|
}
|
|
184
|
-
|
|
185
|
-
|
|
219
|
+
// ffmpeg engine: capture the screen with ffmpeg. Works for any application.
|
|
220
|
+
// window/viewport targets capture the full display and are cropped during
|
|
221
|
+
// stopRecording's transcode.
|
|
222
|
+
// A headless browser has no on-screen content to capture. ffmpeg headless
|
|
223
|
+
// recording is only meaningful against a virtual display (Linux Xvfb),
|
|
224
|
+
// threaded in as context.__display. Without one, skip — matching the
|
|
225
|
+
// long-standing "recording isn't supported headless" behavior.
|
|
226
|
+
if (context.browser?.headless && !context.__display) {
|
|
186
227
|
result.status = "SKIPPED";
|
|
187
|
-
result.description = `Recording
|
|
228
|
+
result.description = `Recording isn't supported in headless mode without a virtual display (Xvfb).`;
|
|
188
229
|
return result;
|
|
189
230
|
}
|
|
190
|
-
|
|
231
|
+
let crop = null;
|
|
232
|
+
if (driver && plan.target !== "display") {
|
|
233
|
+
try {
|
|
234
|
+
crop = await resolveCropGeometry({ driver, target: plan.target });
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
log(config, "warning", `Couldn't resolve ${plan.target} geometry for recording; capturing the full display. ${err}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Show the synthetic cursor in the page so automated actions are visible
|
|
241
|
+
// (WebDriver doesn't move the OS pointer).
|
|
242
|
+
if (driver) {
|
|
243
|
+
try {
|
|
244
|
+
await instantiateCursor(driver, { position: "center" });
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
/* non-fatal */
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const tempDir = path.join(os.tmpdir(), "doc-detective", "recordings");
|
|
251
|
+
if (!fs.existsSync(tempDir))
|
|
252
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
253
|
+
const tempPath = path.join(tempDir, `${safeContextId(context.contextId)}-${baseName}.mkv`);
|
|
254
|
+
let ffmpegPath;
|
|
255
|
+
try {
|
|
256
|
+
ffmpegPath = await getFfmpegPath({ cacheDir: config?.cacheDir });
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
result.status = "FAIL";
|
|
260
|
+
result.description = `Couldn't start recording: ${err}`;
|
|
261
|
+
log(config, "error", result.description);
|
|
262
|
+
return result;
|
|
263
|
+
}
|
|
264
|
+
// On macOS the avfoundation screen device index isn't fixed (it shifts with
|
|
265
|
+
// attached cameras), so detect it rather than guessing.
|
|
266
|
+
let screenIndex;
|
|
267
|
+
if (process.platform === "darwin") {
|
|
268
|
+
screenIndex = (await detectMacScreenIndex(ffmpegPath)) ?? undefined;
|
|
269
|
+
}
|
|
270
|
+
const displayEnv = context.__display || process.env.DISPLAY;
|
|
271
|
+
// On Linux, x11grab must be told the screen size or the bundled ffmpeg only
|
|
272
|
+
// grabs a 640x480 corner. Use the known Xvfb size when threaded, else detect
|
|
273
|
+
// the real display's size.
|
|
274
|
+
let screenSize;
|
|
275
|
+
if (process.platform === "linux") {
|
|
276
|
+
screenSize =
|
|
277
|
+
context.__displaySize ||
|
|
278
|
+
(await detectX11ScreenSize(displayEnv)) ||
|
|
279
|
+
undefined;
|
|
280
|
+
}
|
|
281
|
+
const args = buildCaptureArgs({
|
|
282
|
+
platform: process.platform,
|
|
283
|
+
fps: plan.fps,
|
|
284
|
+
// Honor a per-context virtual display (Linux Xvfb) when threaded through.
|
|
285
|
+
displayEnv,
|
|
286
|
+
outputPath: tempPath,
|
|
287
|
+
screenIndex,
|
|
288
|
+
screenSize,
|
|
289
|
+
});
|
|
290
|
+
log(config, "debug", `ffmpeg recording: platform=${process.platform} target=${plan.target}${screenIndex !== undefined ? ` screen=${screenIndex}` : ""}${context.__display ? ` display=${context.__display}` : ""} -> ${tempPath}`);
|
|
291
|
+
const proc = spawn(ffmpegPath, args, { stdio: ["pipe", "ignore", "pipe"] });
|
|
292
|
+
let spawnError = null;
|
|
293
|
+
// Drain ffmpeg's stderr into a bounded tail: it both prevents the unread
|
|
294
|
+
// pipe from filling and blocking ffmpeg, and surfaces the real reason on a
|
|
295
|
+
// start failure (wrong device index, denied screen-recording permission…).
|
|
296
|
+
let stderrTail = "";
|
|
297
|
+
proc.stderr?.on("data", (d) => {
|
|
298
|
+
stderrTail = (stderrTail + d.toString()).slice(-2000);
|
|
299
|
+
});
|
|
300
|
+
proc.on("error", (err) => {
|
|
301
|
+
spawnError = err;
|
|
302
|
+
});
|
|
303
|
+
// Give ffmpeg a moment to initialize, then make sure it didn't immediately
|
|
304
|
+
// fail (e.g. missing display, permission denied).
|
|
305
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
306
|
+
if (spawnError || proc.exitCode !== null) {
|
|
307
|
+
result.status = "FAIL";
|
|
308
|
+
result.description = `Couldn't start ffmpeg recording.${spawnError ? ` ${spawnError}` : ` ffmpeg exited with code ${proc.exitCode}.`} On macOS, grant screen recording permission; on Linux, ensure a display (or Xvfb) is available.${stderrTail ? ` ffmpeg: ${stderrTail.trim().slice(-500)}` : ""}`;
|
|
309
|
+
log(config, "error", result.description);
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
result.recording = {
|
|
313
|
+
type: "ffmpeg",
|
|
314
|
+
process: proc,
|
|
315
|
+
tempPath,
|
|
316
|
+
targetPath: filePath,
|
|
317
|
+
crop,
|
|
318
|
+
};
|
|
191
319
|
return result;
|
|
192
320
|
}
|
|
193
321
|
//# sourceMappingURL=startRecording.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startRecording.js","sourceRoot":"","sources":["../../../src/core/tests/startRecording.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,KAAK,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAyD;IACpH,IAAI,MAAM,GAAQ;QAChB,MAAM,EAAE,MAAM;QACd,WAAW,EAAE,oBAAoB;KAClC,CAAC;IAEF,wBAAwB;IACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,4BAA4B,WAAW,CAAC,MAAM,EAAE,CAAC;QACtE,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,sCAAsC;IACtC,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC;IAE1B,4BAA4B;IAC5B,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,MAAM,EAAE,CAAC;IAC/C,CAAC;IACD,2BAA2B;IAC3B,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACtC,CAAC;IACD,wBAAwB;IACxB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,MAAM,CAAC;QACxC,gDAAgD;QAChD,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,qBAAqB;IACrB,IAAI,CAAC,MAAM,GAAG;QACZ,GAAG,IAAI,CAAC,MAAM;QACd,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,OAAO;KAC5C,CAAC;IAEF,sCAAsC;IACtC,IAAI,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;QAC1B,MAAM,CAAC,WAAW,GAAG,6CAA6C,CAAC;QACnE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,gBAAgB;IAChB,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEjE,qBAAqB;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3C,oCAAoC;IACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,+BAA+B;IAC/B,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;QAChE,sBAAsB;QACtB,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;QAC1B,MAAM,CAAC,WAAW,GAAG,wBAAwB,QAAQ,EAAE,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IACE,OAAO,EAAE,OAAO,EAAE,IAAI,KAAK,QAAQ;QACnC,OAAO,EAAE,OAAO,EAAE,QAAQ,KAAK,KAAK,EACpC,CAAC;QACD,sBAAsB;QACtB,qBAAqB;QACrB,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;QACnD,oCAAoC;QACpC,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC;QAC3D,qBAAqB;QACrB,MAAM,iBAAiB,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,iBAAiB;QACjB,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACrD,oBAAoB;QACpB,MAAM,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC1C,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC;QAE1D,kBAAkB;QAClB,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,QAAa,EAAE,IAAS,EAAE,EAAE;YAC7E,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAE,EAAE;gBAClC,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,UAAU,GAAG,IAAI,CAAC;oBAClB,IAAI,CAAC,KAAK,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC;YACF,IAAI,MAAW,CAAC;YAChB,MAAM,mBAAmB,GAAG;gBAC1B,KAAK,EAAE;oBACL,cAAc,EAAE,SAAS;iBAC1B;gBACD,KAAK,EAAE;oBACL,0BAA0B,EAAE,KAAK;iBAClC;gBACD,gBAAgB,EAAE,KAAK;gBACvB,kBAAkB,EAAE,SAAS;gBAC7B,WAAW,EAAE,SAAS;gBACtB,gBAAgB,EAAE,SAAS;gBAC3B,mBAAmB,EAAE,SAAS;aAC/B,CAAC;YACF,KAAK,UAAU,YAAY,CAAC,mBAAwB;gBAClD,IAAI,CAAC;oBACH,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,eAAe,CAChE,mBAAmB,CACpB,CAAC;oBACF,OAAO,aAAa,CAAC;gBACvB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;oBAC/B,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,KAAK,UAAU,kBAAkB;gBAC/B,IAAI,CAAC;oBACH,MAAM,GAAG,MAAM,YAAY,CAAC,mBAAmB,CAAC,CAAC;oBACjD,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,QAAQ,CAAC,KAAK,CAAC,CAAC;wBAChB,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;gBAC7B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;oBAC/B,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAClB,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,KAAK,UAAU,YAAY,CAAC,MAAW;gBACpC,MAAc,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,iBAAiB;gBACnG,MAAM,IAAI,GAAU,EAAE,CAAC;gBAEtB,MAAc,CAAC,QAAQ,CAAC,eAAe,GAAG,CAAC,KAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChF,MAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACjC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAEf,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC3C,MAAc,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC;oBACzC,MAAc,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,KAAU,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACxE,CAAC,CAAC,CAAC;gBAEH,MAAM,OAAO,CAAC;gBAEd,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;gBACpD,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;gBACtC,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBACtC,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;gBACzB,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;gBACb,CAAC,CAAC,QAAQ,GAAG,GAAG,QAAQ,OAAO,CAAC;gBAChC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBAC7B,CAAC,CAAC,KAAK,EAAE,CAAC;gBACV,UAAU,CAAC,GAAG,EAAE;oBACd,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;oBAC7B,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;gBAClC,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;YACD,kBAAkB,EAAE,CAAC;QACvB,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEb,2BAA2B;QAC3B,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,MAAM,CAAC,WAAW;gBAChB,qEAAqE;oBACrE,6DAA6D;oBAC7D,6DAA6D,CAAC;YAChE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YACzC,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC3B,MAAM,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YACzC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,aAAkB,EAAE,EAAE;gBAC1C,QAAQ,CAAC,KAAK,GAAG,aAAa,CAAC;YACjC,CAAC,EAAE,aAAa,CAAC,CAAC;YAClB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACzC,sCAAsC;QACtC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,aAAkB,EAAE,EAAE;YAC1C,QAAQ,CAAC,KAAK,GAAG,aAAa,CAAC;QACjC,CAAC,EAAE,aAAa,CAAC,CAAC;QAClB,eAAe;QACf,MAAM,CAAC,SAAS,GAAG;YACjB,IAAI,EAAE,eAAe;YACrB,GAAG,EAAE,WAAW,CAAC,MAAM;YACvB,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,0CAA0C;YACpG,UAAU,EAAE,QAAQ,EAAE,qCAAqC;SAC5D,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,0CAA0C;QAC1C,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;QAC1B,MAAM,CAAC,WAAW,GAAG,8CAA8C,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO;IACP,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"startRecording.js","sourceRoot":"","sources":["../../../src/core/tests/startRecording.ts"],"names":[],"mappings":"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"}
|