@browserless.io/browserless 2.24.3 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +1 -1
  3. package/build/browserless.js +3 -1
  4. package/build/browsers/browsers.cdp.d.ts +3 -0
  5. package/build/browsers/browsers.cdp.js +4 -1
  6. package/build/browsers/browsers.playwright.d.ts +4 -0
  7. package/build/browsers/browsers.playwright.js +5 -1
  8. package/build/browsers/index.js +3 -2
  9. package/build/http.d.ts +9 -0
  10. package/build/http.js +9 -0
  11. package/build/routes/chrome/http/content.post.body.json +8 -8
  12. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  13. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  14. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  15. package/build/routes/chrome/tests/kill-sessions.spec.js +1 -1
  16. package/build/routes/chromium/http/content.post.body.json +8 -8
  17. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  18. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  19. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  20. package/build/routes/chromium/tests/kill-sessions.spec.js +1 -1
  21. package/build/routes/edge/http/content.post.body.json +579 -0
  22. package/build/routes/edge/http/content.post.d.ts +8 -0
  23. package/build/routes/edge/http/content.post.js +7 -0
  24. package/build/routes/edge/http/content.post.query.json +183 -0
  25. package/build/routes/edge/http/content.post.response.json +5 -0
  26. package/build/routes/edge/http/download.post.body.json +32 -0
  27. package/build/routes/edge/http/download.post.d.ts +8 -0
  28. package/build/routes/edge/http/download.post.js +7 -0
  29. package/build/routes/edge/http/download.post.query.json +120 -0
  30. package/build/routes/edge/http/download.post.response.json +4 -0
  31. package/build/routes/edge/http/function.post.body.json +32 -0
  32. package/build/routes/edge/http/function.post.d.ts +8 -0
  33. package/build/routes/edge/http/function.post.js +7 -0
  34. package/build/routes/edge/http/function.post.query.json +120 -0
  35. package/build/routes/edge/http/function.post.response.json +4 -0
  36. package/build/routes/edge/http/json-list.get.d.ts +5 -0
  37. package/build/routes/edge/http/json-list.get.js +5 -0
  38. package/build/routes/edge/http/json-list.get.response.json +52 -0
  39. package/build/routes/edge/http/json-new.put.d.ts +5 -0
  40. package/build/routes/edge/http/json-new.put.js +5 -0
  41. package/build/routes/edge/http/json-new.put.response.json +44 -0
  42. package/build/routes/edge/http/json-protocol.get.d.ts +5 -0
  43. package/build/routes/edge/http/json-protocol.get.js +5 -0
  44. package/build/routes/edge/http/json-protocol.get.response.json +6 -0
  45. package/build/routes/edge/http/json-version.get.d.ts +5 -0
  46. package/build/routes/edge/http/json-version.get.js +5 -0
  47. package/build/routes/edge/http/json-version.get.response.json +44 -0
  48. package/build/routes/edge/http/pdf.post.body.json +724 -0
  49. package/build/routes/edge/http/pdf.post.d.ts +8 -0
  50. package/build/routes/edge/http/pdf.post.js +7 -0
  51. package/build/routes/edge/http/pdf.post.query.json +120 -0
  52. package/build/routes/edge/http/pdf.post.response.json +5 -0
  53. package/build/routes/edge/http/performance.post.body.json +26 -0
  54. package/build/routes/edge/http/performance.post.d.ts +8 -0
  55. package/build/routes/edge/http/performance.post.js +7 -0
  56. package/build/routes/edge/http/performance.post.query.json +120 -0
  57. package/build/routes/edge/http/performance.post.response.json +7 -0
  58. package/build/routes/edge/http/scrape.post.body.json +626 -0
  59. package/build/routes/edge/http/scrape.post.d.ts +8 -0
  60. package/build/routes/edge/http/scrape.post.js +7 -0
  61. package/build/routes/edge/http/scrape.post.query.json +183 -0
  62. package/build/routes/edge/http/scrape.post.response.json +334 -0
  63. package/build/routes/edge/http/screenshot.post.body.json +669 -0
  64. package/build/routes/edge/http/screenshot.post.d.ts +8 -0
  65. package/build/routes/edge/http/screenshot.post.js +7 -0
  66. package/build/routes/edge/http/screenshot.post.query.json +120 -0
  67. package/build/routes/edge/http/screenshot.post.response.json +5 -0
  68. package/build/routes/edge/tests/content.spec.d.ts +1 -0
  69. package/build/routes/edge/tests/content.spec.js +312 -0
  70. package/build/routes/edge/tests/download.spec.d.ts +1 -0
  71. package/build/routes/edge/tests/download.spec.js +67 -0
  72. package/build/routes/edge/tests/function.spec.d.ts +1 -0
  73. package/build/routes/edge/tests/function.spec.js +277 -0
  74. package/build/routes/edge/tests/json-version.spec.d.ts +1 -0
  75. package/build/routes/edge/tests/json-version.spec.js +37 -0
  76. package/build/routes/edge/tests/kill-sessions.spec.d.ts +1 -0
  77. package/build/routes/edge/tests/kill-sessions.spec.js +80 -0
  78. package/build/routes/edge/tests/page-websocket.spec.d.ts +1 -0
  79. package/build/routes/edge/tests/page-websocket.spec.js +97 -0
  80. package/build/routes/edge/tests/pdf.spec.d.ts +1 -0
  81. package/build/routes/edge/tests/pdf.spec.js +345 -0
  82. package/build/routes/edge/tests/performance.spec.d.ts +1 -0
  83. package/build/routes/edge/tests/performance.spec.js +124 -0
  84. package/build/routes/edge/tests/scrape.spec.d.ts +1 -0
  85. package/build/routes/edge/tests/scrape.spec.js +354 -0
  86. package/build/routes/edge/tests/screenshot.spec.d.ts +1 -0
  87. package/build/routes/edge/tests/screenshot.spec.js +339 -0
  88. package/build/routes/edge/tests/websocket.spec.d.ts +1 -0
  89. package/build/routes/edge/tests/websocket.spec.js +384 -0
  90. package/build/routes/edge/ws/browser.d.ts +7 -0
  91. package/build/routes/edge/ws/browser.js +6 -0
  92. package/build/routes/edge/ws/browser.query.json +120 -0
  93. package/build/routes/edge/ws/cdp.d.ts +8 -0
  94. package/build/routes/edge/ws/cdp.js +7 -0
  95. package/build/routes/edge/ws/cdp.query.json +120 -0
  96. package/build/routes/edge/ws/page.d.ts +8 -0
  97. package/build/routes/edge/ws/page.js +7 -0
  98. package/build/routes/edge/ws/page.query.json +120 -0
  99. package/build/routes/edge/ws/playwright.d.ts +8 -0
  100. package/build/routes/edge/ws/playwright.js +7 -0
  101. package/build/routes/edge/ws/playwright.query.json +100 -0
  102. package/build/routes/firefox/tests/kill-sessions.spec.js +1 -1
  103. package/build/routes/webkit/tests/kill-sessions.spec.js +1 -1
  104. package/build/sdk-utils.js +1 -1
  105. package/build/shared/scrape.http.js +2 -2
  106. package/build/types.d.ts +32 -0
  107. package/build/types.js +18 -0
  108. package/build/utils.d.ts +1 -0
  109. package/build/utils.js +16 -2
  110. package/docker/chrome/Dockerfile +14 -14
  111. package/docker/chromium/Dockerfile +14 -14
  112. package/docker/edge/.dockerignore +16 -0
  113. package/docker/edge/Dockerfile +43 -0
  114. package/docker/firefox/Dockerfile +14 -14
  115. package/docker/multi/Dockerfile +18 -18
  116. package/docker/sdk/Dockerfile +10 -0
  117. package/package.json +18 -18
  118. package/src/browserless.ts +4 -0
  119. package/src/browsers/browsers.cdp.ts +5 -0
  120. package/src/browsers/browsers.playwright.ts +6 -0
  121. package/src/browsers/index.ts +4 -1
  122. package/src/http.ts +9 -0
  123. package/src/routes/chrome/tests/kill-sessions.spec.ts +1 -1
  124. package/src/routes/chromium/tests/kill-sessions.spec.ts +1 -1
  125. package/src/routes/edge/http/content.post.ts +20 -0
  126. package/src/routes/edge/http/download.post.ts +20 -0
  127. package/src/routes/edge/http/function.post.ts +20 -0
  128. package/src/routes/edge/http/json-list.get.ts +7 -0
  129. package/src/routes/edge/http/json-new.put.ts +7 -0
  130. package/src/routes/edge/http/json-protocol.get.ts +7 -0
  131. package/src/routes/edge/http/json-version.get.ts +7 -0
  132. package/src/routes/edge/http/pdf.post.ts +20 -0
  133. package/src/routes/edge/http/performance.post.ts +20 -0
  134. package/src/routes/edge/http/scrape.post.ts +20 -0
  135. package/src/routes/edge/http/screenshot.post.ts +20 -0
  136. package/src/routes/edge/tests/content.spec.ts +376 -0
  137. package/src/routes/edge/tests/download.spec.ts +77 -0
  138. package/src/routes/edge/tests/function.spec.ts +317 -0
  139. package/src/routes/edge/tests/json-version.spec.ts +52 -0
  140. package/src/routes/edge/tests/kill-sessions.spec.ts +99 -0
  141. package/src/routes/edge/tests/page-websocket.spec.ts +129 -0
  142. package/src/routes/edge/tests/pdf.spec.ts +389 -0
  143. package/src/routes/edge/tests/performance.spec.ts +155 -0
  144. package/src/routes/edge/tests/scrape.spec.ts +417 -0
  145. package/src/routes/edge/tests/screenshot.spec.ts +387 -0
  146. package/src/routes/edge/tests/websocket.spec.ts +510 -0
  147. package/src/routes/edge/ws/browser.ts +10 -0
  148. package/src/routes/edge/ws/cdp.ts +17 -0
  149. package/src/routes/edge/ws/page.ts +10 -0
  150. package/src/routes/edge/ws/playwright.ts +17 -0
  151. package/src/routes/firefox/tests/kill-sessions.spec.ts +1 -1
  152. package/src/routes/webkit/tests/kill-sessions.spec.ts +1 -1
  153. package/src/sdk-utils.ts +1 -1
  154. package/src/shared/scrape.http.ts +2 -2
  155. package/src/types.ts +19 -0
  156. package/src/utils.ts +38 -16
  157. package/static/docs/swagger.json +2097 -10
  158. package/static/docs/swagger.min.json +2096 -9
  159. package/static/function/client.js +76 -68
  160. package/static/function/index.html +76 -68
