@browserless.io/browserless 2.1.1 → 2.2.0-beta-3

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 (38) hide show
  1. package/bin/scaffold/tsconfig.json +1 -1
  2. package/build/browsers/index.d.ts +1 -10
  3. package/build/browsers/index.js +19 -29
  4. package/build/router.js +13 -6
  5. package/build/routes/chromium/http/content-post.body.json +15 -19
  6. package/build/routes/chromium/http/content-post.d.ts +1 -1
  7. package/build/routes/chromium/http/content-post.js +2 -4
  8. package/build/routes/chromium/http/pdf-post.body.json +15 -19
  9. package/build/routes/chromium/http/pdf-post.d.ts +1 -1
  10. package/build/routes/chromium/http/pdf-post.js +10 -6
  11. package/build/routes/chromium/http/scrape-post.body.json +15 -19
  12. package/build/routes/chromium/http/scrape-post.d.ts +3 -3
  13. package/build/routes/chromium/http/scrape-post.js +2 -4
  14. package/build/routes/chromium/http/scrape-post.response.json +22 -38
  15. package/build/routes/chromium/http/screenshot-post.body.json +15 -19
  16. package/build/routes/chromium/http/screenshot-post.d.ts +1 -1
  17. package/build/routes/chromium/http/screenshot-post.js +2 -4
  18. package/build/routes/chromium/tests/content.spec.js +27 -1
  19. package/build/routes/chromium/tests/websocket.spec.js +53 -4
  20. package/build/routes/chromium/ws/browser.js +1 -1
  21. package/build/routes/management/http/sessions-get.response.json +4 -0
  22. package/build/types.d.ts +1 -0
  23. package/build/utils.d.ts +1 -0
  24. package/build/utils.js +13 -0
  25. package/package.json +3 -3
  26. package/src/browsers/index.ts +24 -45
  27. package/src/router.ts +13 -7
  28. package/src/routes/chromium/http/content-post.ts +3 -4
  29. package/src/routes/chromium/http/pdf-post.ts +13 -6
  30. package/src/routes/chromium/http/scrape-post.ts +5 -6
  31. package/src/routes/chromium/http/screenshot-post.ts +3 -4
  32. package/src/routes/chromium/tests/content.spec.ts +28 -1
  33. package/src/routes/chromium/tests/websocket.spec.ts +70 -4
  34. package/src/routes/chromium/ws/browser.ts +1 -1
  35. package/src/types.ts +1 -0
  36. package/src/utils.ts +26 -0
  37. package/static/docs/swagger.json +70 -98
  38. package/static/function/client.js +192 -488
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "extends": "./node_modules/@browserless.io/browserless/tsconfig.json",
3
- "include": ["./src/**/*"],
3
+ "include": ["./src/**/*"]
4
4
  }
