@vforsh/argus-watcher 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/cdp/mouse.d.ts +19 -3
  3. package/dist/cdp/mouse.d.ts.map +1 -1
  4. package/dist/cdp/mouse.js +57 -9
  5. package/dist/cdp/mouse.js.map +1 -1
  6. package/dist/cdp/pageIndicator.d.ts +5 -0
  7. package/dist/cdp/pageIndicator.d.ts.map +1 -1
  8. package/dist/cdp/pageIndicator.js +21 -5
  9. package/dist/cdp/pageIndicator.js.map +1 -1
  10. package/dist/cdp/pageIndicatorScript.d.ts +4 -3
  11. package/dist/cdp/pageIndicatorScript.d.ts.map +1 -1
  12. package/dist/cdp/pageIndicatorScript.js +61 -7
  13. package/dist/cdp/pageIndicatorScript.js.map +1 -1
  14. package/dist/cdp/recording.d.ts +15 -0
  15. package/dist/cdp/recording.d.ts.map +1 -0
  16. package/dist/cdp/recording.js +389 -0
  17. package/dist/cdp/recording.js.map +1 -0
  18. package/dist/cdp/screenshot.d.ts.map +1 -1
  19. package/dist/cdp/screenshot.js +2 -133
  20. package/dist/cdp/screenshot.js.map +1 -1
  21. package/dist/cdp/visualCapture.d.ts +38 -0
  22. package/dist/cdp/visualCapture.d.ts.map +1 -0
  23. package/dist/cdp/visualCapture.js +156 -0
  24. package/dist/cdp/visualCapture.js.map +1 -0
  25. package/dist/events.d.ts +1 -1
  26. package/dist/events.d.ts.map +1 -1
  27. package/dist/http/routes/getExtensionDiagnostics.d.ts +2 -0
  28. package/dist/http/routes/getExtensionDiagnostics.d.ts.map +1 -0
  29. package/dist/http/routes/getExtensionDiagnostics.js +16 -0
  30. package/dist/http/routes/getExtensionDiagnostics.js.map +1 -0
  31. package/dist/http/routes/index.d.ts.map +1 -1
  32. package/dist/http/routes/index.js +6 -0
  33. package/dist/http/routes/index.js.map +1 -1
  34. package/dist/http/routes/postAttach.d.ts.map +1 -1
  35. package/dist/http/routes/postAttach.js +6 -3
  36. package/dist/http/routes/postAttach.js.map +1 -1
  37. package/dist/http/routes/postDetach.d.ts.map +1 -1
  38. package/dist/http/routes/postDetach.js +6 -3
  39. package/dist/http/routes/postDetach.js.map +1 -1
  40. package/dist/http/routes/postDomClick.d.ts.map +1 -1
  41. package/dist/http/routes/postDomClick.js +12 -20
  42. package/dist/http/routes/postDomClick.js.map +1 -1
  43. package/dist/http/routes/postDomDrag.d.ts +2 -0
  44. package/dist/http/routes/postDomDrag.d.ts.map +1 -0
  45. package/dist/http/routes/postDomDrag.js +54 -0
  46. package/dist/http/routes/postDomDrag.js.map +1 -0
  47. package/dist/http/routes/postRecord.d.ts +3 -0
  48. package/dist/http/routes/postRecord.d.ts.map +1 -0
  49. package/dist/http/routes/postRecord.js +88 -0
  50. package/dist/http/routes/postRecord.js.map +1 -0
  51. package/dist/http/server.d.ts +3 -1
  52. package/dist/http/server.d.ts.map +1 -1
  53. package/dist/http/server.js.map +1 -1
  54. package/dist/native-messaging/control-session-manager.d.ts +24 -4
  55. package/dist/native-messaging/control-session-manager.d.ts.map +1 -1
  56. package/dist/native-messaging/control-session-manager.js +69 -23
  57. package/dist/native-messaging/control-session-manager.js.map +1 -1
  58. package/dist/native-messaging/types.d.ts +62 -3
  59. package/dist/native-messaging/types.d.ts.map +1 -1
  60. package/dist/runtime/watcherServices.d.ts +3 -0
  61. package/dist/runtime/watcherServices.d.ts.map +1 -1
  62. package/dist/runtime/watcherServices.js +12 -0
  63. package/dist/runtime/watcherServices.js.map +1 -1
  64. package/dist/sources/extension-control-source.d.ts.map +1 -1
  65. package/dist/sources/extension-control-source.js +25 -4
  66. package/dist/sources/extension-control-source.js.map +1 -1
  67. package/dist/sources/extension-source.d.ts.map +1 -1
  68. package/dist/sources/extension-source.js +16 -3
  69. package/dist/sources/extension-source.js.map +1 -1
  70. package/dist/sources/types.d.ts +7 -3
  71. package/dist/sources/types.d.ts.map +1 -1
  72. package/dist/startWatcherRuntime.d.ts.map +1 -1
  73. package/dist/startWatcherRuntime.js +7 -1
  74. package/dist/startWatcherRuntime.js.map +1 -1
  75. package/package.json +1 -1
