@browserless.io/browserless 2.25.0-beta-2 → 2.25.1

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 (224) hide show
  1. package/CHANGELOG.md +43 -3
  2. package/README.md +4 -5
  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 +11 -2
  8. package/build/browsers/index.js +4 -3
  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/management/http/meta.get.js +3 -1
  104. package/build/routes/webkit/tests/kill-sessions.spec.js +1 -1
  105. package/build/sdk-utils.js +1 -1
  106. package/build/shared/scrape.http.js +2 -2
  107. package/build/types.d.ts +32 -0
  108. package/build/types.js +18 -0
  109. package/build/utils.d.ts +1 -0
  110. package/build/utils.js +16 -2
  111. package/docker/chrome/Dockerfile +14 -14
  112. package/docker/chromium/Dockerfile +14 -14
  113. package/docker/edge/.dockerignore +16 -0
  114. package/docker/edge/Dockerfile +43 -0
  115. package/docker/firefox/Dockerfile +14 -14
  116. package/docker/multi/Dockerfile +18 -18
  117. package/docker/sdk/Dockerfile +10 -0
  118. package/extensions/ublock/_locales/ar/messages.json +3 -3
  119. package/extensions/ublock/_locales/bg/messages.json +1 -1
  120. package/extensions/ublock/_locales/br_FR/messages.json +2 -2
  121. package/extensions/ublock/_locales/cy/messages.json +11 -11
  122. package/extensions/ublock/_locales/el/messages.json +2 -2
  123. package/extensions/ublock/_locales/hu/messages.json +1 -1
  124. package/extensions/ublock/_locales/id/messages.json +1 -1
  125. package/extensions/ublock/_locales/lv/messages.json +4 -4
  126. package/extensions/ublock/_locales/mk/messages.json +130 -130
  127. package/extensions/ublock/_locales/oc/messages.json +1 -1
  128. package/extensions/ublock/_locales/pt_BR/messages.json +1 -1
  129. package/extensions/ublock/_locales/pt_PT/messages.json +2 -2
  130. package/extensions/ublock/_locales/si/messages.json +100 -100
  131. package/extensions/ublock/_locales/sr/messages.json +4 -4
  132. package/extensions/ublock/_locales/vi/messages.json +19 -19
  133. package/extensions/ublock/_locales/zh_TW/messages.json +28 -28
  134. package/extensions/ublock/assets/assets.json +33 -29
  135. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +2984 -3287
  136. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +150 -171
  137. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +37 -27
  138. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +802 -888
  139. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2355 -2071
  140. package/extensions/ublock/assets/ublock/badlists.txt +9 -1
  141. package/extensions/ublock/assets/ublock/badware.min.txt +354 -243
  142. package/extensions/ublock/assets/ublock/filters.min.txt +5837 -5737
  143. package/extensions/ublock/assets/ublock/privacy.min.txt +151 -38
  144. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +83 -127
  145. package/extensions/ublock/assets/ublock/unbreak.min.txt +66 -50
  146. package/extensions/ublock/css/codemirror.css +4 -0
  147. package/extensions/ublock/document-blocked.html +3 -1
  148. package/extensions/ublock/js/arglist-parser.js +116 -0
  149. package/extensions/ublock/js/background.js +1 -1
  150. package/extensions/ublock/js/logger-ui.js +1 -1
  151. package/extensions/ublock/js/messaging.js +9 -2
  152. package/extensions/ublock/js/pagestore.js +3 -1
  153. package/extensions/ublock/js/redirect-engine.js +3 -1
  154. package/extensions/ublock/{assets/resources/set-attr.js → js/resources/attribute.js} +115 -11
  155. package/extensions/ublock/js/resources/base.js +38 -0
  156. package/extensions/ublock/js/resources/cookie.js +419 -0
  157. package/extensions/ublock/js/resources/href-sanitizer.js +188 -0
  158. package/extensions/ublock/js/resources/localstorage.js +235 -0
  159. package/extensions/ublock/js/resources/parse-replace.js +54 -0
  160. package/extensions/ublock/js/resources/prevent-settimeout.js +236 -0
  161. package/extensions/ublock/js/resources/proxy-apply.js +109 -0
  162. package/extensions/ublock/js/resources/replace-argument.js +120 -0
  163. package/extensions/ublock/{assets → js}/resources/run-at.js +20 -4
  164. package/extensions/ublock/{assets → js}/resources/safe-self.js +5 -4
  165. package/extensions/ublock/{assets → js}/resources/scriptlets.js +90 -1589
  166. package/extensions/ublock/js/resources/set-constant.js +287 -0
  167. package/extensions/ublock/js/resources/shared.js +44 -0
  168. package/extensions/ublock/js/resources/spoof-css.js +163 -0
  169. package/extensions/ublock/js/s14e-serializer.js +2 -1
  170. package/extensions/ublock/js/scriptlet-filtering-core.js +1 -1
  171. package/extensions/ublock/js/scriptlet-filtering.js +1 -31
  172. package/extensions/ublock/js/static-dnr-filtering.js +143 -129
  173. package/extensions/ublock/js/static-filtering-parser.js +27 -117
  174. package/extensions/ublock/js/static-net-filtering.js +53 -141
  175. package/extensions/ublock/js/traffic.js +1 -1
  176. package/extensions/ublock/js/urlskip.js +166 -0
  177. package/extensions/ublock/js/vapi-background-ext.js +38 -14
  178. package/extensions/ublock/manifest.json +1 -1
  179. package/package.json +22 -22
  180. package/src/browserless.ts +4 -0
  181. package/src/browsers/browsers.cdp.ts +5 -0
  182. package/src/browsers/browsers.playwright.ts +14 -1
  183. package/src/browsers/index.ts +5 -2
  184. package/src/http.ts +9 -0
  185. package/src/routes/chrome/tests/kill-sessions.spec.ts +1 -1
  186. package/src/routes/chromium/tests/kill-sessions.spec.ts +1 -1
  187. package/src/routes/edge/http/content.post.ts +20 -0
  188. package/src/routes/edge/http/download.post.ts +20 -0
  189. package/src/routes/edge/http/function.post.ts +20 -0
  190. package/src/routes/edge/http/json-list.get.ts +7 -0
  191. package/src/routes/edge/http/json-new.put.ts +7 -0
  192. package/src/routes/edge/http/json-protocol.get.ts +7 -0
  193. package/src/routes/edge/http/json-version.get.ts +7 -0
  194. package/src/routes/edge/http/pdf.post.ts +20 -0
  195. package/src/routes/edge/http/performance.post.ts +20 -0
  196. package/src/routes/edge/http/scrape.post.ts +20 -0
  197. package/src/routes/edge/http/screenshot.post.ts +20 -0
  198. package/src/routes/edge/tests/content.spec.ts +376 -0
  199. package/src/routes/edge/tests/download.spec.ts +77 -0
  200. package/src/routes/edge/tests/function.spec.ts +317 -0
  201. package/src/routes/edge/tests/json-version.spec.ts +52 -0
  202. package/src/routes/edge/tests/kill-sessions.spec.ts +99 -0
  203. package/src/routes/edge/tests/page-websocket.spec.ts +129 -0
  204. package/src/routes/edge/tests/pdf.spec.ts +389 -0
  205. package/src/routes/edge/tests/performance.spec.ts +155 -0
  206. package/src/routes/edge/tests/scrape.spec.ts +417 -0
  207. package/src/routes/edge/tests/screenshot.spec.ts +387 -0
  208. package/src/routes/edge/tests/websocket.spec.ts +510 -0
  209. package/src/routes/edge/ws/browser.ts +10 -0
  210. package/src/routes/edge/ws/cdp.ts +17 -0
  211. package/src/routes/edge/ws/page.ts +10 -0
  212. package/src/routes/edge/ws/playwright.ts +17 -0
  213. package/src/routes/firefox/tests/kill-sessions.spec.ts +1 -1
  214. package/src/routes/management/http/meta.get.ts +6 -1
  215. package/src/routes/management/http/static.get.ts +1 -1
  216. package/src/routes/webkit/tests/kill-sessions.spec.ts +1 -1
  217. package/src/sdk-utils.ts +1 -1
  218. package/src/shared/scrape.http.ts +2 -2
  219. package/src/types.ts +19 -0
  220. package/src/utils.ts +38 -16
  221. package/static/docs/swagger.json +2097 -10
  222. package/static/docs/swagger.min.json +2096 -9
  223. package/static/function/client.js +141 -253
  224. package/static/function/index.html +141 -253