@@ -6,18 +6,9 @@ export declare class BrowserManager {
6
6
  protected launching: Map<string, Promise<unknown>>;
7
7
  protected timers: Map<string, number>;
8
8
  protected debug: import("debug").Debugger;
9
+ protected playwrightBrowserNames: string[];
9
10
  constructor(config: Config);
10
11
  protected removeUserDataDir: (userDataDir: string | null) => Promise<void>;
11
- /**
12
- * Generates a directory for the user-data-dir contents to be saved in. Uses
13
- * the provided sessionId, or creates one when omitted,
14
- * and appends it to the name of the directory. If the
15
- * directory already exists then no action is taken, verified by run `stat`
16
- *
17
- * @param sessionId The ID of the session
18
- * @returns Promise<string> of the fully-qualified path of the directory
19
- */
20
- protected generateDataDir: (sessionId?: string) => Promise<string>;
21
12
  getProtocolJSON: () => Promise<object>;
22
13
  getVersionJSON: () => Promise<{
23
14
  Browser: string;
@@ -1,13 +1,17 @@
1
- import { BadRequest, CDPChromium, HTTPManagementRoutes, NotFound, ServerError, browserHook, convertIfBase64, createLogger, exists, id, makeExternalURL, noop, pageHook, parseBooleanParam, } from '@browserless.io/browserless';
2
- import path, { join } from 'path';
1
+ import { BadRequest, CDPChromium, HTTPManagementRoutes, NotFound, PlaywrightChromium, PlaywrightFirefox, PlaywrightWebkit, browserHook, convertIfBase64, createLogger, exists, generateDataDir, makeExternalURL, noop, pageHook, parseBooleanParam, } from '@browserless.io/browserless';
3
2
  import { deleteAsync } from 'del';
4
- import { mkdir } from 'fs/promises';
3
+ import path from 'path';
5
4
  export class BrowserManager {
6
5
  config;
7
6
  browsers = new Map();
8
7
  launching = new Map();
9
8
  timers = new Map();
10
9
  debug = createLogger('browser-manager');
10
+ playwrightBrowserNames = [
11
+ PlaywrightChromium.name,
12
+ PlaywrightFirefox.name,
13
+ PlaywrightWebkit.name,
14
+ ];
11
15
  constructor(config) {
12
16
  this.config = config;
13
17
  }
@@ -19,28 +23,6 @@ export class BrowserManager {
19
23
  });
20
24
  }
21
25
  };