@@ -0,0 +1,417 @@
1
+ import { Browserless, Config, Metrics } from '@browserless.io/browserless';
2
+ import { expect } from 'chai';
3
+
4
+ describe('/edge/scrape API', function () {
5
+ let browserless: Browserless;
6
+
7
+ const start = ({
8
+ config = new Config(),
9
+ metrics = new Metrics(),
10
+ }: { config?: Config; metrics?: Metrics } = {}) => {
11
+ browserless = new Browserless({ config, metrics });
12
+ return browserless.start();
13
+ };
14
+
15
+ afterEach(async () => {
16
+ await browserless.stop();
17
+ });
18
+
19
+ it('allows requests', async () => {
20
+ const config = new Config();
21
+ config.setToken('browserless');
22
+ const metrics = new Metrics();
23
+ await start({ config, metrics });
24
+ const body = {
25
+ elements: [
26
+ {
27
+ selector: 'a',
28
+ },
29
+ ],
30
+ url: 'https://example.com',
31
+ };
32
+
33
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
34
+ body: JSON.stringify(body),
35
+ headers: {
36
+ 'content-type': 'application/json',
37
+ },
38
+ method: 'POST',
39
+ }).then((res) => {
40
+ expect(res.headers.get('content-type')).to.equal(
41
+ 'application/json; charset=UTF-8',
42
+ );
43
+ expect(res.status).to.equal(200);
44
+ });
45
+ });
46
+
47
+ it('404s GET requests', async () => {
48
+ const config = new Config();
49
+ config.setToken('browserless');
50
+ const metrics = new Metrics();
51
+ await start({ config, metrics });
52
+
53
+ await fetch('http://localhost:3000/edge/scrape?token=browserless').then(
54
+ (res) => {
55
+ expect(res.headers.get('content-type')).to.equal(
56
+ 'text/plain; charset=UTF-8',
57
+ );
58
+ expect(res.status).not.to.equal(200);
59
+ },
60
+ );
61
+ });
62
+
63
+ it('handles debug options', async () => {
64
+ const config = new Config();
65
+ config.setToken('browserless');
66
+ const metrics = new Metrics();
67
+ await start({ config, metrics });
68
+ const body = {
69
+ debugOpts: {
70
+ network: true,
71
+ },
72
+ elements: [
73
+ {
74
+ selector: 'a',
75
+ },
76
+ ],
77
+ url: 'https://example.com',
78
+ };
79
+
80
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
81
+ body: JSON.stringify(body),
82
+ headers: {
83
+ 'content-type': 'application/json',
84
+ },
85
+ method: 'POST',
86
+ }).then(async (res) => {
87
+ expect(res.headers.get('content-type')).to.equal(
88
+ 'application/json; charset=UTF-8',
89
+ );
90
+ expect(res.status).to.equal(200);
91
+
92
+ const json = await res.json();
93
+ expect(json).to.have.property('debug');
94
+ expect(json.debug).to.have.property('network');
95
+ });
96
+ });
97
+
98
+ it('handles selector timeouts', async () => {
99
+ const config = new Config();
100
+ config.setToken('browserless');
101
+ const metrics = new Metrics();
102
+ await start({ config, metrics });
103
+ const body = {
104
+ elements: [
105
+ {
106
+ selector: 'blink',
107
+ timeout: 1000,
108
+ },
109
+ ],
110
+ url: 'https://example.com',
111
+ };
112
+
113
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
114
+ body: JSON.stringify(body),
115
+ headers: {
116
+ 'content-type': 'application/json',
117
+ },
118
+ method: 'POST',
119
+ }).then(async (res) => {
120
+ expect(await res.text()).to.contain('Timed out waiting for selector');
121
+ expect(res.status).not.to.equal(200);
122
+ });
123
+ });
124
+
125
+ it('handles `waitForFunction` properties', async () => {
126
+ const config = new Config();
127
+ config.setToken('browserless');
128
+ const metrics = new Metrics();
129
+ await start({ config, metrics });
130
+ const body = {
131
+ elements: [
132
+ {
133
+ selector: 'a',
134
+ },
135
+ ],
136
+ url: 'https://example.com',
137
+ waitForFunction: {
138
+ fn: '() => 5 + 5',
139
+ },
140
+ };
141
+
142
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
143
+ body: JSON.stringify(body),
144
+ headers: {
145
+ 'content-type': 'application/json',
146
+ },
147
+ method: 'POST',
148
+ }).then((res) => {
149
+ expect(res.headers.get('content-type')).to.equal(
150
+ 'application/json; charset=UTF-8',
151
+ );
152
+ expect(res.status).to.equal(200);
153
+ });
154
+ });
155
+
156
+ it('handles async `waitForFunction` properties', async () => {
157
+ const config = new Config();
158
+ config.setToken('browserless');
159
+ const metrics = new Metrics();
160
+ await start({ config, metrics });
161
+ const body = {
162
+ elements: [
163
+ {
164
+ selector: 'a',
165
+ },
166
+ ],
167
+ url: 'https://example.com',
168
+ waitForFunction: {
169
+ fn: 'async () => new Promise(resolve => resolve(5))',
170
+ },
171
+ };
172
+
173
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
174
+ body: JSON.stringify(body),
175
+ headers: {
176
+ 'content-type': 'application/json',
177
+ },
178
+ method: 'POST',
179
+ }).then((res) => {
180
+ expect(res.headers.get('content-type')).to.equal(
181
+ 'application/json; charset=UTF-8',
182
+ );
183
+ expect(res.status).to.equal(200);
184
+ });
185
+ });
186
+
187
+ it('handles `waitForSelector` properties', async () => {
188
+ const config = new Config();
189
+ config.setToken('browserless');
190
+ const metrics = new Metrics();
191
+ await start({ config, metrics });
192
+ const body = {
193
+ elements: [
194
+ {
195
+ selector: 'a',
196
+ },
197
+ ],
198
+ url: 'https://example.com',
199
+ waitForSelector: {
200
+ selector: 'h1',
201
+ },
202
+ };
203
+
204
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
205
+ body: JSON.stringify(body),
206
+ headers: {
207
+ 'content-type': 'application/json',
208
+ },
209
+ method: 'POST',
210
+ }).then((res) => {
211
+ expect(res.headers.get('content-type')).to.equal(
212
+ 'application/json; charset=UTF-8',
213
+ );
214
+ expect(res.status).to.equal(200);
215
+ });
216
+ });
217
+
218
+ it('handles `waitForTimeout` properties', async () => {
219
+ const config = new Config();
220
+ config.setToken('browserless');
221
+ const metrics = new Metrics();
222
+ await start({ config, metrics });
223
+ const body = {
224
+ elements: [
225
+ {
226
+ selector: 'a',
227
+ },
228
+ ],
229
+ url: 'https://example.com',
230
+ waitForTimeout: 500,
231
+ };
232
+
233
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
234
+ body: JSON.stringify(body),
235
+ headers: {
236
+ 'content-type': 'application/json',
237
+ },
238
+ method: 'POST',
239
+ }).then((res) => {
240
+ expect(res.headers.get('content-type')).to.equal(
241
+ 'application/json; charset=UTF-8',
242
+ );
243
+ expect(res.status).to.equal(200);
244
+ });
245
+ });
246
+
247
+ it('handles `waitForEvent` properties', async () => {
248
+ const config = new Config();
249
+ config.setToken('browserless');
250
+ const metrics = new Metrics();
251
+ await start({ config, metrics });
252
+
253
+ const body = {
254
+ elements: [
255
+ {
256
+ selector: 'a',
257
+ },
258
+ ],
259
+ html: `<script type="text/javascript">
260
+ const event = new Event("customEvent");
261
+ setTimeout(() => document.dispatchEvent(event), 1500);
262
+ </script><a href="/">Link</a>`,
263
+ waitForEvent: {
264
+ event: 'customEvent',
265
+ },
266
+ };
267
+
268
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
269
+ body: JSON.stringify(body),
270
+ headers: {
271
+ 'content-type': 'application/json',
272
+ },
273
+ method: 'POST',
274
+ }).then((res) => {
275
+ expect(res.status).to.equal(200);
276
+ expect(res.headers.get('content-type')).to.equal(
277
+ 'application/json; charset=UTF-8',
278
+ );
279
+ });
280
+ });
281
+
282
+ it('allows cookies', async () => {
283
+ const config = new Config();
284
+ config.setToken('browserless');
285
+ const metrics = new Metrics();
286
+ await start({ config, metrics });
287
+ const body = {
288
+ cookies: [{ domain: 'example.com', name: 'foo', value: 'bar' }],
289
+ elements: [
290
+ {
291
+ selector: 'a',
292
+ },
293
+ ],
294
+ url: 'https://example.com',
295
+ };
296
+
297
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
298
+ body: JSON.stringify(body),
299
+ headers: {
300
+ 'content-type': 'application/json',
301
+ },
302
+ method: 'POST',
303
+ }).then((res) => {
304
+ expect(res.headers.get('content-type')).to.equal(
305
+ 'application/json; charset=UTF-8',
306
+ );
307
+ expect(res.status).to.equal(200);
308
+ });
309
+ });
310
+
311
+ it('times out requests', async () => {
312
+ const config = new Config();
313
+ config.setToken('browserless');
314
+ const metrics = new Metrics();
315
+ await start({ config, metrics });
316
+ const body = {
317
+ elements: [
318
+ {
319
+ selector: 'a',
320
+ },
321
+ ],
322
+ url: 'https://example.com',
323
+ };
324
+
325
+ await fetch(
326
+ 'http://localhost:3000/edge/scrape?token=browserless&timeout=10',
327
+ {
328
+ body: JSON.stringify(body),
329
+ headers: {
330
+ 'content-type': 'application/json',
331
+ },
332
+ method: 'POST',
333
+ },
334
+ ).then((res) => {
335
+ expect(res.status).to.equal(408);
336
+ });
337
+ });
338
+
339
+ it('rejects requests', async () => {
340
+ const config = new Config();
341
+ config.setConcurrent(0);
342
+ config.setQueued(0);
343
+ config.setToken('browserless');
344
+ const metrics = new Metrics();
345
+ await start({ config, metrics });
346
+
347
+ const body = {
348
+ elements: [
349
+ {
350
+ selector: 'a',
351
+ },
352
+ ],
353
+ url: 'https://example.com',
354
+ };
355
+
356
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
357
+ body: JSON.stringify(body),
358
+ headers: {
359
+ 'content-type': 'application/json',
360
+ },
361
+ method: 'POST',
362
+ }).then((res) => {
363
+ expect(res.status).to.equal(429);
364
+ });
365
+ });
366
+
367
+ it('allows goto options', async () => {
368
+ const config = new Config();
369
+ config.setToken('browserless');
370
+ const metrics = new Metrics();
371
+ await start({ config, metrics });
372
+
373
+ const body = {
374
+ elements: [
375
+ {
376
+ selector: 'a',
377
+ },
378
+ ],
379
+ url: 'https://example.com',
380
+ };
381
+
382
+ await fetch('http://localhost:3000/edge/scrape?token=browserless', {
383
+ body: JSON.stringify(body),
384
+ headers: {
385
+ 'content-type': 'application/json',
386
+ },
387
+ method: 'POST',
388
+ }).then((res) => {
389
+ expect(res.status).to.equal(200);
390
+ });
391
+ });
392
+
393
+ it('allows requests without token when auth token is not set', async () => {
394
+ await start();
395
+ const body = {
396
+ elements: [
397
+ {
398
+ selector: 'a',
399
+ },
400
+ ],
401
+ url: 'https://example.com',
402
+ };
403
+
404
+ await fetch('http://localhost:3000/edge/scrape', {
405
+ body: JSON.stringify(body),
406
+ headers: {
407
+ 'content-type': 'application/json',
408
+ },
409
+ method: 'POST',
410
+ }).then((res) => {
411
+ expect(res.headers.get('content-type')).to.equal(
412
+ 'application/json; charset=UTF-8',
413
+ );
414
+ expect(res.status).to.equal(200);
415
+ });
416
+ });
417
+ });