pupeteer-capture 0.0.1-security → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pupeteer-capture might be problematic. Click here for more details.

@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MP4 = void 0;
13
+ function MP4(preset = 'ultrafast', videoCodec = 'libx264') {
14
+ return (ffmpeg) => __awaiter(this, void 0, void 0, function* () {
15
+ ffmpeg
16
+ .outputFormat('mp4').withVideoCodec(videoCodec)
17
+ .outputOption(`-preset ${preset}`)
18
+ .outputOption('-movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov');
19
+ });
20
+ }
21
+ exports.MP4 = MP4;
@@ -0,0 +1,8 @@
1
+ import { FfmpegCommand } from 'fluent-ffmpeg';
2
+ export interface PuppeteerCaptureOptions {
3
+ fps?: number;
4
+ size?: string;
5
+ format?: (ffmpeg: FfmpegCommand) => Promise<void>;
6
+ ffmpeg?: string;
7
+ customFfmpegConfig?: (ffmpeg: FfmpegCommand) => Promise<void>;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface PuppeteerCaptureStartOptions {
2
+ waitForFirstFrame?: boolean;
3
+ dropCapturedFrames?: boolean;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,27 @@
1
+ import type { Browser as PuppeteerBrowser, CDPSession as PuppeteerCDPSession, Page as PuppeteerPage } from 'puppeteer';
2
+ import { Protocol } from 'devtools-protocol';
3
+ import { PuppeteerCaptureBase } from './PuppeteerCaptureBase';
4
+ import { PuppeteerCaptureOptions } from './PuppeteerCaptureOptions';
5
+ export declare class PuppeteerCaptureViaHeadlessExperimental extends PuppeteerCaptureBase {
6
+ static readonly REQUIRED_ARGS: string[];
7
+ protected static readonly INJECTED = "__PuppeteerCaptureViaHeadlessExperimental";
8
+ protected static readonly EJECTOR: string;
9
+ protected readonly _injected: string;
10
+ protected readonly _injector: string;
11
+ protected readonly _ejector: string;
12
+ protected readonly _requestFrameCapture: () => void;
13
+ protected readonly _onSessionDisconnected: () => void;
14
+ protected _session: PuppeteerCDPSession | null;
15
+ protected _onNewDocumentScript: Protocol.Page.ScriptIdentifier | null;
16
+ constructor(options?: PuppeteerCaptureOptions);
17
+ protected getPageClient(page: PuppeteerPage): PuppeteerCDPSession;
18
+ protected _attach(page: PuppeteerPage): Promise<void>;
19
+ protected _detach(page: PuppeteerPage): Promise<void>;
20
+ protected requestFrameCapture(): void;
21
+ protected doRequestFrameCapture(page: PuppeteerPage, session: PuppeteerCDPSession): void;
22
+ protected onPostCaptureStarted(): Promise<void>;
23
+ protected onPostCaptureStopped(): Promise<void>;
24
+ protected onSessionDisconnected(): void;
25
+ protected static validateBrowserArgs(browser: PuppeteerBrowser): void;
26
+ protected static generateInjector(fps: number): string;
27
+ }
@@ -0,0 +1,440 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PuppeteerCaptureViaHeadlessExperimental = void 0;
13
+ const MissingHeadlessExperimentalRequiredArgs_1 = require("./MissingHeadlessExperimentalRequiredArgs");
14
+ const PuppeteerCaptureBase_1 = require("./PuppeteerCaptureBase");
15
+ class PuppeteerCaptureViaHeadlessExperimental extends PuppeteerCaptureBase_1.PuppeteerCaptureBase {
16
+ constructor(options) {
17
+ super(options);
18
+ this._injected = PuppeteerCaptureViaHeadlessExperimental.INJECTED;
19
+ this._injector = PuppeteerCaptureViaHeadlessExperimental.generateInjector(this._options.fps); // eslint-disable-line @typescript-eslint/no-non-null-assertion
20
+ this._ejector = PuppeteerCaptureViaHeadlessExperimental.EJECTOR;
21
+ this._requestFrameCapture = this.requestFrameCapture.bind(this);
22
+ this._onSessionDisconnected = this.onSessionDisconnected.bind(this);
23
+ this._session = null;
24
+ this._onNewDocumentScript = null;
25
+ if (process.platform === 'darwin') {
26
+ throw new Error('MacOS is not supported by HeadlessExperimental.BeginFrame');
27
+ }
28
+ }
29
+ getPageClient(page) {
30
+ // Before puppeteer 14.4.0, the internal method was client()
31
+ if ('client' in page) {
32
+ // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
33
+ // @ts-ignore
34
+ return page.client();
35
+ }
36
+ // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
37
+ // @ts-ignore
38
+ return page._client();
39
+ }
40
+ _attach(page) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ PuppeteerCaptureViaHeadlessExperimental.validateBrowserArgs(page.browser());
43
+ const session = yield page.target().createCDPSession();
44
+ // NOTE: For some reason, page.client() has to be used instead of newly created session
45
+ const onNewDocumentScript = (yield this.getPageClient(page).send('Page.addScriptToEvaluateOnNewDocument', {
46
+ source: this._injector
47
+ })).identifier;
48
+ session.on('CDPSession.Disconnected', this._onSessionDisconnected);
49
+ this._session = session;
50
+ this._onNewDocumentScript = onNewDocumentScript;
51
+ });
52
+ }
53
+ _detach(page) {
54
+ var _a;
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ if (this._onNewDocumentScript != null) {
57
+ // NOTE: For details, see send('Page.addScriptToEvaluateOnNewDocument') code
58
+ yield this.getPageClient(page).send('Page.removeScriptToEvaluateOnNewDocument', {
59
+ identifier: this._onNewDocumentScript
60
+ });
61
+ this._onNewDocumentScript = null;
62
+ }
63
+ if (((_a = this._session) === null || _a === void 0 ? void 0 : _a.connection()) != null) {
64
+ this._session.off('CDPSession.Disconnected', this._onSessionDisconnected);
65
+ yield this._session.detach();
66
+ this._session = null;
67
+ }
68
+ });
69
+ }
70
+ requestFrameCapture() {
71
+ if (!this._isCapturing || this._error != null) {
72
+ return;
73
+ }
74
+ if (this._page == null) {
75
+ throw new Error('Not attached to a page');
76
+ }
77
+ if (this._session == null) {
78
+ throw new Error('No session available');
79
+ }
80
+ if (this._session.connection() == null) {
81
+ throw new Error('Session disconnected');
82
+ }
83
+ this.doRequestFrameCapture(this._page, this._session);
84
+ }
85
+ doRequestFrameCapture(page, session) {
86
+ const captureTimestamp = this._captureTimestamp;
87
+ const frameInterval = this._frameInterval;
88
+ this._frameBeingCaptured = Promise.all(page.frames().map((frame) => __awaiter(this, void 0, void 0, function* () {
89
+ yield frame.evaluate(`${this._injected}.process(${captureTimestamp})`);
90
+ }))).then(() => __awaiter(this, void 0, void 0, function* () {
91
+ return yield session.send('HeadlessExperimental.beginFrame', {
92
+ frameTimeTicks: captureTimestamp,
93
+ interval: frameInterval,
94
+ noDisplayUpdates: false,
95
+ screenshot: { format: 'png' }
96
+ });
97
+ })).then(({ screenshotData: dataBase64 }) => __awaiter(this, void 0, void 0, function* () {
98
+ this._frameBeingCaptured = null;
99
+ if (!this._isCapturing) {
100
+ return;
101
+ }
102
+ if (dataBase64 == null) {
103
+ setTimeout(this._requestFrameCapture, 0);
104
+ return;
105
+ }
106
+ const data = Buffer.from(dataBase64, 'base64');
107
+ yield this.onFrameCaptured(captureTimestamp, data);
108
+ if (this._isCapturing) {
109
+ this._captureTimestamp = captureTimestamp + frameInterval;
110
+ setTimeout(this._requestFrameCapture, 0);
111
+ }
112
+ }), (reason) => __awaiter(this, void 0, void 0, function* () {
113
+ this._frameBeingCaptured = null;
114
+ if (!this._isCapturing) {
115
+ return;
116
+ }
117
+ yield this.onFrameCaptureFailed(reason);
118
+ }));
119
+ }
120
+ onPostCaptureStarted() {
121
+ var _a;
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ const page = this._page;
124
+ const session = this._session;
125
+ if (page == null || ((_a = this.getPageClient(page)) === null || _a === void 0 ? void 0 : _a.connection()) == null || (session === null || session === void 0 ? void 0 : session.connection()) == null) {
126
+ return;
127
+ }
128
+ for (const frame of page.frames()) {
129
+ yield frame.evaluate(this._injector);
130
+ yield frame.evaluate(`${this._injected}.activate()`);
131
+ }
132
+ yield session.send('HeadlessExperimental.enable');
133
+ this.doRequestFrameCapture(page, session);
134
+ });
135
+ }
136
+ onPostCaptureStopped() {
137
+ var _a;
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ const page = this._page;
140
+ const session = this._session;
141
+ if (page == null || ((_a = this.getPageClient(page)) === null || _a === void 0 ? void 0 : _a.connection()) == null || (session === null || session === void 0 ? void 0 : session.connection()) == null) {
142
+ return;
143
+ }
144
+ for (const frame of page.frames()) {
145
+ yield frame.evaluate(`${this._injected}.deactivate()`);
146
+ yield frame.evaluate(this._ejector);
147
+ }
148
+ yield session.send('HeadlessExperimental.disable');
149
+ });
150
+ }
151
+ onSessionDisconnected() {
152
+ this._error = new Error('Session was disconnected');
153
+ this._startStopMutex.runExclusive(() => __awaiter(this, void 0, void 0, function* () {
154
+ if (this._isCapturing) {
155
+ yield this._stop();
156
+ }
157
+ yield this.detach();
158
+ }))
159
+ .then(() => { })
160
+ .catch(() => { });
161
+ }
162
+ static validateBrowserArgs(browser) {
163
+ var _a;
164
+ const spawnargs = (_a = browser.process()) === null || _a === void 0 ? void 0 : _a.spawnargs;
165
+ if (spawnargs == null || !PuppeteerCaptureViaHeadlessExperimental.REQUIRED_ARGS.every(arg => spawnargs.includes(arg))) {
166
+ throw new MissingHeadlessExperimentalRequiredArgs_1.MissingHeadlessExperimentalRequiredArgs();
167
+ }
168
+ }
169
+ static generateInjector(fps) {
170
+ return (`
171
+ if (typeof ${PuppeteerCaptureViaHeadlessExperimental.INJECTED} === 'undefined') {
172
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED} = {
173
+ active: false,
174
+ scheduledSimulatedProcessing: null,
175
+ previousSimulatedProcessingTimestamp: null,
176
+ simulatedProcessFPS: ${fps},
177
+ original: {},
178
+ dateOrigin: new Date(),
179
+ performanceNowOrigin: performance.now(),
180
+ timestampOffsetFromOrigin: 0,
181
+ animationFrameRequests: [],
182
+ intervalTimers: [],
183
+ timeoutTimers: [],
184
+ };
185
+
186
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.activate = function () {
187
+ if (${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.active) {
188
+ return;
189
+ }
190
+
191
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.dateOrigin = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.newDate();
192
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNowOrigin = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp;
193
+ if (${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNowOrigin === null) {
194
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNowOrigin = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNow();
195
+ }
196
+
197
+ if (${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.scheduledSimulatedProcessing) {
198
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_clearTimeout(${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.scheduledSimulatedProcessing);
199
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.scheduledSimulatedProcessing = null;
200
+ }
201
+
202
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.active = true;
203
+ };
204
+
205
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.deactivate = function () {
206
+ if (!${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.active) {
207
+ return;
208
+ }
209
+
210
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.dateOrigin = null;
211
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNowOrigin = null;
212
+
213
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp = -${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin;
214
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.scheduledSimulatedProcessing = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_setTimeout(
215
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcess,
216
+ 1000 / ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcessFPS,
217
+ );
218
+
219
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.active = false;
220
+ };
221
+
222
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.getTimestamp = function () {
223
+ return ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNowOrigin + ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin;
224
+ }
225
+
226
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.Date = Date;
227
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.newDate = function () {
228
+ return new ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.Date();
229
+ }
230
+ Date = function () {
231
+ var OriginalDate = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.Date;
232
+ // NOTE: ECMA-262 says that using apply() is not possible: The function call Date(…) is not equivalent to the object creation expression new Date(…) with the same arguments.
233
+ switch (arguments.length) {
234
+ case 0:
235
+ return new OriginalDate(
236
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.dateOrigin.getTime() + ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin
237
+ );
238
+ case 1:
239
+ return new OriginalDate(
240
+ arguments[0],
241
+ );
242
+ case 2:
243
+ return new OriginalDate(
244
+ arguments[0],
245
+ arguments[1],
246
+ );
247
+ case 3:
248
+ return new OriginalDate(
249
+ arguments[0],
250
+ arguments[1],
251
+ arguments[2],
252
+ );
253
+ case 4:
254
+ return new OriginalDate(
255
+ arguments[0],
256
+ arguments[1],
257
+ arguments[2],
258
+ arguments[3],
259
+ );
260
+ case 5:
261
+ return new OriginalDate(
262
+ arguments[0],
263
+ arguments[1],
264
+ arguments[2],
265
+ arguments[3],
266
+ arguments[4],
267
+ );
268
+ case 6:
269
+ return new OriginalDate(
270
+ arguments[0],
271
+ arguments[1],
272
+ arguments[2],
273
+ arguments[3],
274
+ arguments[4],
275
+ arguments[5],
276
+ );
277
+ case 7:
278
+ return new OriginalDate(
279
+ arguments[0],
280
+ arguments[1],
281
+ arguments[2],
282
+ arguments[3],
283
+ arguments[4],
284
+ arguments[5],
285
+ arguments[6],
286
+ );
287
+ };
288
+ };
289
+ Date.now = function () {
290
+ return ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.dateOrigin.getTime() + ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin;
291
+ };
292
+
293
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.performance_now = performance.now;
294
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNow = performance.now.bind(performance);
295
+ performance.now = function () {
296
+ return ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNowOrigin + ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin;
297
+ };
298
+
299
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_setInterval = window.setInterval;
300
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_setInterval = window.setInterval.bind(window);
301
+ window.setInterval = function (callback, interval, ...parameters) {
302
+ return ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.intervalTimers.push({
303
+ interval,
304
+ executionTimestamp: ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.getTimestamp(),
305
+ callback,
306
+ parameters,
307
+ });
308
+ };
309
+
310
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_clearInterval = window.clearInterval;
311
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_clearInterval = window.clearInterval.bind(window);
312
+ window.clearInterval = function (timer) {
313
+ delete ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.intervalTimers[timer - 1];
314
+ };
315
+
316
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_setTimeout = window.setTimeout;
317
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_setTimeout = window.setTimeout.bind(window);
318
+ window.setTimeout = function (callback, timeout, ...parameters) {
319
+ return ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timeoutTimers.push({
320
+ timeout,
321
+ enqueuedTimestamp: ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.getTimestamp(),
322
+ callback,
323
+ parameters,
324
+ });
325
+ };
326
+
327
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_clearTimeout = window.clearTimeout;
328
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_clearTimeout = window.clearTimeout.bind(window);
329
+ window.clearTimeout = function (timer) {
330
+ delete ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timeoutTimers[timer - 1];
331
+ };
332
+
333
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_requestAnimationFrame = window.requestAnimationFrame;
334
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_requestAnimationFrame = window.requestAnimationFrame.bind(window);
335
+ window.requestAnimationFrame = function (callback) {
336
+ return ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.animationFrameRequests.push({
337
+ callback,
338
+ });
339
+ };
340
+
341
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_cancelAnimationFrame = window.cancelAnimationFrame;
342
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_cancelAnimationFrame = window.cancelAnimationFrame.bind(window);
343
+ window.cancelAnimationFrame = function (request) {
344
+ delete ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.animationFrameRequests[request - 1];
345
+ };
346
+
347
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.process = function (timestampOffsetFromOrigin) {
348
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin = timestampOffsetFromOrigin;
349
+ var timestamp = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.getTimestamp();
350
+
351
+ var intervalTimers = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.intervalTimers.slice();
352
+ var timeoutTimers = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timeoutTimers.slice();
353
+ var animationFrameRequests = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.animationFrameRequests.slice();
354
+
355
+ intervalTimers.forEach(function (intervalTimer) {
356
+ while (intervalTimer.executionTimestamp + intervalTimer.interval <= timestamp) {
357
+ if (intervalTimer.callback) {
358
+ intervalTimer.callback.apply(undefined, intervalTimer.parameters);
359
+ }
360
+ intervalTimer.executionTimestamp += intervalTimer.interval;
361
+ }
362
+ });
363
+
364
+ timeoutTimers.forEach(function (timeoutTimer, timeoutTimerIndex) {
365
+ if (timeoutTimer.enqueuedTimestamp + timeoutTimer.timeout <= timestamp) {
366
+ if (timeoutTimer.callback) {
367
+ timeoutTimer.callback.apply(undefined, timeoutTimer.parameters);
368
+ }
369
+ delete ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timeoutTimers[timeoutTimerIndex];
370
+ }
371
+ });
372
+
373
+ animationFrameRequests.forEach(function (animationFrameRequest, animationFrameRequestIndex) {
374
+ if (animationFrameRequest.callback) {
375
+ animationFrameRequest.callback.apply(undefined, [timestamp]);
376
+ }
377
+ delete ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.animationFrameRequests[animationFrameRequestIndex];
378
+ });
379
+ }
380
+
381
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcess = function () {
382
+ if (${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.active) {
383
+ return;
384
+ }
385
+
386
+ var timestamp = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.performanceNow();
387
+
388
+ if (${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp === null) {
389
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp = timestamp;
390
+ } else if (${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp < 0) {
391
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp += timestamp;
392
+ }
393
+
394
+ var timestampDelta = timestamp - ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp;
395
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.process(
396
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.timestampOffsetFromOrigin + timestampDelta
397
+ );
398
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.previousSimulatedProcessingTimestamp = timestamp;
399
+
400
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.scheduledSimulatedProcessing = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_setTimeout(
401
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcess,
402
+ 1000 / ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcessFPS,
403
+ );
404
+ }
405
+
406
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.scheduledSimulatedProcessing = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.window_setTimeout(
407
+ ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcess,
408
+ 1000 / ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.simulatedProcessFPS,
409
+ );
410
+ }
411
+ `);
412
+ }
413
+ }
414
+ exports.PuppeteerCaptureViaHeadlessExperimental = PuppeteerCaptureViaHeadlessExperimental;
415
+ PuppeteerCaptureViaHeadlessExperimental.REQUIRED_ARGS = [
416
+ '--deterministic-mode',
417
+ '--enable-begin-frame-control',
418
+ '--disable-new-content-rendering-timeout',
419
+ '--run-all-compositor-stages-before-draw',
420
+ '--disable-threaded-animation',
421
+ '--disable-threaded-scrolling',
422
+ '--disable-checker-imaging',
423
+ '--disable-image-animation-resync',
424
+ '--enable-surface-synchronization'
425
+ ];
426
+ PuppeteerCaptureViaHeadlessExperimental.INJECTED = '__PuppeteerCaptureViaHeadlessExperimental';
427
+ PuppeteerCaptureViaHeadlessExperimental.EJECTOR = `
428
+ if (typeof ${PuppeteerCaptureViaHeadlessExperimental.INJECTED} !== 'undefined') {
429
+ Date = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.Date;
430
+ performance.now = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.performance_now;
431
+ window.setInterval = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_setInterval;
432
+ window.clearInterval = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_clearInterval;
433
+ window.setTimeout = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_setTimeout;
434
+ window.clearTimeout = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_clearTimeout;
435
+ window.requestAnimationFrame = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_requestAnimationFrame;
436
+ window.cancelAnimationFrame = ${PuppeteerCaptureViaHeadlessExperimental.INJECTED}.original.window_cancelAnimationFrame;
437
+
438
+ delete ${PuppeteerCaptureViaHeadlessExperimental.INJECTED};
439
+ }
440
+ `;
@@ -0,0 +1,6 @@
1
+ import type { Page as PuppeteerPage } from 'puppeteer';
2
+ import { PuppeteerCapture } from './PuppeteerCapture';
3
+ import { PuppeteerCaptureOptions } from './PuppeteerCaptureOptions';
4
+ export declare function capture(page: PuppeteerPage, options?: PuppeteerCaptureOptions & {
5
+ attach?: boolean;
6
+ }): Promise<PuppeteerCapture>;
package/lib/capture.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.capture = void 0;
13
+ const PuppeteerCaptureViaHeadlessExperimental_1 = require("./PuppeteerCaptureViaHeadlessExperimental");
14
+ function capture(page, options) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const puppeteerCapture = new PuppeteerCaptureViaHeadlessExperimental_1.PuppeteerCaptureViaHeadlessExperimental(options);
17
+ if ((options === null || options === void 0 ? void 0 : options.attach) !== false) {
18
+ yield puppeteerCapture.attach(page);
19
+ }
20
+ return puppeteerCapture;
21
+ });
22
+ }
23
+ exports.capture = capture;
package/lib/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { capture } from './capture';
2
+ export { launch } from './launch';
3
+ export { MissingHeadlessExperimentalRequiredArgs as MissingRequiredArgs } from './MissingHeadlessExperimentalRequiredArgs';
4
+ export { PuppeteerCapture } from './PuppeteerCapture';
5
+ export { PuppeteerCaptureBase } from './PuppeteerCaptureBase';
6
+ export { PuppeteerCaptureEvents } from './PuppeteerCaptureEvents';
7
+ export * as PuppeteerCaptureFormat from './PuppeteerCaptureFormat';
8
+ export { PuppeteerCaptureOptions } from './PuppeteerCaptureOptions';
9
+ export { PuppeteerCaptureViaHeadlessExperimental } from './PuppeteerCaptureViaHeadlessExperimental';
package/lib/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.PuppeteerCaptureViaHeadlessExperimental = exports.PuppeteerCaptureFormat = exports.PuppeteerCaptureBase = exports.MissingRequiredArgs = exports.launch = exports.capture = void 0;
27
+ var capture_1 = require("./capture");
28
+ Object.defineProperty(exports, "capture", { enumerable: true, get: function () { return capture_1.capture; } });
29
+ var launch_1 = require("./launch");
30
+ Object.defineProperty(exports, "launch", { enumerable: true, get: function () { return launch_1.launch; } });
31
+ var MissingHeadlessExperimentalRequiredArgs_1 = require("./MissingHeadlessExperimentalRequiredArgs");
32
+ Object.defineProperty(exports, "MissingRequiredArgs", { enumerable: true, get: function () { return MissingHeadlessExperimentalRequiredArgs_1.MissingHeadlessExperimentalRequiredArgs; } });
33
+ var PuppeteerCaptureBase_1 = require("./PuppeteerCaptureBase");
34
+ Object.defineProperty(exports, "PuppeteerCaptureBase", { enumerable: true, get: function () { return PuppeteerCaptureBase_1.PuppeteerCaptureBase; } });
35
+ exports.PuppeteerCaptureFormat = __importStar(require("./PuppeteerCaptureFormat"));
36
+ var PuppeteerCaptureViaHeadlessExperimental_1 = require("./PuppeteerCaptureViaHeadlessExperimental");
37
+ Object.defineProperty(exports, "PuppeteerCaptureViaHeadlessExperimental", { enumerable: true, get: function () { return PuppeteerCaptureViaHeadlessExperimental_1.PuppeteerCaptureViaHeadlessExperimental; } });
@@ -0,0 +1,5 @@
1
+ import type { Browser as PuppeteerBrowser, BrowserConnectOptions as PuppeteerBrowserConnectOptions, BrowserLaunchArgumentOptions as PuppeteerBrowserLaunchArgumentOptions, LaunchOptions as PuppeteerLaunchOptions, Product as PuppeteerProduct } from 'puppeteer';
2
+ export declare function launch(options?: PuppeteerLaunchOptions & PuppeteerBrowserLaunchArgumentOptions & PuppeteerBrowserConnectOptions & {
3
+ product?: PuppeteerProduct;
4
+ extraPrefsFirefox?: Record<string, unknown>;
5
+ }): Promise<PuppeteerBrowser>;
package/lib/launch.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var _a;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.launch = void 0;
14
+ const PuppeteerCaptureViaHeadlessExperimental_1 = require("./PuppeteerCaptureViaHeadlessExperimental");
15
+ /* eslint-disable-next-line @typescript-eslint/no-var-requires */
16
+ const puppeteer = require(`puppeteer${(_a = process.env.PUPPETEER_CAPTURE__PUPPETEER_VERSION) !== null && _a !== void 0 ? _a : ''}`);
17
+ function launch(options) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ options = Object.assign(Object.assign({}, (options != null ? options : {})), { args: [
20
+ ...((options === null || options === void 0 ? void 0 : options.args) != null ? options === null || options === void 0 ? void 0 : options.args : []),
21
+ ...PuppeteerCaptureViaHeadlessExperimental_1.PuppeteerCaptureViaHeadlessExperimental.REQUIRED_ARGS
22
+ ] });
23
+ return yield puppeteer.launch(options);
24
+ });
25
+ }
26
+ exports.launch = launch;