22
- /**
23
- * Generates a directory for the user-data-dir contents to be saved in. Uses
24
- * the provided sessionId, or creates one when omitted,
25
- * and appends it to the name of the directory. If the
26
- * directory already exists then no action is taken, verified by run `stat`
27
- *
28
- * @param sessionId The ID of the session
29
- * @returns Promise<string> of the fully-qualified path of the directory
30
- */
31
- generateDataDir = async (sessionId = id()) => {
32
- const baseDirectory = await this.config.getDataDir();
33
- const dataDirPath = join(baseDirectory, `browserless-data-dir-${sessionId}`);
34
- if (await exists(dataDirPath)) {
35
- this.debug(`Data directory already exists, not creating "${dataDirPath}"`);
36
- return dataDirPath;
37
- }
38
- this.debug(`Generating user-data-dir at ${dataDirPath}`);
39
- await mkdir(dataDirPath, { recursive: true }).catch((err) => {
40
- throw new ServerError(`Error creating data-directory "${dataDirPath}": ${err}`);
41
- });
42
- return dataDirPath;
43
- };
44
26
  getProtocolJSON = async () => {
45
27
  this.debug(`Launching Chrome to generate /json/protocol results`);
46
28
  const browser = new CDPChromium({
@@ -126,6 +108,10 @@ export class BrowserManager {
126
108
  close = async (browser, session) => {
127
109
  const cleanupACtions = [];
128
110
  this.debug(`${session.numbConnected} Client(s) are currently connected`);
111
+ // Don't close if there's clients still connected
112
+ if (session.numbConnected > 0) {
113
+ return;
114
+ }
129
115
  this.debug(`Closing browser session`);
130
116
  cleanupACtions.push(() => browser.close());
131
117
  if (session.isTempDataDir) {
@@ -168,10 +154,12 @@ export class BrowserManager {
168
154
  if (req.parsed.pathname.includes('/devtools/browser')) {
169
155
  const sessions = Array.from(this.browsers);
170
156
  const id = req.parsed.pathname.split('/').pop();
171
- const browser = sessions.find(([b]) => b.wsEndpoint()?.includes(req.parsed.pathname));
172
- if (browser) {
157
+ const found = sessions.find(([b]) => b.wsEndpoint()?.includes(req.parsed.pathname));
158
+ if (found) {
159
+ const [browser, session] = found;
160
+ ++session.numbConnected;
173
161
  this.debug(`Located browser with ID ${id}`);
174
- return browser[0];
162
+ return browser;
175
163
  }
176
164
  throw new NotFound(`Couldn't locate browser "${id}" for request "${req.parsed.pathname}"`);
177
165
  }
@@ -194,7 +182,9 @@ export class BrowserManager {
194
182
  // Always specify a user-data-dir since plugins can "inject" their own
195
183
  // unless it's playwright which takes care of its own data-dirs
196
184
  const userDataDir = manualUserDataDir ||
197
- (Browser.name === CDPChromium.name ? await this.generateDataDir() : null);
185
+ (!this.playwrightBrowserNames.includes(Browser.name)
186
+ ? await generateDataDir(undefined, this.config)
187
+ : null);
198
188
  const proxyServerArg = launchOptions.args?.find((arg) => arg.includes('--proxy-server='));
199
189
  if (launchOptions.args &&
200
190
  proxyServerArg &&
package/build/router.js CHANGED
@@ -46,15 +46,22 @@ export class Router {
46
46
  return Promise.resolve();
47
47
  }
48
48
  if (!browser) {
49
- return writeResponse(res, 500, `Error loading the browser.`);
50
- }
51
- if (!isConnected(res)) {
52
- this.log(`HTTP Request has closed prior to running`);
53
- return Promise.resolve();
49
+ return writeResponse(res, 500, `Error loading the browser`);
54
50
  }
55
51
  try {
56
52
  this.verbose(`Running found HTTP handler.`);
57
- return await handler(req, res, browser);
53
+ return await Promise.race([
54
+ handler(req, res, browser),
55
+ new Promise((resolve, reject) => {
56
+ res.once('close', () => {
57
+ if (!res.writableEnded) {
58
+ reject(new Error(`Request closed prior to writing results`));
59
+ }
60
+ this.verbose(`Response has been written, resolving`);
61
+ resolve(null);
62
+ });
63
+ }),
64
+ ]);
58
65
  }
59
66
  finally {
60
67
  this.verbose(`HTTP Request handler has finished.`);
@@ -23,7 +23,7 @@
23
23
  "cookies": {
24
24
  "type": "array",
25
25
  "items": {
26
- "$ref": "#/definitions/Protocol.Network.CookieParam"
26
+ "$ref": "#/definitions/CookieParam"
27
27
  }
28
28
  },
29
29
  "emulateMediaType": {
@@ -230,7 +230,7 @@
230
230
  "username"
231
231
  ]
232
232
  },
233
- "Protocol.Network.CookieParam": {
233
+ "CookieParam": {
234
234
  "description": "Cookie parameter object",
235
235
  "type": "object",
236
236
  "properties": {
@@ -243,7 +243,7 @@
243
243
  "type": "string"
244
244
  },
245
245
  "url": {
246
- "description": "The request-URI to associate with the setting of the cookie. This value can affect the\ndefault domain, path, source port, and source scheme values of the created cookie.",
246
+ "description": "The request-URI to associate with the setting of the cookie. This value can affect\nthe default domain, path, and source scheme values of the created cookie.",
247
247
  "type": "string"
248
248
  },
249
249
  "domain": {
@@ -276,7 +276,7 @@
276
276
  "type": "number"
277
277
  },
278
278
  "priority": {
279
- "description": "Cookie Priority.",
279
+ "description": "Cookie Priority. Supported only in Chrome.",
280
280
  "enum": [
281
281
  "High",
282
282
  "Low",
@@ -285,11 +285,11 @@
285
285
  "type": "string"
286
286
  },
287
287
  "sameParty": {
288
- "description": "True if cookie is SameParty.",
288
+ "description": "True if cookie is SameParty. Supported only in Chrome.",
289
289
  "type": "boolean"
290
290
  },
291
291
  "sourceScheme": {
292
- "description": "Cookie source scheme type.",
292
+ "description": "Cookie source scheme type. Supported only in Chrome.",
293
293
  "enum": [
294
294
  "NonSecure",
295
295
  "Secure",
@@ -297,12 +297,8 @@
297
297
  ],
298
298
  "type": "string"
299
299
  },
300
- "sourcePort": {
301
- "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.\nAn unspecified port value allows protocol clients to emulate legacy cookie scope for the port.\nThis is a temporary ability and it will be removed in the future.",
302
- "type": "number"
303
- },
304
300
  "partitionKey": {
305
- "description": "Cookie partition key. The site of the top-level URL the browser was visiting at the start\nof the request to the endpoint that set the cookie.\nIf not set, the cookie will be set as not partitioned.",
301
+ "description": "Cookie partition key. The site of the top-level URL the browser was visiting at the\nstart of the request to the endpoint that set the cookie. If not set, the cookie will\nbe set as not partitioned.",
306
302
  "type": "string"
307
303
  }
308
304
  },
@@ -398,14 +394,14 @@
398
394
  "length": {
399
395
  "type": "number"
400
396
  },
401
- "__@toStringTag@10788": {
397
+ "__@toStringTag@10774": {
402
398
  "type": "string",
403
399
  "const": "Uint8Array"
404
400
  }
405
401
  },
406
402
  "required": [
407
403
  "BYTES_PER_ELEMENT",
408
- "__@toStringTag@10788",
404
+ "__@toStringTag@10774",
409
405
  "buffer",
410
406
  "byteLength",
411
407
  "byteOffset",
@@ -440,13 +436,13 @@
440
436
  "byteLength": {
441
437
  "type": "number"
442
438
  },
443
- "__@toStringTag@10788": {
439
+ "__@toStringTag@10774": {
444
440
  "type": "string"
445
441
  }
446
442
  },
447
443
  "additionalProperties": false,
448
444
  "required": [
449
- "__@toStringTag@10788",
445
+ "__@toStringTag@10774",
450
446
  "byteLength"
451
447
  ]
452
448
  },
@@ -456,18 +452,18 @@
456
452
  "byteLength": {
457
453
  "type": "number"
458
454
  },
459
- "__@species@10889": {
455
+ "__@species@10875": {
460
456
  "$ref": "#/definitions/SharedArrayBuffer"
461
457
  },
462
- "__@toStringTag@10788": {
458
+ "__@toStringTag@10774": {
463
459
  "type": "string",
464
460
  "const": "SharedArrayBuffer"
465
461
  }
466
462
  },
467
463
  "additionalProperties": false,
468
464
  "required": [
469
- "__@species@10889",
470
- "__@toStringTag@10788",
465
+ "__@species@10875",
466
+ "__@toStringTag@10774",
471
467
  "byteLength"
472
468
  ]
473
469
  },
@@ -22,7 +22,7 @@ export interface BodySchema {
22
22
  waitForEvent?: WaitForEventOptions;
23
23
  waitForFunction?: WaitForFunctionOptions;
24
24
  waitForSelector?: WaitForSelectorOptions;
25
- waitForTimeout?: Parameters<Page['waitForTimeout']>[0];
25
+ waitForTimeout?: number;
26
26
  }
27
27
  /**
28
28
  * An HTML payload of the website or HTML after JavaScript
@@ -1,4 +1,4 @@
1
- import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, bestAttemptCatch, contentTypes, noop, waitForEvent as waitForEvt, waitForFunction as waitForFn, writeResponse, } from '@browserless.io/browserless';
1
+ import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, bestAttemptCatch, contentTypes, noop, sleep, waitForEvent as waitForEvt, waitForFunction as waitForFn, writeResponse, } from '@browserless.io/browserless';
2
2
  export default class ContentPostRoute extends BrowserHTTPRoute {
3
3
  accepts = [contentTypes.json];
4
4
  auth = true;
@@ -73,9 +73,7 @@ export default class ContentPostRoute extends BrowserHTTPRoute {
73
73
  }
74
74
  const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
75
75
  if (waitForTimeout) {
76
- await page
77
- .waitForTimeout(waitForTimeout)
78
- .catch(bestAttemptCatch(bestAttempt));
76
+ await sleep(waitForTimeout).catch(bestAttemptCatch(bestAttempt));
79
77
  }
80
78
  if (waitForFunction) {
81
79
  await waitForFn(page, waitForFunction).catch(bestAttemptCatch(bestAttempt));
@@ -26,7 +26,7 @@
26
26
  "cookies": {
27
27
  "type": "array",
28
28
  "items": {
29
- "$ref": "#/definitions/Protocol.Network.CookieParam"
29
+ "$ref": "#/definitions/CookieParam"
30
30
  }
31
31
  },
32
32
  "emulateMediaType": {
@@ -235,7 +235,7 @@
235
235
  "username"
236
236
  ]
237
237
  },
238
- "Protocol.Network.CookieParam": {
238
+ "CookieParam": {
239
239
  "description": "Cookie parameter object",
240
240
  "type": "object",
241
241
  "properties": {
@@ -248,7 +248,7 @@
248
248
  "type": "string"
249
249
  },
250
250
  "url": {
251
- "description": "The request-URI to associate with the setting of the cookie. This value can affect the\ndefault domain, path, source port, and source scheme values of the created cookie.",
251
+ "description": "The request-URI to associate with the setting of the cookie. This value can affect\nthe default domain, path, and source scheme values of the created cookie.",
252
252
  "type": "string"
253
253
  },
254
254
  "domain": {
@@ -281,7 +281,7 @@
281
281
  "type": "number"
282
282
  },
283
283
  "priority": {
284
- "description": "Cookie Priority.",
284
+ "description": "Cookie Priority. Supported only in Chrome.",
285
285
  "enum": [
286
286
  "High",
287
287
  "Low",
@@ -290,11 +290,11 @@
290
290
  "type": "string"
291
291
  },
292
292
  "sameParty": {
293
- "description": "True if cookie is SameParty.",
293
+ "description": "True if cookie is SameParty. Supported only in Chrome.",
294
294
  "type": "boolean"
295
295
  },
296
296
  "sourceScheme": {
297
- "description": "Cookie source scheme type.",
297
+ "description": "Cookie source scheme type. Supported only in Chrome.",
298
298
  "enum": [
299
299
  "NonSecure",
300
300
  "Secure",
@@ -302,12 +302,8 @@
302
302
  ],
303
303
  "type": "string"
304
304
  },
305
- "sourcePort": {
306
- "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.\nAn unspecified port value allows protocol clients to emulate legacy cookie scope for the port.\nThis is a temporary ability and it will be removed in the future.",
307
- "type": "number"
308
- },
309
305
  "partitionKey": {
310
- "description": "Cookie partition key. The site of the top-level URL the browser was visiting at the start\nof the request to the endpoint that set the cookie.\nIf not set, the cookie will be set as not partitioned.",
306
+ "description": "Cookie partition key. The site of the top-level URL the browser was visiting at the\nstart of the request to the endpoint that set the cookie. If not set, the cookie will\nbe set as not partitioned.",
311
307
  "type": "string"
312
308
  }
313
309
  },
@@ -542,14 +538,14 @@
542
538
  "length": {
543
539
  "type": "number"
544
540
  },
545
- "__@toStringTag@75058": {
541
+ "__@toStringTag@75019": {
546
542
  "type": "string",
547
543
  "const": "Uint8Array"
548
544
  }
549
545
  },
550
546
  "required": [
551
547
  "BYTES_PER_ELEMENT",
552
- "__@toStringTag@75058",
548
+ "__@toStringTag@75019",
553
549
  "buffer",
554
550
  "byteLength",
555
551
  "byteOffset",
@@ -584,13 +580,13 @@
584
580
  "byteLength": {
585
581
  "type": "number"
586
582
  },
587
- "__@toStringTag@75058": {
583
+ "__@toStringTag@75019": {
588
584
  "type": "string"
589
585
  }
590
586
  },
591
587
  "additionalProperties": false,
592
588
  "required": [
593
- "__@toStringTag@75058",
589
+ "__@toStringTag@75019",
594
590
  "byteLength"
595
591
  ]
596
592
  },
@@ -600,18 +596,18 @@
600
596
  "byteLength": {
601
597
  "type": "number"
602
598
  },
603
- "__@species@75159": {
599
+ "__@species@75120": {
604
600
  "$ref": "#/definitions/SharedArrayBuffer"
605
601
  },
606
- "__@toStringTag@75058": {
602
+ "__@toStringTag@75019": {
607
603
  "type": "string",
608
604
  "const": "SharedArrayBuffer"
609
605
  }
610
606
  },
611
607
  "additionalProperties": false,
612
608
  "required": [
613
- "__@species@75159",
614
- "__@toStringTag@75058",
609
+ "__@species@75120",
610
+ "__@toStringTag@75019",
615
611
  "byteLength"
616
612
  ]
617
613
  },
@@ -24,7 +24,7 @@ export interface BodySchema {
24
24
  waitForEvent?: WaitForEventOptions;
25
25
  waitForFunction?: WaitForFunctionOptions;
26
26
  waitForSelector?: WaitForSelectorOptions;
27
- waitForTimeout?: Parameters<Page['waitForTimeout']>[0];
27
+ waitForTimeout?: number;
28
28
  }
29
29
  export interface QuerySchema extends SystemQueryParameters {
30
30
  launch?: CDPLaunchOptions | string;
@@ -1,4 +1,5 @@
1
- import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, bestAttemptCatch, contentTypes, dedent, noop, waitForEvent as waitForEvt, waitForFunction as waitForFn, writeResponse, } from '@browserless.io/browserless';
1
+ import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, bestAttemptCatch, contentTypes, dedent, noop, sleep, waitForEvent as waitForEvt, waitForFunction as waitForFn, writeResponse, } from '@browserless.io/browserless';
2
+ import { Stream } from 'stream';
2
3
  export default class PDFPost extends BrowserHTTPRoute {
3
4
  accepts = [contentTypes.json];
4
5
  auth = true;
@@ -23,7 +24,7 @@ export default class PDFPost extends BrowserHTTPRoute {
23
24
  return;
24
25
  }
25
26
  res.setHeader('Content-Type', contentType);
26
- const { url, gotoOptions, authenticate, html, addScriptTag = [], addStyleTag = [], cookies = [], emulateMediaType, rejectRequestPattern = [], requestInterceptors = [], rejectResourceTypes = [], options, setExtraHTTPHeaders, setJavaScriptEnabled, userAgent, viewport, waitForFunction, waitForSelector, waitForEvent, bestAttempt = false, } = req.body;
27
+ const { url, gotoOptions, authenticate, html, addScriptTag = [], addStyleTag = [], cookies = [], emulateMediaType, rejectRequestPattern = [], requestInterceptors = [], rejectResourceTypes = [], options, setExtraHTTPHeaders, setJavaScriptEnabled, userAgent, viewport, waitForEvent, waitForFunction, waitForSelector, waitForTimeout, bestAttempt = false, } = req.body;
27
28
  const content = url || html;
28
29
  if (!content) {
29
30
  throw new BadRequest(`One of "url" or "html" properties are required.`);
@@ -78,6 +79,9 @@ export default class PDFPost extends BrowserHTTPRoute {
78
79
  }
79
80
  }
80
81
  const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
82
+ if (waitForTimeout) {
83
+ await sleep(waitForTimeout).catch(bestAttemptCatch(bestAttempt));
84
+ }
81
85
  if (waitForFunction) {
82
86
  await waitForFn(page, waitForFunction).catch(bestAttemptCatch(bestAttempt));
83
87
  }
@@ -102,10 +106,10 @@ export default class PDFPost extends BrowserHTTPRoute {
102
106
  res.setHeader(key, value);
103
107
  }
104
108
  }
105
- const pdfStream = await page.createPDFStream(options);
106
- await new Promise((resolve, reject) => {
107
- return pdfStream.pipe(res).once('finish', resolve).once('error', reject);
108
- });
109
+ const pdfBuffer = await page.pdf(options);
110
+ const readStream = new Stream.PassThrough();
111
+ readStream.end(pdfBuffer);
112
+ await new Promise((r) => readStream.pipe(res).once('close', r));
109
113
  page.close().catch(noop);
110
114
  };
111
115
  }
@@ -23,7 +23,7 @@
23
23
  "cookies": {
24
24
  "type": "array",
25
25
  "items": {
26
- "$ref": "#/definitions/Protocol.Network.CookieParam"
26
+ "$ref": "#/definitions/CookieParam"
27
27
  }
28
28
  },
29
29
  "debugOpts": {
@@ -241,7 +241,7 @@
241
241
  "username"
242
242
  ]
243
243
  },
244
- "Protocol.Network.CookieParam": {
244
+ "CookieParam": {
245
245
  "description": "Cookie parameter object",
246
246
  "type": "object",
247
247
  "properties": {
@@ -254,7 +254,7 @@
254
254
  "type": "string"
255
255
  },
256
256
  "url": {
257
- "description": "The request-URI to associate with the setting of the cookie. This value can affect the\ndefault domain, path, source port, and source scheme values of the created cookie.",
257
+ "description": "The request-URI to associate with the setting of the cookie. This value can affect\nthe default domain, path, and source scheme values of the created cookie.",
258
258
  "type": "string"
259
259
  },
260
260
  "domain": {
@@ -287,7 +287,7 @@
287
287
  "type": "number"
288
288
  },
289
289
  "priority": {
290
- "description": "Cookie Priority.",
290
+ "description": "Cookie Priority. Supported only in Chrome.",
291
291
  "enum": [
292
292
  "High",
293
293
  "Low",
@@ -296,11 +296,11 @@
296
296
  "type": "string"
297
297
  },
298
298
  "sameParty": {
299
- "description": "True if cookie is SameParty.",
299
+ "description": "True if cookie is SameParty. Supported only in Chrome.",
300
300
  "type": "boolean"
301
301
  },
302
302
  "sourceScheme": {
303
- "description": "Cookie source scheme type.",
303
+ "description": "Cookie source scheme type. Supported only in Chrome.",
304
304
  "enum": [
305
305
  "NonSecure",
306
306
  "Secure",
@@ -308,12 +308,8 @@
308
308
  ],
309
309
  "type": "string"
310
310
  },
311
- "sourcePort": {
312
- "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.\nAn unspecified port value allows protocol clients to emulate legacy cookie scope for the port.\nThis is a temporary ability and it will be removed in the future.",
313
- "type": "number"
314
- },
315
311
  "partitionKey": {
316
- "description": "Cookie partition key. The site of the top-level URL the browser was visiting at the start\nof the request to the endpoint that set the cookie.\nIf not set, the cookie will be set as not partitioned.",
312
+ "description": "Cookie partition key. The site of the top-level URL the browser was visiting at the\nstart of the request to the endpoint that set the cookie. If not set, the cookie will\nbe set as not partitioned.",
317
313
  "type": "string"
318
314
  }
319
315
  },
@@ -445,14 +441,14 @@
445
441
  "length": {
446
442
  "type": "number"
447
443
  },
448
- "__@toStringTag@107362": {
444
+ "__@toStringTag@107541": {
449
445
  "type": "string",
450
446
  "const": "Uint8Array"
451
447
  }
452
448
  },
453
449
  "required": [
454
450
  "BYTES_PER_ELEMENT",
455
- "__@toStringTag@107362",
451
+ "__@toStringTag@107541",
456
452
  "buffer",
457
453
  "byteLength",
458
454
  "byteOffset",
@@ -487,13 +483,13 @@
487
483
  "byteLength": {
488
484
  "type": "number"
489
485
  },
490
- "__@toStringTag@107362": {
486
+ "__@toStringTag@107541": {
491
487
  "type": "string"
492
488
  }
493
489
  },
494
490
  "additionalProperties": false,
495
491
  "required": [
496
- "__@toStringTag@107362",
492
+ "__@toStringTag@107541",
497
493
  "byteLength"
498
494
  ]
499
495
  },
@@ -503,18 +499,18 @@
503
499
  "byteLength": {
504
500
  "type": "number"
505
501
  },
506
- "__@species@107463": {
502
+ "__@species@107642": {
507
503
  "$ref": "#/definitions/SharedArrayBuffer"
508
504
  },
509
- "__@toStringTag@107362": {
505
+ "__@toStringTag@107541": {
510
506
  "type": "string",
511
507
  "const": "SharedArrayBuffer"
512
508
  }
513
509
  },
514
510
  "additionalProperties": false,
515
511
  "required": [
516
- "__@species@107463",
517
- "__@toStringTag@107362",
512
+ "__@species@107642",
513
+ "__@toStringTag@107541",
518
514
  "byteLength"
519
515
  ]
520
516
  },
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { APITags, BrowserHTTPRoute, BrowserInstance, CDPChromium, CDPLaunchOptions, HTTPRoutes, InBoundRequest, Methods, OutBoundRequest, Request, ScrapeDebugOptions, ScrapeElementSelector, SystemQueryParameters, WaitForEventOptions, WaitForFunctionOptions, WaitForSelectorOptions, bestAttempt, contentTypes, rejectRequestPattern, rejectResourceTypes, requestInterceptors } from '@browserless.io/browserless';
3
- import { Page, Protocol } from 'puppeteer-core';
3
+ import { Cookie, Page } from 'puppeteer-core';
4
4
  import { ServerResponse } from 'http';
5
5
  export interface BodySchema {
6
6
  addScriptTag?: Array<Parameters<Page['addScriptTag']>[0]>;
@@ -24,7 +24,7 @@ export interface BodySchema {
24
24
  waitForEvent?: WaitForEventOptions;
25
25
  waitForFunction?: WaitForFunctionOptions;
26
26
  waitForSelector?: WaitForSelectorOptions;
27
- waitForTimeout?: Parameters<Page['waitForTimeout']>[0];
27
+ waitForTimeout?: number;
28
28
  }
29
29
  export type QuerySchema = SystemQueryParameters & {
30
30
  launch?: CDPLaunchOptions | string;
@@ -89,7 +89,7 @@ export interface ResponseSchema {
89
89
  /**
90
90
  * List of cookies for the site or null
91
91
  */
92
- cookies: Protocol.Network.Cookie[] | null;
92
+ cookies: Cookie[] | null;
93
93
  /**
94
94
  * The HTML string of the website or null
95
95
  */
@@ -1,4 +1,4 @@
1
- import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, Timeout, bestAttemptCatch, contentTypes, debugScreenshotOpts, dedent, jsonResponse, noop, waitForEvent as waitForEvt, waitForFunction as waitForFn, } from '@browserless.io/browserless';
1
+ import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, Timeout, bestAttemptCatch, contentTypes, debugScreenshotOpts, dedent, jsonResponse, noop, sleep, waitForEvent as waitForEvt, waitForFunction as waitForFn, } from '@browserless.io/browserless';
2
2
  const scrape = async (elements) => {
3
3
  const wait = (selector, timeout = 30000) => {
4
4
  return new Promise((resolve, reject) => {
@@ -141,9 +141,7 @@ export default class ScrapePost extends BrowserHTTPRoute {
141
141
  }
142
142
  }
143
143
  if (waitForTimeout) {
144
- await page
145
- .waitForTimeout(waitForTimeout)
146
- .catch(bestAttemptCatch(bestAttempt));
144
+ await sleep(waitForTimeout).catch(bestAttemptCatch(bestAttempt));
147
145
  }
148
146
  if (waitForFunction) {
149
147
  await waitForFn(page, waitForFunction).catch(bestAttemptCatch(bestAttempt));