@@ -0,0 +1,389 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import crypto from 'node:crypto';
4
+ import { spawn } from 'node:child_process';
5
+ import { ensureArtifactsDir, ensureParentDir, resolveArtifactPath } from '../artifacts.js';
6
+ import { createVisualCapturePlan } from './visualCapture.js';
7
+ const DEFAULT_RECORD_FPS = 30;
8
+ const FIRST_FRAME_TIMEOUT_MS = 2_000;
9
+ export const createRecorder = (options) => {
10
+ let active = null;
11
+ const capture = async (request) => {
12
+ await start(request);
13
+ await delay(request.durationMs);
14
+ return stop({});
15
+ };
16
+ const start = async (request) => {
17
+ if (active) {
18
+ throw new Error('Recording already active');
19
+ }
20
+ await ensureArtifactsDir(options.artifactsDir);
21
+ const format = resolveRecordFormat(request);
22
+ const fps = normalizeFps(request.fps);
23
+ const recordId = crypto.randomUUID();
24
+ const sessionName = `record-${new Date().toISOString().replace(/[:.]/g, '-')}`;
25
+ const defaultName = `recordings/${sessionName}.${format}`;
26
+ const { absolutePath, displayPath } = resolveArtifactPath(options.artifactsDir, request.outFile, defaultName);
27
+ validateOutputPathFormat(displayPath, format);
28
+ await ensureParentDir(absolutePath);
29
+ const capturePlan = await createVisualCapturePlan(options.session, options.pageSession, request);
30
+ const firstFrameDeferred = createDeferred();
31
+ const state = {
32
+ recordId,
33
+ sessionName,
34
+ absolutePath: path.resolve(absolutePath),
35
+ outFile: displayPath,
36
+ session: capturePlan.session,
37
+ removeFrameHandler: () => { },
38
+ ffmpeg: null,
39
+ firstFrame: firstFrameDeferred.promise,
40
+ resolveFirstFrame: firstFrameDeferred.resolve,
41
+ rejectFirstFrame: firstFrameDeferred.reject,
42
+ firstFrameTimer: setTimeout(() => {
43
+ firstFrameDeferred.reject(new Error('No screencast frames received. Make the page visible with `argus page show <id>` and try again.'));
44
+ }, FIRST_FRAME_TIMEOUT_MS),
45
+ sampleTimer: null,
46
+ latestFrame: null,
47
+ pendingFrameCount: 0,
48
+ pumpBlocked: false,
49
+ frameCount: 0,
50
+ startedAt: Date.now(),
51
+ capturedDurationMs: null,
52
+ fps,
53
+ format,
54
+ clip: capturePlan.clip,
55
+ viewport: capturePlan.viewport,
56
+ state: 'starting',
57
+ };
58
+ active = state;
59
+ try {
60
+ state.removeFrameHandler = state.session.onEvent('Page.screencastFrame', (params) => {
61
+ handleScreencastFrame(state, params);
62
+ });
63
+ await state.session.sendAndWait('Page.startScreencast', { format: 'png', everyNthFrame: 1 });
64
+ const firstFrame = await state.firstFrame;
65
+ clearTimeout(state.firstFrameTimer);
66
+ const frameSize = readPngSize(firstFrame);
67
+ state.ffmpeg = await startFfmpeg({
68
+ absolutePath: state.absolutePath,
69
+ fps,
70
+ format,
71
+ clip: state.clip,
72
+ viewport: state.viewport,
73
+ frameSize,
74
+ });
75
+ state.state = 'recording';
76
+ state.startedAt = Date.now();
77
+ queueFrameSample(state);
78
+ state.sampleTimer = setInterval(() => queueFrameSample(state), Math.round(1000 / fps));
79
+ options.onRecordingStateChange?.(true);
80
+ return {
81
+ ok: true,
82
+ recordId,
83
+ sessionName,
84
+ outFile: displayPath,
85
+ format,
86
+ fps,
87
+ clipped: Boolean(state.clip),
88
+ };
89
+ }
90
+ catch (error) {
91
+ active = null;
92
+ await cleanupFailedStart(state, error);
93
+ throw error;
94
+ }
95
+ };
96
+ const stop = async (request) => {
97
+ const state = active;
98
+ if (!state) {
99
+ throw new Error('No active recording to stop');
100
+ }
101
+ if (request.recordId && request.recordId !== state.recordId) {
102
+ throw new Error('Record id does not match active recording');
103
+ }
104
+ if (state.state === 'stopping') {
105
+ await state.ffmpeg?.completion;
106
+ await resolveFinalPath(state, request.outFile);
107
+ return buildStopResponse(state);
108
+ }
109
+ state.state = 'stopping';
110
+ clearRecordingTimers(state);
111
+ state.removeFrameHandler();
112
+ state.capturedDurationMs = Math.max(0, Date.now() - state.startedAt);
113
+ try {
114
+ await state.session.sendAndWait('Page.stopScreencast', {}, { timeoutMs: 5_000 }).catch(() => { });
115
+ queueMissingDurationFrames(state);
116
+ await flushQueuedFrames(state);
117
+ state.ffmpeg?.child.stdin.end();
118
+ await state.ffmpeg?.completion;
119
+ await resolveFinalPath(state, request.outFile);
120
+ return buildStopResponse(state);
121
+ }
122
+ finally {
123
+ if (active === state) {
124
+ active = null;
125
+ }
126
+ options.onRecordingStateChange?.(false);
127
+ }
128
+ };
129
+ const onDetached = (reason) => {
130
+ const state = active;
131
+ if (!state) {
132
+ return;
133
+ }
134
+ active = null;
135
+ clearRecordingTimers(state);
136
+ state.removeFrameHandler();
137
+ state.rejectFirstFrame(new Error(reason ?? 'CDP detached while recording'));
138
+ state.ffmpeg?.child.kill('SIGTERM');
139
+ options.onRecordingStateChange?.(false);
140
+ };
141
+ return { capture, start, stop, onDetached };
142
+ async function resolveFinalPath(state, outFile) {
143
+ if (!outFile?.trim()) {
144
+ return;
145
+ }
146
+ const { absolutePath, displayPath } = resolveArtifactPath(options.artifactsDir, outFile, `recordings/${state.sessionName}.${state.format}`);
147
+ validateOutputPathFormat(displayPath, state.format);
148
+ if (path.resolve(absolutePath) === state.absolutePath) {
149
+ return;
150
+ }
151
+ await ensureParentDir(absolutePath);
152
+ try {
153
+ await fs.rename(state.absolutePath, absolutePath);
154
+ }
155
+ catch (error) {
156
+ const nodeError = error;
157
+ if (nodeError.code !== 'EXDEV') {
158
+ throw error;
159
+ }
160
+ await fs.copyFile(state.absolutePath, absolutePath);
161
+ await fs.unlink(state.absolutePath);
162
+ }
163
+ state.absolutePath = path.resolve(absolutePath);
164
+ state.outFile = displayPath;
165
+ }
166
+ };
167
+ const handleScreencastFrame = (state, params) => {
168
+ const payload = params;
169
+ if (typeof payload.data !== 'string') {
170
+ return;
171
+ }
172
+ const frame = Buffer.from(payload.data, 'base64');
173
+ state.latestFrame = frame;
174
+ state.resolveFirstFrame(frame);
175
+ if (typeof payload.sessionId === 'number') {
176
+ void state.session.sendAndWait('Page.screencastFrameAck', { sessionId: payload.sessionId }).catch(() => { });
177
+ }
178
+ };
179
+ const queueFrameSample = (state) => {
180
+ if (!state.latestFrame || state.state !== 'recording') {
181
+ return;
182
+ }
183
+ state.pendingFrameCount += 1;
184
+ pumpQueuedFrames(state);
185
+ };
186
+ const queueMissingDurationFrames = (state) => {
187
+ if (!state.latestFrame) {
188
+ return;
189
+ }
190
+ const elapsedMs = state.capturedDurationMs ?? Math.max(0, Date.now() - state.startedAt);
191
+ const targetFrameCount = Math.max(1, Math.round((elapsedMs / 1000) * state.fps));
192
+ const queuedOrWritten = state.frameCount + state.pendingFrameCount;
193
+ if (queuedOrWritten < targetFrameCount) {
194
+ state.pendingFrameCount += targetFrameCount - queuedOrWritten;
195
+ }
196
+ };
197
+ const flushQueuedFrames = async (state) => {
198
+ pumpQueuedFrames(state);
199
+ while (state.pendingFrameCount > 0 || state.pumpBlocked) {
200
+ if (!state.ffmpeg || state.ffmpeg.child.stdin.destroyed) {
201
+ return;
202
+ }
203
+ await delay(10);
204
+ pumpQueuedFrames(state);
205
+ }
206
+ };
207
+ const pumpQueuedFrames = (state) => {
208
+ if (!state.latestFrame || !state.ffmpeg || state.pumpBlocked || state.ffmpeg.child.stdin.destroyed) {
209
+ return;
210
+ }
211
+ while (state.pendingFrameCount > 0) {
212
+ state.pendingFrameCount -= 1;
213
+ state.frameCount += 1;
214
+ const ready = state.ffmpeg.child.stdin.write(state.latestFrame);
215
+ if (!ready) {
216
+ state.pumpBlocked = true;
217
+ state.ffmpeg.child.stdin.once('drain', () => {
218
+ state.pumpBlocked = false;
219
+ pumpQueuedFrames(state);
220
+ });
221
+ return;
222
+ }
223
+ }
224
+ };
225
+ const startFfmpeg = async (options) => {
226
+ const ffmpeg = process.env.ARGUS_FFMPEG?.trim() || 'ffmpeg';
227
+ const filter = buildVideoFilter(options);
228
+ const args = [
229
+ '-hide_banner',
230
+ '-loglevel',
231
+ 'error',
232
+ '-f',
233
+ 'image2pipe',
234
+ '-framerate',
235
+ String(options.fps),
236
+ '-vcodec',
237
+ 'png',
238
+ '-i',
239
+ 'pipe:0',
240
+ '-an',
241
+ '-vf',
242
+ filter,
243
+ ...buildEncoderArgs(options.format),
244
+ '-y',
245
+ options.absolutePath,
246
+ ];
247
+ const child = spawn(ffmpeg, args, { stdio: ['pipe', 'ignore', 'pipe'] });
248
+ let stderr = '';
249
+ child.stderr.setEncoding('utf8');
250
+ child.stderr.on('data', (chunk) => {
251
+ stderr = `${stderr}${chunk}`.slice(-4000);
252
+ });
253
+ const completion = new Promise((resolve, reject) => {
254
+ child.once('error', (error) => reject(formatFfmpegError(error)));
255
+ child.once('close', (code) => {
256
+ if (code === 0) {
257
+ resolve();
258
+ return;
259
+ }
260
+ reject(new Error(`ffmpeg failed with exit code ${code ?? 'unknown'}${stderr ? `: ${stderr.trim()}` : ''}`));
261
+ });
262
+ });
263
+ void completion.catch(() => { });
264
+ await new Promise((resolve, reject) => {
265
+ child.once('spawn', () => resolve());
266
+ child.once('error', (error) => reject(formatFfmpegError(error)));
267
+ });
268
+ return { child, completion };
269
+ };
270
+ const buildVideoFilter = (options) => {
271
+ if (!options.clip) {
272
+ return 'scale=trunc(iw/2)*2:trunc(ih/2)*2,format=yuv420p';
273
+ }
274
+ if (!options.viewport) {
275
+ throw new Error('Unable to compute viewport size for recording crop');
276
+ }
277
+ const ratioX = options.frameSize.width / options.viewport.width;
278
+ const ratioY = options.frameSize.height / options.viewport.height;
279
+ const x = clampEven(options.clip.x * ratioX, 0, options.frameSize.width - 2);
280
+ const y = clampEven(options.clip.y * ratioY, 0, options.frameSize.height - 2);
281
+ const width = clampEven(options.clip.width * ratioX, 2, options.frameSize.width - x);
282
+ const height = clampEven(options.clip.height * ratioY, 2, options.frameSize.height - y);
283
+ return `crop=${width}:${height}:${x}:${y},format=yuv420p`;
284
+ };
285
+ const cleanupFailedStart = async (state, error) => {
286
+ clearRecordingTimers(state);
287
+ state.removeFrameHandler();
288
+ await state.session.sendAndWait('Page.stopScreencast', {}, { timeoutMs: 5_000 }).catch(() => { });
289
+ state.ffmpeg?.child.kill('SIGTERM');
290
+ state.ffmpeg?.child.stdin.destroy();
291
+ try {
292
+ await fs.unlink(state.absolutePath);
293
+ }
294
+ catch {
295
+ // Best effort: the encoder may not have created the file yet.
296
+ }
297
+ if (error instanceof Error && error.message.startsWith('spawn ffmpeg ENOENT')) {
298
+ throw formatFfmpegError(error);
299
+ }
300
+ };
301
+ const clearRecordingTimers = (state) => {
302
+ clearTimeout(state.firstFrameTimer);
303
+ if (state.sampleTimer) {
304
+ clearInterval(state.sampleTimer);
305
+ state.sampleTimer = null;
306
+ }
307
+ };
308
+ const buildStopResponse = (state) => ({
309
+ ok: true,
310
+ recordId: state.recordId,
311
+ sessionName: state.sessionName,
312
+ outFile: state.outFile,
313
+ format: state.format,
314
+ frameCount: state.frameCount,
315
+ durationMs: state.capturedDurationMs ?? Math.max(0, Date.now() - state.startedAt),
316
+ fps: state.fps,
317
+ clipped: Boolean(state.clip),
318
+ });
319
+ const normalizeFps = (fps) => {
320
+ if (fps == null) {
321
+ return DEFAULT_RECORD_FPS;
322
+ }
323
+ return Math.min(60, Math.max(1, Math.round(fps)));
324
+ };
325
+ const resolveRecordFormat = (request) => request.format ?? inferRecordFormatFromPath(request.outFile) ?? 'mp4';
326
+ const inferRecordFormatFromPath = (outFile) => {
327
+ const ext = path.extname(outFile?.trim() ?? '').toLowerCase();
328
+ if (ext === '.mp4')
329
+ return 'mp4';
330
+ if (ext === '.webm')
331
+ return 'webm';
332
+ return undefined;
333
+ };
334
+ const validateOutputPathFormat = (outFile, format) => {
335
+ const ext = path.extname(outFile.trim()).toLowerCase();
336
+ if (ext && ext !== '.mp4' && ext !== '.webm') {
337
+ throw new Error('Recording output must use .mp4 or .webm when an extension is provided');
338
+ }
339
+ const inferred = inferRecordFormatFromPath(outFile);
340
+ if (inferred && inferred !== format) {
341
+ throw new Error(`Output extension .${inferred} does not match recording format ${format}`);
342
+ }
343
+ };
344
+ const buildEncoderArgs = (format) => {
345
+ if (format === 'webm') {
346
+ return ['-c:v', 'libvpx', '-deadline', 'realtime', '-cpu-used', '5', '-b:v', '1M', '-f', 'webm'];
347
+ }
348
+ // yuv420p + H.264 keeps files playable in Finder, QuickTime, iOS Photos, Slack, and browsers.
349
+ return ['-c:v', 'libx264', '-preset', 'veryfast', '-crf', '23', '-movflags', '+faststart', '-f', 'mp4'];
350
+ };
351
+ const readPngSize = (buffer) => {
352
+ if (buffer.length < 24 ||
353
+ buffer[0] !== 0x89 ||
354
+ buffer[1] !== 0x50 ||
355
+ buffer[2] !== 0x4e ||
356
+ buffer[3] !== 0x47 ||
357
+ buffer[4] !== 0x0d ||
358
+ buffer[5] !== 0x0a ||
359
+ buffer[6] !== 0x1a ||
360
+ buffer[7] !== 0x0a) {
361
+ throw new Error('Expected PNG screencast frame');
362
+ }
363
+ return {
364
+ width: buffer.readUInt32BE(16),
365
+ height: buffer.readUInt32BE(20),
366
+ };
367
+ };
368
+ const clampEven = (value, min, max) => {
369
+ const clamped = Math.min(max, Math.max(min, Math.floor(value)));
370
+ return Math.max(2, Math.floor(clamped / 2) * 2);
371
+ };
372
+ const formatFfmpegError = (error) => {
373
+ const nodeError = error;
374
+ if (nodeError.code === 'ENOENT') {
375
+ return new Error('ffmpeg not found. Install ffmpeg or pass ARGUS_FFMPEG=/path/to/ffmpeg.');
376
+ }
377
+ return error instanceof Error ? error : new Error(String(error));
378
+ };
379
+ const createDeferred = () => {
380
+ let resolve;
381
+ let reject;
382
+ const promise = new Promise((nextResolve, nextReject) => {
383
+ resolve = nextResolve;
384
+ reject = nextReject;
385
+ });
386
+ return { promise, resolve, reject };
387
+ };
388
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
389
+ //# sourceMappingURL=recording.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording.js","sourceRoot":"","sources":["../../src/cdp/recording.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/cdp/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACrG,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,iBAAiB,CAAA;AAqBzE,MAAM,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;CACpE,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,SAAS;IAAE,OAAO,EAAE,gBAAgB,CAAC;IAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,KAAG,aAuBlI,CAAA"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/cdp/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAYvD,MAAM,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;CACpE,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,SAAS;IAAE,OAAO,EAAE,gBAAgB,CAAC;IAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,KAAG,aAuBlI,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import { ensureArtifactsDir, ensureParentDir, resolveArtifactPath } from '../artifacts.js';
3
- import { resolveFirstSelectorNodeId } from './dom/selector.js';
3
+ import { createVisualCapturePlan } from './visualCapture.js';
4
4
  const SCREENSHOT_CDP_TIMEOUT_MS = 20_000;
