single-file-cli 2.0.69 → 2.0.71

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/build.sh CHANGED
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- deno vendor "npm:single-file-core@1.5.36"
3
+ mv package.json package.json.tmp
4
+ mv deno.json deno.json.tmp
5
+ mv deno.lock deno.lock.tmp
6
+ deno install --vendor --quiet "npm:single-file-core@1.5.41"
7
+ mv package.json.tmp package.json
8
+ mv deno.json.tmp deno.json
9
+ mv deno.lock.tmp deno.lock
4
10
 
5
11
  echo "
6
12
  import { build } from 'npm:esbuild';
@@ -82,5 +88,4 @@ const version = JSON.parse(await Deno.readTextFile('./deno.json')).version;
82
88
  await Deno.writeTextFile('lib/version.js', 'export const version = ' + JSON.stringify(version) + ';');
83
89
  " | deno run --allow-read --allow-write --allow-net --allow-run --allow-env --lock=node_modules/deno.lock.tmp -
84
90
 
85
- rm -rf node_modules
86
- rm -rf vendor
91
+ rm -rf node_modules
package/deno.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@single-file/single-file-cli",
3
- "version": "2.0.69",
3
+ "version": "2.0.71",
4
4
  "description": "SingleFile CLI",
5
- "nodeModulesDir": true,
5
+ "nodeModulesDir": "auto",
6
6
  "exports": {
7
7
  ".": "./single-file-cli-api.js"
8
8
  },
9
9
  "imports": {
10
10
  "simple-cdp": "jsr:@simple-cdp/simple-cdp@^1.8.5",
11
- "path": "jsr:@std/path@^0.220.1"
11
+ "path": "jsr:@std/path@^0.224.0"
12
12
  }
13
13
  }
