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.
@@ -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":"AAOA,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,gBAwMrH"}
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
- if (context?.browser?.name === "chrome" &&
66
- context?.browser?.headless === false) {
67
- // Chrome and Chromium
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 "RECORD_ME"
72
- await driver.execute(() => (document.title = "RECORD_ME"));
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: path.join(os.tmpdir(), `${baseName}.webm`), // Where the recording will be downloaded.
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
- else {
185
- // Other context recording not supported
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 is not supported for this context.`;
228
+ result.description = `Recording isn't supported in headless mode without a virtual display (Xvfb).`;
188
229
  return result;
189
230
  }
190
- // PASS
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":"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"}
1
+ {"version":3,"file":"startRecording.js","sourceRoot":"","sources":["../../../src/core/tests/startRecording.ts"],"names":[],"mappings":"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"}