@@ -0,0 +1,277 @@
1
+ import { Browserless, Config, Metrics } from '@browserless.io/browserless';
2
+ import { expect } from 'chai';
3
+ describe('/edge/function API', function () {
4
+ let browserless;
5
+ const start = ({ config = new Config(), metrics = new Metrics(), } = {}) => {
6
+ browserless = new Browserless({ config, metrics });
7
+ return browserless.start();
8
+ };
9
+ afterEach(async () => {
10
+ await browserless.stop();
11
+ });
12
+ it('runs functions', async () => {
13
+ const config = new Config();
14
+ config.setToken('browserless');
15
+ const metrics = new Metrics();
16
+ await start({ config, metrics });
17
+ const body = {
18
+ code: `export default async function ({ page }) {
19
+ return Promise.resolve({
20
+ data: "ok",
21
+ type: "application/text",
22
+ });
23
+ }`,
24
+ context: {},
25
+ };
26
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
27
+ body: JSON.stringify(body),
28
+ headers: {
29
+ 'content-type': 'application/json',
30
+ },
31
+ method: 'POST',
32
+ }).then(async (res) => {
33
+ const json = await res.json();
34
+ expect(json).to.have.property('data');
35
+ expect(json.data).to.equal('ok');
36
+ expect(res.status).to.equal(200);
37
+ });
38
+ });
39
+ it('runs functions with "context"', async () => {
40
+ const config = new Config();
41
+ config.setToken('browserless');
42
+ const metrics = new Metrics();
43
+ await start({ config, metrics });
44
+ const body = {
45
+ code: `export default async function ({ page, context }) {
46
+ if (!!context.ok) {
47
+ return Promise.resolve({
48
+ data: "ok",
49
+ type: "application/text",
50
+ });
51
+ }
52
+ return Promise.reject(new Error('Bad context!'));
53
+ }`,
54
+ context: {
55
+ ok: true,
56
+ },
57
+ };
58
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
59
+ body: JSON.stringify(body),
60
+ headers: {
61
+ 'content-type': 'application/json',
62
+ },
63
+ method: 'POST',
64
+ }).then(async (res) => {
65
+ const json = await res.json();
66
+ expect(json).to.have.property('data');
67
+ expect(json.data).to.equal('ok');
68
+ expect(res.status).to.equal(200);
69
+ });
70
+ });
71
+ it('runs "application/javascript" functions', async () => {
72
+ const config = new Config();
73
+ config.setToken('browserless');
74
+ const metrics = new Metrics();
75
+ await start({ config, metrics });
76
+ const body = `export default async function ({ page }) {
77
+ return Promise.resolve({
78
+ data: "ok",
79
+ type: "application/text",
80
+ });
81
+ }`;
82
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
83
+ body,
84
+ headers: { 'Content-Type': 'application/javascript' },
85
+ method: 'POST',
86
+ }).then(async (res) => {
87
+ const json = await res.json();
88
+ expect(json).to.have.property('data');
89
+ expect(json.data).to.equal('ok');
90
+ expect(json.type).to.equal('application/text');
91
+ expect(res.status).to.equal(200);
92
+ });
93
+ });
94
+ it('runs functions that import libraries', async () => {
95
+ const config = new Config();
96
+ config.setToken('browserless');
97
+ const metrics = new Metrics();
98
+ await start({ config, metrics });
99
+ const body = {
100
+ code: `
101
+ import 'https://code.jquery.com/jquery-3.6.0.min.js';
102
+ export default async function ({ page }) {
103
+ return Promise.resolve({
104
+ data: typeof window.jQuery,
105
+ });
106
+ }`,
107
+ context: {},
108
+ };
109
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
110
+ body: JSON.stringify(body),
111
+ headers: {
112
+ 'content-type': 'application/json',
113
+ },
114
+ method: 'POST',
115
+ }).then(async (res) => {
116
+ const json = await res.json();
117
+ expect(json).to.have.property('data');
118
+ expect(json.data).to.equal('function');
119
+ expect(res.status).to.equal(200);
120
+ });
121
+ });
122
+ it('runs functions with custom return types', async () => {
123
+ const config = new Config();
124
+ config.setToken('browserless');
125
+ const metrics = new Metrics();
126
+ await start({ config, metrics });
127
+ const body = {
128
+ code: `
129
+ export default async function ({ page }) {
130
+ return Promise.resolve({
131
+ data: {
132
+ status: 'ok',
133
+ },
134
+ });
135
+ }`,
136
+ context: {},
137
+ };
138
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
139
+ body: JSON.stringify(body),
140
+ headers: {
141
+ 'content-type': 'application/json',
142
+ },
143
+ method: 'POST',
144
+ }).then(async (res) => {
145
+ const json = await res.json();
146
+ expect(res.headers.get('content-type')).to.equal(`application/json; charset=UTF-8`);
147
+ expect(json).to.have.property('data');
148
+ expect(res.status).to.equal(200);
149
+ });
150
+ });
151
+ it('times out requests', async () => {
152
+ const config = new Config();
153
+ config.setToken('browserless');
154
+ const metrics = new Metrics();
155
+ await start({ config, metrics });
156
+ const body = {
157
+ code: `export default async function ({ page }) {
158
+ return Promise.resolve({
159
+ data: "ok",
160
+ type: "application/text",
161
+ });
162
+ }`,
163
+ context: {},
164
+ };
165
+ await fetch('http://localhost:3000/edge/function?token=browserless&timeout=10', {
166
+ body: JSON.stringify(body),
167
+ headers: {
168
+ 'content-type': 'application/json',
169
+ },
170
+ method: 'POST',
171
+ }).then((res) => {
172
+ expect(res.status).to.equal(408);
173
+ });
174
+ });
175
+ it('rejects requests with bad content-types', async () => {
176
+ const config = new Config();
177
+ config.setConcurrent(0);
178
+ config.setQueued(0);
179
+ config.setToken('browserless');
180
+ const metrics = new Metrics();
181
+ await start({ config, metrics });
182
+ const body = {
183
+ code: `export default async function ({ page }) {
184
+ return Promise.resolve({
185
+ data: "ok",
186
+ type: "application/text",
187
+ });
188
+ }`,
189
+ context: {},
190
+ };
191
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
192
+ body: JSON.stringify(body),
193
+ headers: {
194
+ 'content-type': 'joelson',
195
+ },
196
+ method: 'POST',
197
+ }).then(async (res) => {
198
+ return expect(res.status).to.equal(404);
199
+ });
200
+ });
201
+ it('rejects requests with 429', async () => {
202
+ const config = new Config();
203
+ config.setConcurrent(0);
204
+ config.setQueued(0);
205
+ config.setToken('browserless');
206
+ const metrics = new Metrics();
207
+ await start({ config, metrics });
208
+ const body = {
209
+ code: `export default async function ({ page }) {
210
+ return Promise.resolve({
211
+ data: "ok",
212
+ type: "application/text",
213
+ });
214
+ }`,
215
+ context: {},
216
+ };
217
+ await fetch('http://localhost:3000/edge/function?token=browserless', {
218
+ body: JSON.stringify(body),
219
+ headers: {
220
+ 'content-type': 'application/json',
221
+ },
222
+ method: 'POST',
223
+ }).then(async (res) => {
224
+ return expect(res.status).to.equal(429);
225
+ });
226
+ });
227
+ it('rejects requests that are unauthorized', async () => {
228
+ const config = new Config();
229
+ config.setToken('browserless');
230
+ const metrics = new Metrics();
231
+ await start({ config, metrics });
232
+ const body = {
233
+ code: `export default async function ({ page }) {
234
+ return Promise.resolve({
235
+ data: "ok",
236
+ type: "application/text",
237
+ });
238
+ }`,
239
+ context: {},
240
+ };
241
+ await fetch('http://localhost:3000/edge/function?token=bless', {
242
+ body: JSON.stringify(body),
243
+ headers: {
244
+ 'content-type': 'application/json',
245
+ },
246
+ method: 'POST',
247
+ }).then(async (res) => {
248
+ return expect(res.status).to.equal(401);
249
+ });
250
+ });
251
+ it('allows requests without token when auth token is not set', async () => {
252
+ const config = new Config();
253
+ const metrics = new Metrics();
254
+ await start({ config, metrics });
255
+ const body = {
256
+ code: `export default async function ({ page }) {
257
+ return Promise.resolve({
258
+ data: "ok",
259
+ type: "application/text",
260
+ });
261
+ }`,
262
+ context: {},
263
+ };
264
+ await fetch('http://localhost:3000/edge/function', {
265
+ body: JSON.stringify(body),
266
+ headers: {
267
+ 'content-type': 'application/json',
268
+ },
269
+ method: 'POST',
270
+ }).then(async (res) => {
271
+ const json = await res.json();
272
+ expect(json).to.have.property('data');
273
+ expect(json.data).to.equal('ok');
274
+ expect(res.status).to.equal(200);
275
+ });
276
+ });
277
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ import { Browserless, Config, Metrics } from '@browserless.io/browserless';
2
+ import { expect } from 'chai';
3
+ describe('/json/version API', function () {
4
+ let browserless;
5
+ const start = ({ config = new Config(), metrics = new Metrics(), } = {}) => {
6
+ browserless = new Browserless({ config, metrics });
7
+ return browserless.start();
8
+ };
9
+ afterEach(async () => {
10
+ await browserless.stop();
11
+ });
12
+ it('allows requests to /json/version', async () => {
13
+ const config = new Config();
14
+ config.setToken('browserless');
15
+ const metrics = new Metrics();
16
+ await start({ config, metrics });
17
+ const res = await fetch('http://localhost:3000/json/version?token=browserless');
18
+ const resJSON = await res.json();
19
+ [
20
+ 'Browser',
21
+ 'Protocol-Version',
22
+ 'User-Agent',
23
+ 'V8-Version',
24
+ 'WebKit-Version',
25
+ 'webSocketDebuggerUrl',
26
+ 'Debugger-Version',
27
+ ].forEach((k) => expect(resJSON).to.haveOwnProperty(k));
28
+ });
29
+ it('rejects unauthorized requests to /json/version', async () => {
30
+ const config = new Config();
31
+ config.setToken('browserless');
32
+ const metrics = new Metrics();
33
+ await start({ config, metrics });
34
+ const res = await fetch('http://localhost:3000/json/version?token=imabadboi');
35
+ expect(res.status).to.equal(401);
36
+ });
37
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,80 @@
1
+ import { Browserless, Config, Metrics } from '@browserless.io/browserless';
2
+ import { expect } from 'chai';
3
+ import puppeteer from 'puppeteer-core';
4
+ describe('/kill API', function () {
5
+ let browserless;
6
+ const start = ({ config = new Config(), metrics = new Metrics(), } = {}) => {
7
+ config.setToken('6R0W53R135510');
8
+ browserless = new Browserless({ config, metrics });
9
+ return browserless.start();
10
+ };
11
+ afterEach(async () => {
12
+ await browserless.stop();
13
+ });
14
+ it('Kill all sessions', async () => {
15
+ await start();
16
+ const browser1 = await puppeteer.connect({
17
+ browserWSEndpoint: `ws://localhost:3000/edge?token=6R0W53R135510`,
18
+ });
19
+ const browser2 = await puppeteer.connect({
20
+ browserWSEndpoint: `ws://localhost:3000/edge?token=6R0W53R135510`,
21
+ });
22
+ await fetch('http://localhost:3000/kill/all?token=6R0W53R135510').then(async (res) => {
23
+ expect(res.status).to.equal(204);
24
+ });
25
+ let errorThrown1;
26
+ try {
27
+ await browser1.newPage();
28
+ }
29
+ catch (e) {
30
+ errorThrown1 = e;
31
+ }
32
+ let errorThrown2;
33
+ try {
34
+ await browser2.newPage();
35
+ }
36
+ catch (e) {
37
+ errorThrown2 = e;
38
+ }
39
+ expect(errorThrown1.message).contains('closed');
40
+ expect(errorThrown2.message).contains('closed');
41
+ });
42
+ it('Kill session by browserId', async () => {
43
+ await start();
44
+ const browser = await puppeteer.connect({
45
+ browserWSEndpoint: `ws://localhost:3000/edge?token=6R0W53R135510`,
46
+ });
47
+ await fetch('http://localhost:3000/sessions?token=6R0W53R135510').then(async (res) => {
48
+ const sessions = await res.json();
49
+ const browserId = sessions[0].browserId;
50
+ await fetch(`http://localhost:3000/kill/${browserId}?token=6R0W53R135510`).then(async (res) => {
51
+ expect(res.status).to.equal(204);
52
+ });
53
+ });
54
+ let errorThrown;
55
+ try {
56
+ await browser.newPage();
57
+ }
58
+ catch (e) {
59
+ errorThrown = e;
60
+ }
61
+ expect(errorThrown.message).contains('closed');
62
+ });
63
+ it('Kill session by trackingId', async () => {
64
+ await start();
65
+ const browser = await puppeteer.connect({
66
+ browserWSEndpoint: `ws://localhost:3000/edge?token=6R0W53R135510&trackingId=session-1`,
67
+ });
68
+ await fetch('http://localhost:3000/kill/session-1?token=6R0W53R135510').then(async (res) => {
69
+ expect(res.status).to.equal(204);
70
+ });
71
+ let errorThrown;
72
+ try {
73
+ await browser.newPage();
74
+ }
75
+ catch (e) {
76
+ errorThrown = e;
77
+ }
78
+ expect(errorThrown.message).contains('closed');
79
+ });
80
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,97 @@
1
+ import { Browserless, Config, Metrics } from '@browserless.io/browserless';
2
+ import puppeteer, { Connection } from 'puppeteer-core';
3
+ import { NodeWebSocketTransport } from 'puppeteer-core/lib/esm/puppeteer/node/NodeWebSocketTransport.js';
4
+ import { expect } from 'chai';
5
+ describe('WebSocket Page API', function () {
6
+ // Server shutdown can take a few seconds
7
+ // and so can these tests :/
8
+ this.timeout(5000);
9
+ let browserless;
10
+ const start = ({ config = new Config(), metrics = new Metrics(), } = {}) => {
11
+ browserless = new Browserless({ config, metrics });
12
+ return browserless.start();
13
+ };
14
+ afterEach(async () => {
15
+ await browserless.stop();
16
+ });
17
+ it('forwards requests to running pages', async () => {
18
+ const config = new Config();
19
+ const metrics = new Metrics();
20
+ await start({ config, metrics });
21
+ const browser = await puppeteer.connect({
22
+ browserWSEndpoint: `ws://localhost:3000/edge`,
23
+ });
24
+ const page = await browser.newPage();
25
+ await page.goto('https://example.com/');
26
+ // @ts-ignore
27
+ const pageId = page.target()._targetId;
28
+ const webSocketDebuggerUrl = `ws://localhost:3000/devtools/page/${pageId}`;
29
+ // Connect to raw page target
30
+ const cdp = new Connection(webSocketDebuggerUrl, await NodeWebSocketTransport.create(webSocketDebuggerUrl));
31
+ // Send a command
32
+ const result = await cdp.send('Page.enable');
33
+ await browser.close();
34
+ expect(result);
35
+ });
36
+ it('creates pages when interacting with /json/new', async () => {
37
+ const config = new Config();
38
+ const metrics = new Metrics();
39
+ await start({ config, metrics });
40
+ const { webSocketDebuggerUrl } = await fetch('http://localhost:3000/json/new', {
41
+ method: 'PUT',
42
+ }).then((r) => r.json());
43
+ // Connect to raw page target
44
+ const cdp = new Connection(webSocketDebuggerUrl, await NodeWebSocketTransport.create(webSocketDebuggerUrl));
45
+ // Send a command
46
+ const result = await cdp.send('Page.enable');
47
+ cdp.dispose();
48
+ expect(result);
49
+ });
50
+ it('rejects unauthorized page requests', async () => {
51
+ const config = new Config();
52
+ config.setToken('browserless');
53
+ const metrics = new Metrics();
54
+ await start({ config, metrics });
55
+ const browser = await puppeteer.connect({
56
+ browserWSEndpoint: `ws://localhost:3000/edge?token=browserless`,
57
+ });
58
+ const page = await browser.newPage();
59
+ await page.goto('https://example.com/');
60
+ // @ts-ignore
61
+ const pageId = page.target()._targetId;
62
+ const webSocketDebuggerUrl = `ws://localhost:3000/devtools/page/${pageId}`;
63
+ // Connect to raw page target without authorization
64
+ try {
65
+ new Connection(webSocketDebuggerUrl, await NodeWebSocketTransport.create(webSocketDebuggerUrl));
66
+ }
67
+ catch (err) {
68
+ //@ts-ignore
69
+ expect(err.message).to.include('401');
70
+ }
71
+ finally {
72
+ browser.close();
73
+ }
74
+ });
75
+ it('404s pages not found', async () => {
76
+ const config = new Config();
77
+ const metrics = new Metrics();
78
+ await start({ config, metrics });
79
+ const browser = await puppeteer.connect({
80
+ browserWSEndpoint: `ws://localhost:3000/edge?token=browserless`,
81
+ });
82
+ const page = await browser.newPage();
83
+ await page.goto('https://example.com/');
84
+ const webSocketDebuggerUrl = `ws://localhost:3000/devtools/page/im-a-banana`;
85
+ // Connect to raw page target without authorization
86
+ try {
87
+ new Connection(webSocketDebuggerUrl, await NodeWebSocketTransport.create(webSocketDebuggerUrl));
88
+ }
89
+ catch (err) {
90
+ //@ts-ignore
91
+ expect(err.message).to.include('404');
92
+ }
93
+ finally {
94
+ browser.close();
95
+ }
96
+ });
97
+ });
@@ -0,0 +1 @@
1
+ export {};