package/deno.lock CHANGED
@@ -1,43 +1,38 @@
1
1
  {
2
- "version": "3",
3
- "packages": {
4
- "specifiers": {
5
- "jsr:@simple-cdp/simple-cdp@^1.8.5": "jsr:@simple-cdp/simple-cdp@1.8.5",
6
- "jsr:@std/assert@^0.220.1": "jsr:@std/assert@0.220.1",
7
- "jsr:@std/path@^0.220.1": "jsr:@std/path@0.220.1",
8
- "npm:simple-cdp@^1.8.5": "npm:simple-cdp@1.8.5",
9
- "npm:ws@^8.16.0": "npm:ws@8.16.0"
2
+ "version": "4",
3
+ "specifiers": {
4
+ "jsr:@simple-cdp/simple-cdp@^1.8.5": "1.8.5",
5
+ "jsr:@std/assert@0.224": "0.224.0",
6
+ "jsr:@std/path@0.224": "0.224.0",
7
+ "npm:simple-cdp@^1.8.5": "1.8.5",
8
+ "npm:ws@^8.16.0": "8.16.0"
9
+ },
10
+ "jsr": {
11
+ "@simple-cdp/simple-cdp@1.8.5": {
12
+ "integrity": "7386ca561cd6293bb3115eadf14b8c98d1c41c35a69c79774ea70e5101159413"
13
+ },
14
+ "@std/assert@0.224.0": {
15
+ "integrity": "8643233ec7aec38a940a8264a6e3eed9bfa44e7a71cc6b3c8874213ff401967f"
10
16
  },
11
- "jsr": {
12
- "@simple-cdp/simple-cdp@1.8.5": {
13
- "integrity": "7386ca561cd6293bb3115eadf14b8c98d1c41c35a69c79774ea70e5101159413"
14
- },
15
- "@std/assert@0.220.1": {
16
- "integrity": "88710d54f3afdd7a5761e7805abba1f56cd14e4b212feffeb3e73a9f77482425"
17
- },
18
- "@std/path@0.220.1": {
19
- "integrity": "cc63c1b5e5192e2f718dc2f365a3514fffb26cc0380959bab0f8fb5988a52f0c",
20
- "dependencies": [
21
- "jsr:@std/assert@^0.220.1"
22
- ]
23
- }
17
+ "@std/path@0.224.0": {
18
+ "integrity": "55bca6361e5a6d158b9380e82d4981d82d338ec587de02951e2b7c3a24910ee6",
19
+ "dependencies": [
20
+ "jsr:@std/assert"
21
+ ]
22
+ }
23
+ },
24
+ "npm": {
25
+ "simple-cdp@1.8.5": {
26
+ "integrity": "sha512-bpXoeCk0mwFrr+8C8vVkhCug5h4HO49GI+MZdnyLQcFVKzTlokrimTjEoc69X2Y2n7mtjzDHTriq6B/kgUeUcA=="
24
27
  },
25
- "npm": {
26
- "simple-cdp@1.8.5": {
27
- "integrity": "sha512-bpXoeCk0mwFrr+8C8vVkhCug5h4HO49GI+MZdnyLQcFVKzTlokrimTjEoc69X2Y2n7mtjzDHTriq6B/kgUeUcA==",
28
- "dependencies": {}
29
- },
30
- "ws@8.16.0": {
31
- "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
32
- "dependencies": {}
33
- }
28
+ "ws@8.16.0": {
29
+ "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ=="
34
30
  }
35
31
  },
36
- "remote": {},
37
32
  "workspace": {
38
33
  "dependencies": [
39
34
  "jsr:@simple-cdp/simple-cdp@^1.8.5",
40
- "jsr:@std/path@^0.220.1"
35
+ "jsr:@std/path@0.224"
41
36
  ],
42
37
  "packageJson": {
43
38
  "dependencies": [
package/lib/cdp-client.js CHANGED
@@ -28,6 +28,7 @@ import { getScriptSource, getHookScriptSource } from "./single-file-script.js";
28
28
  import { CDP, options } from "simple-cdp";
29
29
 
30
30
  const LOAD_TIMEOUT_ERROR = "ERR_LOAD_TIMEOUT";
31
+ const CAPTURE_TIMEOUT_ERROR = "ERR_CAPTURE_TIMEOUT";
31
32
  const NETWORK_STATES = ["InteractiveTime", "networkIdle", "networkAlmostIdle", "load", "DOMContentLoaded"];
32
33
  const MINIMIZED_WINDOW_STATE = "minimized";
33
34
  const SINGLE_FILE_WORLD_NAME = "singlefile";
@@ -50,12 +51,19 @@ async function initialize(singleFileOptions) {
50
51
  }
51
52
 
52
53
  async function getPageData(options) {
54
+ const debugMessages = [];
53
55
  let targetInfo;
54
56
  try {
57
+ if (options.debugMessagesFile) {
58
+ debugMessages.push([Date.now(), ["Loading page", EMPTY_PAGE_URL]]);
59
+ }
55
60
  targetInfo = await CDP.createTarget(EMPTY_PAGE_URL);
56
61
  const consoleMessages = [];
57
62
  const { Browser, Security, Page, Emulation, Fetch, Network, Runtime, Debugger, Console } = new CDP(targetInfo);
58
63
  if (options.consoleMessagesFile) {
64
+ if (options.debugMessagesFile) {
65
+ debugMessages.push([Date.now(), ["Enabling console messages"]]);
66
+ }
59
67
  await Console.enable();
60
68
  Console.addEventListener("messageAdded", ({ params }) => {
61
69
  const { message } = params;
@@ -65,13 +73,22 @@ async function getPageData(options) {
65
73
  if (options.browserStartMinimized) {
66
74
  const { windowId, bounds } = await Browser.getWindowForTarget({ targetId: targetInfo.id });
67
75
  if (bounds.windowState !== MINIMIZED_WINDOW_STATE) {
76
+ if (options.debugMessagesFile) {
77
+ debugMessages.push([Date.now(), ["Minimizing window"]]);
78
+ }
68
79
  await Browser.setWindowBounds({ windowId, bounds: { windowState: MINIMIZED_WINDOW_STATE } });
69
80
  }
70
81
  }
71
82
  if (options.browserIgnoreHTTPSErrors !== undefined && options.browserIgnoreHTTPSErrors) {
83
+ if (options.debugMessagesFile) {
84
+ debugMessages.push([Date.now(), ["Ignoring HTTPS errors"]]);
85
+ }
72
86
  await Security.setIgnoreCertificateErrors({ ignore: true });
73
87
  }
74
88
  if (options.browserByPassCSP === undefined || options.browserByPassCSP) {
89
+ if (options.debugMessagesFile) {
90
+ debugMessages.push([Date.now(), ["Bypassing CSP"]]);
91
+ }
75
92
  await Page.setBypassCSP({ enabled: true });
76
93
  }
77
94
  if (options.browserMobileEmulation || options.browserDeviceWidth || options.browserDeviceHeight || options.browserDeviceScaleFactor || options.platform || options.acceptLanguage) {
@@ -91,12 +108,16 @@ async function getPageData(options) {
91
108
  const { result } = await Runtime.evaluate({ expression: "window.devicePixelRatio" });
92
109
  browserDeviceScaleFactor = result.value;
93
110
  }
94
- await Emulation.setDeviceMetricsOverride({
111
+ const deviceMetricsOptions = {
95
112
  mobile: Boolean(options.browserMobileEmulation),
96
113
  width: options.browserDeviceWidth || (options.browserMobileEmulation ? 360 : options.width || browserDeviceWidth),
97
114
  height: options.browserDeviceHeight || (options.browserMobileEmulation ? 800 : options.height || browserDeviceHeight),
98
115
  deviceScaleFactor: options.browserDeviceScaleFactor || (options.browserMobileEmulation ? 2 : browserDeviceScaleFactor)
99
- });
116
+ };
117
+ if (options.debugMessagesFile) {
118
+ debugMessages.push([Date.now(), ["Emulating device metrics", JSON.stringify(deviceMetricsOptions)]]);
119
+ }
120
+ await Emulation.setDeviceMetricsOverride(deviceMetricsOptions);
100
121
  }
101
122
  if (options.browserMobileEmulation || options.platform || options.acceptLanguage) {
102
123
  const { userAgent, product } = await Browser.getVersion();
@@ -109,21 +130,29 @@ async function getPageData(options) {
109
130
  if (options.platform || options.browserMobileEmulation) {
110
131
  agentOptions.platform = options.platform || "Android";
111
132
  }
133
+ if (options.debugMessagesFile) {
134
+ debugMessages.push([Date.now(), ["Emulating user agent", JSON.stringify(agentOptions)]]);
135
+ }
112
136
  await Emulation.setUserAgentOverride(agentOptions);
113
137
  }
114
138
  }
115
139
  const handleAuthRequests = Boolean(options.httpProxyUsername);
116
- const patterns = handleAuthRequests ? [{ requestStage: "Request" }, { requestStage: "Response", resourceType: "Document" }] : [{ requestStage: "Response", resourceType: "Document" }];
140
+ const patterns = handleAuthRequests ? [{ requestStage: "Request" }, { requestStage: "Response" }] : [{ requestStage: "Response" }];
117
141
  await Fetch.enable({ handleAuthRequests, patterns });
118
142
  if (handleAuthRequests) {
119
- Fetch.addEventListener("authRequired", ({ params }) => Fetch.continueWithAuth({
120
- requestId: params.requestId,
121
- authChallengeResponse: {
122
- response: "ProvideCredentials",
123
- username: options.httpProxyUsername,
124
- password: options.httpProxyPassword
143
+ Fetch.addEventListener("authRequired", async ({ params }) => {
144
+ if (options.debugMessagesFile) {
145
+ debugMessages.push([Date.now(), ["Authenticating"]]);
125
146
  }
126
- }));
147
+ await Fetch.continueWithAuth({
148
+ requestId: params.requestId,
149
+ authChallengeResponse: {
150
+ response: "ProvideCredentials",
151
+ username: options.httpProxyUsername,
152
+ password: options.httpProxyPassword
153
+ }
154
+ });
155
+ });
127
156
  }
128
157
  let url = options.url;
129
158
  let alternativeUrl = new URL(url);
@@ -134,12 +163,15 @@ async function getPageData(options) {
134
163
  let httpInfo;
135
164
  Fetch.addEventListener("requestPaused", async ({ params }) => {
136
165
  const { requestId, request, resourceType, responseHeaders, responseStatusCode, responseStatusText } = params;
137
- if (options.outputJson && !httpInfo && (request.url == url || request.url == alternativeUrl) && responseStatusCode !== undefined) {
166
+ if (resourceType == "Document" && (options.outputJson && !httpInfo && (request.url == url || request.url == alternativeUrl) && responseStatusCode !== undefined)) {
138
167
  if (REDIRECT_STATUS_CODES.includes(responseStatusCode)) {
139
168
  const redirect = responseHeaders.find(header => header.name.toLowerCase() == "location").value;
140
169
  if (redirect) {
141
170
  url = new URL(redirect, url).href;
142
171
  }
172
+ if (options.debugMessagesFile) {
173
+ debugMessages.push([Date.now(), ["Redirecting", url]]);
174
+ }
143
175
  } else {
144
176
  httpInfo = {
145
177
  request: {
@@ -156,6 +188,18 @@ async function getPageData(options) {
156
188
  }
157
189
  };
158
190
  }
191
+ } else if (options.blockedURLPatterns && options.blockedURLPatterns.length) {
192
+ const blockedURL = options.blockedURLPatterns.find(blockedURL => new RegExp(blockedURL).test(request.url));
193
+ if (blockedURL) {
194
+ try {
195
+ if (options.debugMessagesFile) {
196
+ debugMessages.push([Date.now(), ["Blocking request", request.url]]);
197
+ }
198
+ await Fetch.failRequest({ requestId, errorReason: "Aborted" });
199
+ } catch {
200
+ // ignored
201
+ }
202
+ }
159
203
  }
160
204
  try {
161
205
  await Fetch.continueRequest({ requestId });
@@ -164,10 +208,16 @@ async function getPageData(options) {
164
208
  }
165
209
  });
166
210
  if (options.httpHeaders && options.httpHeaders.length) {
211
+ if (options.debugMessagesFile) {
212
+ debugMessages.push([Date.now(), ["Setting HTTP headers", JSON.stringify(options.httpHeaders)]]);
213
+ }
167
214
  await Network.setExtraHTTPHeaders({ headers: options.httpHeaders });
168
215
  }
169
216
  if (options.emulateMediaFeatures) {
170
217
  for (const mediaFeature of options.emulateMediaFeatures) {
218
+ if (options.debugMessagesFile) {
219
+ debugMessages.push([Date.now(), ["Emulating media feature", mediaFeature.name, mediaFeature.value]]);
220
+ }
171
221
  await Emulation.setEmulatedMedia({
172
222
  media: mediaFeature.name,
173
223
  features: mediaFeature.value.split(",").map(feature => feature.trim())
@@ -175,6 +225,9 @@ async function getPageData(options) {
175
225
  }
176
226
  }
177
227
  if (options.browserCookies && options.browserCookies.length) {
228
+ if (options.debugMessagesFile) {
229
+ debugMessages.push([Date.now(), ["Setting cookies", JSON.stringify(options.browserCookies)]]);
230
+ }
178
231
  await Network.setCookies({ cookies: options.browserCookies });
179
232
  }
180
233
  await Browser.setDownloadBehavior({ behavior: "deny" });
@@ -188,7 +241,7 @@ async function getPageData(options) {
188
241
  worldName: SINGLE_FILE_WORLD_NAME
189
242
  });
190
243
  const [contextId] = await Promise.all([
191
- loadPage({ Page, Runtime }, options),
244
+ loadPage({ Page, Runtime }, options, debugMessages),
192
245
  options.browserDebug ? waitForDebuggerReady({ Debugger }) : Promise.resolve()
193
246
  ]);
194
247
  await Runtime.addBinding({ name: SET_PAGE_DATA_FUNCTION_NAME, executionContextId: contextId });
@@ -196,6 +249,9 @@ async function getPageData(options) {
196
249
  await Runtime.addBinding({ name: CAPTURE_SCREENSHOT_FUNCTION_NAME, executionContextId: contextId });
197
250
  Runtime.addEventListener("bindingCalled", async ({ params }) => {
198
251
  if (params.name === CAPTURE_SCREENSHOT_FUNCTION_NAME) {
252
+ if (options.debugMessagesFile) {
253
+ debugMessages.push([Date.now(), ["Capturing screenshot"]]);
254
+ }
199
255
  try {
200
256
  let screenshotOptions = { captureBeyondViewport: true };
201
257
  if (options.embedScreenshotOptions) {
@@ -218,6 +274,9 @@ async function getPageData(options) {
218
274
  await Runtime.addBinding({ name: PRINT_TO_PDF_FUNCTION_NAME, executionContextId: contextId });
219
275
  Runtime.addEventListener("bindingCalled", async ({ params }) => {
220
276
  if (params.name === PRINT_TO_PDF_FUNCTION_NAME) {
277
+ if (options.debugMessagesFile) {
278
+ debugMessages.push([Date.now(), ["Printing to PDF", options.embedPdfOptions || ""]]);
279
+ }
221
280
  let pdfOptions = {};
222
281
  if (options.embedPdfOptions) {
223
282
  try {
@@ -243,6 +302,9 @@ async function getPageData(options) {
243
302
  if (payload.length) {
244
303
  pageDataResponse += payload;
245
304
  } else {
305
+ if (options.debugMessagesFile) {
306
+ debugMessages.push([Date.now(), ["Setting page data"]]);
307
+ }
246
308
  const result = JSON.parse(pageDataResponse);
247
309
  if (result.content instanceof Array) {
248
310
  result.content = new Uint8Array(result.content);
@@ -253,36 +315,71 @@ async function getPageData(options) {
253
315
  });
254
316
  });
255
317
  if (options.browserWaitDelay) {
318
+ if (options.debugMessagesFile) {
319
+ debugMessages.push([Date.now(), [`Waiting ${options.browserWaitDelay} ms`]]);
320
+ }
256
321
  await new Promise(resolve => setTimeout(resolve, options.browserWaitDelay));
257
322
  }
258
- const { result } = await Runtime.evaluate({
259
- expression: `(${getPageDataScriptSource.toString()})(${JSON.stringify(options)},${JSON.stringify([SET_SCREENSHOT_FUNCTION_NAME, SET_PDF_FUNCTION_NAME, SET_PAGE_DATA_FUNCTION_NAME, CAPTURE_SCREENSHOT_FUNCTION_NAME, PRINT_TO_PDF_FUNCTION_NAME])})`,
260
- awaitPromise: true,
261
- returnByValue: true,
262
- contextId
263
- });
264
- const { subtype, description } = result;
265
- if (subtype === "error") {
266
- throw new Error(description);
323
+ const captureTimeoutAbortController = new AbortController();
324
+ const captureTimeoutAbortSignal = captureTimeoutAbortController.signal;
325
+ try {
326
+ if (options.debugMessagesFile) {
327
+ debugMessages.push([Date.now(), ["Capturing page"]]);
328
+ }
329
+ const { result } = await Promise.race([
330
+ Runtime.evaluate({
331
+ expression: `(${getPageDataScriptSource.toString()})(${JSON.stringify(options)},${JSON.stringify([SET_SCREENSHOT_FUNCTION_NAME, SET_PDF_FUNCTION_NAME, SET_PAGE_DATA_FUNCTION_NAME, CAPTURE_SCREENSHOT_FUNCTION_NAME, PRINT_TO_PDF_FUNCTION_NAME])})`,
332
+ awaitPromise: true,
333
+ returnByValue: true,
334
+ contextId
335
+ }),
336
+ waitForTimeout(captureTimeoutAbortSignal, options.browserCaptureMaxTime, "Capture timeout", CAPTURE_TIMEOUT_ERROR)
337
+ ]);
338
+ const { subtype, description } = result;
339
+ if (subtype === "error") {
340
+ throw new Error(description);
341
+ }
342
+ } finally {
343
+ if (!captureTimeoutAbortSignal.aborted) {
344
+ captureTimeoutAbortController.abort();
345
+ }
346
+ await Runtime.disable();
347
+ await Page.disable();
267
348
  }
268
349
  const pageData = await pageDataPromise;
269
350
  if (options.consoleMessagesFile) {
270
351
  await Console.disable();
271
352
  pageData.consoleMessages = consoleMessages;
272
353
  }
354
+ if (options.debugMessagesFile) {
355
+ pageData.debugMessages = debugMessages;
356
+ debugMessages.push([Date.now(), ["Returning page data"]]);
357
+ }
273
358
  Object.assign(pageData, httpInfo);
274
359
  return pageData;
275
360
  } catch (error) {
276
361
  if (error.code === LOAD_TIMEOUT_ERROR && options.browserWaitUntilFallback && options.browserWaitUntil) {
277
362
  const browserWaitUntil = NETWORK_STATES[(NETWORK_STATES.indexOf(options.browserWaitUntil) + 1)];
278
363
  if (browserWaitUntil) {
364
+ if (options.debugMessagesFile) {
365
+ debugMessages.push([Date.now(), ["Retrying with waitUntil", browserWaitUntil]]);
366
+ }
279
367
  options.browserWaitUntil = browserWaitUntil;
280
368
  await closeTarget();
281
369
  return await getPageData(options);
282
370
  }
283
371
  }
372
+ if (options.consoleMessagesFile) {
373
+ error.consoleMessages = consoleMessages;
374
+ }
375
+ if (options.debugMessagesFile) {
376
+ error.debugMessages = debugMessages;
377
+ }
284
378
  throw error;
285
379
  } finally {
380
+ if (options.debugMessagesFile) {
381
+ debugMessages.push([Date.now(), ["Closing page"]]);
382
+ }
286
383
  await closeTarget();
287
384
  }
288
385
 
@@ -335,15 +432,18 @@ function getPageDataScriptSource(options, [SET_SCREENSHOT_FUNCTION_NAME, SET_PDF
335
432
  });
336
433
  }
337
434
 
338
- async function loadPage({ Page, Runtime }, options) {
435
+ async function loadPage({ Page, Runtime }, options, debugMessages) {
339
436
  await Runtime.enable();
340
437
  await Page.enable();
341
438
  const loadTimeoutAbortController = new AbortController();
342
439
  const loadTimeoutAbortSignal = loadTimeoutAbortController.signal;
343
440
  try {
441
+ if (options.debugMessagesFile) {
442
+ debugMessages.push([Date.now(), ["Loading page", options.url]]);
443
+ }
344
444
  const [contextId] = await Promise.race([
345
- Promise.all([getTopFrameContextId({ Page, Runtime }, options), Page.navigate({ url: options.url })]),
346
- waitForLoadTimeout(loadTimeoutAbortSignal, options.browserLoadMaxTime)
445
+ Promise.all([getTopFrameContextId({ Page, Runtime }, options, debugMessages), Page.navigate({ url: options.url })]),
446
+ waitForTimeout(loadTimeoutAbortSignal, options.browserLoadMaxTime, "Load timeout", LOAD_TIMEOUT_ERROR)
347
447
  ]);
348
448
  return contextId;
349
449
  } finally {
@@ -355,13 +455,16 @@ async function loadPage({ Page, Runtime }, options) {
355
455
  }
356
456
  }
357
457
 
358
- async function getTopFrameContextId({ Page, Runtime }, options) {
458
+ async function getTopFrameContextId({ Page, Runtime }, options, debugMessages) {
359
459
  const CONTEXT_CREATED_EVENT = "executionContextCreated";
360
460
  const contextIds = [];
361
461
  let topFrameId;
362
462
  try {
363
463
  Runtime.addEventListener(CONTEXT_CREATED_EVENT, onExecutionContextCreated);
364
464
  await waitForPageReady({ Page }, options);
465
+ if (options.debugMessagesFile) {
466
+ debugMessages.push([Date.now(), ["Getting execution context"]]);
467
+ }
365
468
  const contextId = await getContextId();
366
469
  if (contextId === undefined) {
367
470
  throw new Error("Execution context not found");
@@ -392,12 +495,23 @@ async function getTopFrameContextId({ Page, Runtime }, options) {
392
495
 
393
496
  function onLifecycleEvent({ params }) {
394
497
  const { frameId, name } = params;
395
- if (frameId === topFrameId && name === options.browserWaitUntil || (resolveCallbackTimeout && NETWORK_STATES.indexOf(name) < NETWORK_STATES.indexOf(options.browserWaitUntil))) {
396
- clearTimeout(resolveCallbackTimeout);
397
- setTimeout(() => {
398
- removeListeners();
399
- resolve();
400
- }, options.browserWaitUntilDelay);
498
+ if (frameId === topFrameId) {
499
+ if (options.debugMessagesFile) {
500
+ debugMessages.push([Date.now(), ["Detecting lifecycle event", name]]);
501
+ }
502
+ if (name === options.browserWaitUntil || (resolveCallbackTimeout && NETWORK_STATES.indexOf(name) < NETWORK_STATES.indexOf(options.browserWaitUntil))) {
503
+ clearTimeout(resolveCallbackTimeout);
504
+ if (options.debugMessagesFile) {
505
+ debugMessages.push([Date.now(), [`Waiting ${options.browserWaitUntilDelay} ms`]]);
506
+ }
507
+ setTimeout(() => {
508
+ if (options.debugMessagesFile) {
509
+ debugMessages.push([Date.now(), ["Detecting page ready"]]);
510
+ }
511
+ removeListeners();
512
+ resolve();
513
+ }, options.browserWaitUntilDelay);
514
+ }
401
515
  }
402
516
  }
403
517
 
@@ -409,6 +523,9 @@ async function getTopFrameContextId({ Page, Runtime }, options) {
409
523
  removeListeners();
410
524
  reject(new Error("Unreachable URL: " + frame.unreachableUrl));
411
525
  } else {
526
+ if (options.debugMessagesFile) {
527
+ debugMessages.push([Date.now(), ["Detecting top frame ID"]]);
528
+ }
412
529
  topFrameId = frame.id;
413
530
  }
414
531
  }
@@ -452,14 +569,14 @@ async function getTopFrameContextId({ Page, Runtime }, options) {
452
569
  }
453
570
  }
454
571
 
455
- function waitForLoadTimeout(abortSignal, maxDelay) {
572
+ function waitForTimeout(abortSignal, maxDelay, errorMessage, errorCode) {
456
573
  return new Promise((resolve, reject) => {
457
574
  const ABORT_EVENT = "abort";
458
575
  abortSignal.addEventListener(ABORT_EVENT, onAbort);
459
576
  const timeoutId = setTimeout(() => {
460
577
  abortSignal.removeEventListener(ABORT_EVENT, onAbort);
461
- const error = new Error("Load timeout");
462
- error.code = LOAD_TIMEOUT_ERROR;
578
+ const error = new Error(errorMessage);
579
+ error.code = errorCode;
463
580
  reject(error);
464
581
  }, maxDelay);
465
582
 
package/lib/constants.js CHANGED
@@ -51,7 +51,9 @@ const BROWSER_ARGS = [
51
51
  "--enable-use-zoom-for-dsf=false",
52
52
  "--no-sandbox",
53
53
  "--no-startup-window",
54
- "--bwsi"
54
+ "--bwsi",
55
+ "--mute-audio",
56
+ "--deny-permission-prompts"
55
57
  ];
56
58
  const BROWSER_PATHS = {
57
59
  linux: [