5
5
  const SCREENSHOT_CDP_MAX_ATTEMPTS = 2;
6
6
  export const createScreenshotter = (options) => {
@@ -13,7 +13,7 @@ export const createScreenshotter = (options) => {
13
13
  const defaultName = `screenshots/${new Date().toISOString().replace(/[:.]/g, '-')}.png`;
14
14
  const { absolutePath, displayPath } = resolveArtifactPath(options.artifactsDir, request.outFile, defaultName);
15
15
  await ensureParentDir(absolutePath);
16
- const capturePlan = await createCapturePlan(options.session, options.pageSession, request);
16
+ const capturePlan = await createVisualCapturePlan(options.session, options.pageSession, request);
17
17
  const result = await captureScreenshot(capturePlan.session, {
18
18
  format,
19
19
  clip: capturePlan.clip,
@@ -23,43 +23,6 @@ export const createScreenshotter = (options) => {
23
23
  };
24
24
  return { capture };
25
25
  };
26
- /**
27
- * `Page.captureScreenshot` only works on top-level page targets.
28
- * When Argus is attached to an iframe through the extension source, we keep using the
29
- * selected frame session for DOM lookups but route the final screenshot through the
30
- * top-level page session with a translated clip rect.
31
- */
32
- const createCapturePlan = async (session, pageSession, request) => {
33
- const subject = resolveCaptureSubject(request);
34
- const targetContext = session.getTargetContext?.();
35
- if (targetContext?.kind === 'frame' && pageSession) {
36
- return createFrameCapturePlan({
37
- frameSession: session,
38
- pageSession,
39
- frameContext: targetContext,
40
- subject,
41
- });
42
- }
43
- const clip = await resolveSubjectClip(session, subject);
44
- if (!clip) {
45
- return { session };
46
- }
47
- return { session, clip };
48
- };
49
- const createFrameCapturePlan = async (options) => {
50
- const frameClip = await resolveFrameViewportClip(options.pageSession, options.frameContext.frameId);
51
- const subjectClip = await resolveSubjectClip(options.frameSession, options.subject);
52
- if (!subjectClip) {
53
- return {
54
- session: options.pageSession,
55
- clip: frameClip,
56
- };
57
- }
58
- return {
59
- session: options.pageSession,
60
- clip: offsetClip(frameClip, subjectClip),
61
- };
62
- };
63
26
  const captureScreenshot = async (session, options) => {
64
27
  let lastError;
65
28
  for (let attempt = 1; attempt <= SCREENSHOT_CDP_MAX_ATTEMPTS; attempt += 1) {
@@ -84,99 +47,5 @@ const captureScreenshot = async (session, options) => {
84
47
  }
85
48
  throw lastError instanceof Error ? lastError : new Error('Failed to capture screenshot');
86
49
  };
87
- const resolveFrameViewportClip = async (pageSession, frameId) => {
88
- const owner = (await pageSession.sendAndWait('DOM.getFrameOwner', {
89
- frameId,
90
- }));
91
- if (owner.backendNodeId == null && owner.nodeId == null) {
92
- throw new Error(`Unable to resolve iframe owner for frame: ${frameId}`);
93
- }
94
- return resolveNodeClip(pageSession, owner);
95
- };
96
- const resolveSelectorClip = async (session, selector) => {
97
- const nodeId = await resolveFirstSelectorNodeId(session, selector);
98
- if (!nodeId) {
99
- throw new Error(`No element found for selector: ${selector}`);
100
- }
101
- return resolveNodeClip(session, { nodeId });
102
- };
103
- const resolveSubjectClip = async (session, subject) => {
104
- switch (subject.kind) {
105
- case 'viewport':
106
- return null;
107
- case 'selector':
108
- return resolveSelectorClip(session, subject.selector);
109
- case 'clip':
110
- return resolveViewportRectClip(session, subject.clip);
111
- }
112
- };
113
- const resolveCaptureSubject = (request) => {
114
- if (request.selector) {
115
- return { kind: 'selector', selector: request.selector };
116
- }
117
- if (request.clip) {
118
- return { kind: 'clip', clip: request.clip };
119
- }
120
- return { kind: 'viewport' };
121
- };
122
- const resolveViewportRectClip = async (session, clip) => {
123
- const viewport = await resolveVisualViewport(session);
124
- return {
125
- x: clip.x,
126
- y: clip.y,
127
- width: clip.width,
128
- height: clip.height,
129
- // CDP clip rectangles always need the current viewport scale, even when x/y are already viewport-relative.
130
- scale: viewport?.scale ?? 1,
131
- };
132
- };
133
- const resolveNodeClip = async (session, target) => {
134
- const boxResult = await session.sendAndWait('DOM.getBoxModel', target.nodeId != null ? { nodeId: target.nodeId } : { backendNodeId: target.backendNodeId });
135
- const quad = boxResult.model?.content ??
136
- boxResult.model?.border;
137
- if (!quad || quad.length < 8) {
138
- throw new Error('Unable to compute element box model');
139
- }
140
- const rect = quadToRect(quad);
141
- if (rect.width <= 0 || rect.height <= 0) {
142
- throw new Error('Element has zero area');
143
- }
144
- const viewport = await resolveVisualViewport(session);
145
- const pageX = viewport?.pageX ?? 0;
146
- const pageY = viewport?.pageY ?? 0;
147
- const scale = viewport?.scale ?? 1;
148
- return {
149
- x: rect.x - pageX,
150
- y: rect.y - pageY,
151
- width: rect.width,
152
- height: rect.height,
153
- scale,
154
- };
155
- };
156
- const resolveVisualViewport = async (session) => {
157
- const metrics = await session.sendAndWait('Page.getLayoutMetrics');
158
- return metrics.visualViewport;
159
- };
160
50
  const isScreenshotTimeout = (error) => error instanceof Error && error.message.startsWith('CDP request timed out after');
161
- const offsetClip = (outer, inner) => ({
162
- x: outer.x + inner.x,
163
- y: outer.y + inner.y,
164
- width: inner.width,
165
- height: inner.height,
166
- scale: outer.scale,
167
- });
168
- const quadToRect = (quad) => {
169
- const xs = [quad[0], quad[2], quad[4], quad[6]];
170
- const ys = [quad[1], quad[3], quad[5], quad[7]];
171
- const minX = Math.min(...xs);
172
- const maxX = Math.max(...xs);
173
- const minY = Math.min(...ys);
174
- const maxY = Math.max(...ys);
175
- return {
176
- x: minX,
177
- y: minY,
178
- width: maxX - minX,
179
- height: maxY - minY,
180
- };
181
- };
182
51
  //# sourceMappingURL=screenshot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/cdp/screenshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/cdp/screenshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { ScreenshotClipRegion } from '@vforsh/argus-core';
2
+ import type { CdpSessionHandle } from './connection.js';
3
+ export type VisualCaptureClip = {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ scale: number;
9
+ };
10
+ export type VisualCaptureViewport = {
11
+ width: number;
12
+ height: number;
13
+ };
14
+ export type VisualCaptureSubject = {
15
+ kind: 'viewport';
16
+ } | {
17
+ kind: 'selector';
18
+ selector: string;
19
+ } | {
20
+ kind: 'clip';
21
+ clip: ScreenshotClipRegion;
22
+ };
23
+ export type VisualCaptureRequest = {
24
+ selector?: string;
25
+ clip?: ScreenshotClipRegion;
26
+ };
27
+ export type VisualCapturePlan = {
28
+ session: CdpSessionHandle;
29
+ clip?: VisualCaptureClip;
30
+ viewport?: VisualCaptureViewport;
31
+ };
32
+ /**
33
+ * Resolve a viewport/selector/clip request into the top-level page session that can capture pixels.
34
+ * Frame targets use their selected frame session for DOM lookup, then translate the clip to page pixels.
35
+ */
36
+ export declare const createVisualCapturePlan: (session: CdpSessionHandle, pageSession: CdpSessionHandle | undefined, request: VisualCaptureRequest) => Promise<VisualCapturePlan>;
37
+ export declare const resolveVisualCaptureSubject: (request: VisualCaptureRequest) => VisualCaptureSubject;
38
+ //# sourceMappingURL=visualCapture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualCapture.d.ts","sourceRoot":"","sources":["../../src/cdp/visualCapture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,iBAAiB,CAAA;AAGzE,MAAM,MAAM,iBAAiB,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtG,MAAM,MAAM,qBAAqB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAA;AAE/I,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,OAAO,EAAE,gBAAgB,CAAA;IACzB,IAAI,CAAC,EAAE,iBAAiB,CAAA;IACxB,QAAQ,CAAC,EAAE,qBAAqB,CAAA;CAChC,CAAA;AAID;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GACnC,SAAS,gBAAgB,EACzB,aAAa,gBAAgB,GAAG,SAAS,EACzC,SAAS,oBAAoB,KAC3B,OAAO,CAAC,iBAAiB,CAsB3B,CAAA;AA0DD,eAAO,MAAM,2BAA2B,GAAI,SAAS,oBAAoB,KAAG,oBAQ3E,CAAA"}