@browserless.io/browserless 2.12.0-beta-3 → 2.12.0-beta-6
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/browserless.d.ts +3 -3
- package/build/browserless.js +6 -6
- package/build/browsers/chromium.cdp.d.ts +13 -13
- package/build/browsers/chromium.cdp.js +79 -67
- package/build/browsers/chromium.playwright.d.ts +12 -12
- package/build/browsers/chromium.playwright.js +44 -36
- package/build/browsers/firefox.playwright.d.ts +12 -12
- package/build/browsers/firefox.playwright.js +44 -36
- package/build/browsers/index.d.ts +17 -16
- package/build/browsers/index.js +63 -42
- package/build/browsers/webkit.playwright.d.ts +12 -12
- package/build/browsers/webkit.playwright.js +47 -39
- package/build/config.d.ts +65 -63
- package/build/config.js +162 -102
- package/build/file-system.d.ts +4 -4
- package/build/file-system.js +8 -8
- package/build/hooks.d.ts +2 -2
- package/build/hooks.js +4 -4
- package/build/limiter.d.ts +4 -4
- package/build/limiter.js +10 -10
- package/build/logger.d.ts +6 -6
- package/build/logger.js +12 -12
- package/build/metrics.d.ts +12 -12
- package/build/metrics.js +23 -23
- package/build/monitoring.d.ts +4 -4
- package/build/monitoring.js +8 -8
- package/build/router.d.ts +8 -8
- package/build/router.js +74 -70
- package/build/routes/chrome/http/pdf.post.body.json +8 -8
- package/build/routes/chrome/http/scrape.post.body.json +8 -8
- package/build/routes/chrome/http/screenshot.post.body.json +8 -8
- package/build/routes/chromium/http/content.post.body.json +8 -8
- package/build/routes/chromium/http/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/build/routes/firefox/ws/playwright.d.ts +1 -1
- package/build/routes/firefox/ws/playwright.js +2 -2
- package/build/routes/management/http/active.get.d.ts +1 -1
- package/build/routes/management/http/active.get.js +3 -1
- package/build/routes/management/http/config.get.d.ts +1 -1
- package/build/routes/management/http/config.get.js +2 -2
- package/build/routes/management/http/metrics-total.get.d.ts +1 -1
- package/build/routes/management/http/metrics-total.get.js +2 -2
- package/build/routes/management/http/metrics.get.d.ts +1 -1
- package/build/routes/management/http/metrics.get.js +2 -2
- package/build/routes/management/http/pressure.get.d.ts +1 -1
- package/build/routes/management/http/pressure.get.js +2 -2
- package/build/routes/management/http/sessions.get.d.ts +1 -1
- package/build/routes/management/http/sessions.get.js +2 -2
- package/build/routes/management/http/static.get.d.ts +1 -1
- package/build/routes/management/http/static.get.js +2 -2
- package/build/routes/webkit/ws/playwright.d.ts +1 -1
- package/build/routes/webkit/ws/playwright.js +2 -2
- package/build/server.d.ts +5 -5
- package/build/server.js +11 -11
- package/build/shared/browser.ws.d.ts +1 -1
- package/build/shared/browser.ws.js +3 -1
- package/build/shared/chromium.playwright.ws.d.ts +1 -1
- package/build/shared/chromium.playwright.ws.js +2 -2
- package/build/shared/chromium.ws.d.ts +1 -1
- package/build/shared/chromium.ws.js +3 -1
- package/build/shared/content.http.d.ts +1 -1
- package/build/shared/content.http.js +2 -2
- package/build/shared/download.http.d.ts +1 -1
- package/build/shared/download.http.js +60 -58
- package/build/shared/function.http.d.ts +1 -1
- package/build/shared/function.http.js +2 -2
- package/build/shared/json-list.http.d.ts +1 -1
- package/build/shared/json-list.http.js +2 -2
- package/build/shared/json-new.http.d.ts +1 -1
- package/build/shared/json-new.http.js +2 -2
- package/build/shared/json-protocol.http.d.ts +1 -1
- package/build/shared/json-protocol.http.js +2 -2
- package/build/shared/json-version.http.d.ts +1 -1
- package/build/shared/json-version.http.js +2 -2
- package/build/shared/page.ws.d.ts +1 -1
- package/build/shared/page.ws.js +3 -1
- package/build/shared/pdf.http.d.ts +1 -1
- package/build/shared/pdf.http.js +2 -2
- package/build/shared/performance.http.d.ts +1 -1
- package/build/shared/performance.http.js +2 -2
- package/build/shared/scrape.http.d.ts +1 -1
- package/build/shared/scrape.http.js +2 -2
- package/build/shared/screenshot.http.d.ts +1 -1
- package/build/shared/screenshot.http.js +2 -2
- package/build/shared/utils/function/client.d.ts +1 -1
- package/build/shared/utils/function/client.js +3 -1
- package/build/shim.d.ts +1 -1
- package/build/shim.js +2 -2
- package/build/token.d.ts +3 -3
- package/build/token.js +6 -6
- package/build/types.d.ts +5 -5
- package/build/webhooks.d.ts +2 -2
- package/build/webhooks.js +4 -4
- package/extensions/ublock/_locales/eu/messages.json +4 -4
- package/extensions/ublock/_locales/hi/messages.json +5 -5
- package/extensions/ublock/_locales/kn/messages.json +11 -11
- package/extensions/ublock/_locales/nb/messages.json +2 -2
- package/extensions/ublock/_locales/no/messages.json +2 -2
- package/extensions/ublock/_locales/ro/messages.json +1 -1
- package/extensions/ublock/_locales/sv/messages.json +1 -1
- package/extensions/ublock/_locales/zh_CN/messages.json +2 -2
- package/extensions/ublock/assets/assets.json +3 -8
- package/extensions/ublock/assets/resources/scriptlets.js +128 -31
- package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +4870 -3560
- package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +662 -173
- package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +10 -42
- package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +241 -80
- package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2093 -1224
- package/extensions/ublock/assets/ublock/badlists.txt +2 -0
- package/extensions/ublock/assets/ublock/badware.min.txt +408 -287
- package/extensions/ublock/assets/ublock/filters.min.txt +947 -645
- package/extensions/ublock/assets/ublock/privacy.min.txt +43 -8
- package/extensions/ublock/assets/ublock/quick-fixes.min.txt +55 -93
- package/extensions/ublock/assets/ublock/unbreak.min.txt +52 -19
- package/extensions/ublock/css/1p-filters.css +2 -0
- package/extensions/ublock/css/codemirror.css +2 -2
- package/extensions/ublock/css/dashboard.css +2 -5
- package/extensions/ublock/css/epicker-ui.css +3 -3
- package/extensions/ublock/css/fa-icons.css +3 -0
- package/extensions/ublock/css/logger-ui-inspector.css +1 -0
- package/extensions/ublock/css/logger-ui.css +44 -32
- package/extensions/ublock/img/fontawesome/fontawesome-defs.svg +1 -0
- package/extensions/ublock/js/3p-filters.js +4 -5
- package/extensions/ublock/js/biditrie.js +16 -11
- package/extensions/ublock/js/cachestorage.js +37 -37
- package/extensions/ublock/js/contentscript-extra.js +0 -2
- package/extensions/ublock/js/contentscript.js +1 -6
- package/extensions/ublock/js/epicker-ui.js +28 -36
- package/extensions/ublock/js/fa-icons.js +1 -0
- package/extensions/ublock/js/hntrie.js +19 -13
- package/extensions/ublock/js/logger-ui-inspector.js +6 -13
- package/extensions/ublock/js/logger-ui.js +264 -264
- package/extensions/ublock/js/s14e-serializer.js +267 -264
- package/extensions/ublock/js/scriptlet-filtering.js +12 -18
- package/extensions/ublock/js/scriptlets/dom-inspector.js +1 -5
- package/extensions/ublock/js/scriptlets/epicker.js +53 -59
- package/extensions/ublock/js/start.js +0 -8
- package/extensions/ublock/js/storage.js +2 -9
- package/extensions/ublock/js/vapi-background.js +19 -20
- package/extensions/ublock/js/vapi-common.js +2 -7
- package/extensions/ublock/js/vapi.js +0 -4
- package/extensions/ublock/js/webext.js +23 -15
- package/extensions/ublock/logger-ui.html +24 -15
- package/extensions/ublock/manifest.json +2 -3
- package/package.json +4 -4
- package/src/browserless.ts +6 -6
- package/src/browsers/chromium.cdp.ts +35 -25
- package/src/browsers/chromium.playwright.ts +30 -23
- package/src/browsers/firefox.playwright.ts +30 -24
- package/src/browsers/index.ts +81 -50
- package/src/browsers/webkit.playwright.ts +33 -26
- package/src/config.ts +166 -104
- package/src/file-system.ts +9 -9
- package/src/hooks.ts +4 -4
- package/src/limiter.ts +12 -12
- package/src/logger.ts +12 -12
- package/src/metrics.ts +23 -23
- package/src/monitoring.ts +9 -9
- package/src/router.ts +31 -31
- package/src/routes/chrome/tests/websocket.spec.ts +2 -2
- package/src/routes/chromium/tests/websocket.spec.ts +2 -2
- package/src/routes/firefox/tests/websocket.spec.ts +2 -4
- package/src/routes/firefox/ws/playwright.ts +3 -3
- package/src/routes/management/http/active.get.ts +3 -2
- package/src/routes/management/http/config.get.ts +2 -2
- package/src/routes/management/http/metrics-total.get.ts +2 -2
- package/src/routes/management/http/metrics.get.ts +2 -2
- package/src/routes/management/http/pressure.get.ts +2 -2
- package/src/routes/management/http/sessions.get.ts +2 -2
- package/src/routes/management/http/static.get.ts +3 -3
- package/src/routes/webkit/tests/websocket.spec.ts +2 -3
- package/src/routes/webkit/ws/playwright.ts +3 -3
- package/src/server.ts +14 -16
- package/src/shared/browser.ws.ts +4 -2
- package/src/shared/chromium.playwright.ws.ts +3 -3
- package/src/shared/chromium.ws.ts +4 -2
- package/src/shared/content.http.ts +3 -3
- package/src/shared/download.http.ts +4 -3
- package/src/shared/function.http.ts +3 -3
- package/src/shared/json-list.http.ts +2 -2
- package/src/shared/json-new.http.ts +2 -2
- package/src/shared/json-protocol.http.ts +2 -6
- package/src/shared/json-version.http.ts +2 -6
- package/src/shared/page.ws.ts +4 -2
- package/src/shared/pdf.http.ts +3 -3
- package/src/shared/performance.http.ts +3 -3
- package/src/shared/scrape.http.ts +3 -3
- package/src/shared/screenshot.http.ts +3 -3
- package/src/shared/utils/function/client.ts +3 -1
- package/src/shim.ts +2 -2
- package/src/token.ts +7 -7
- package/src/types.ts +8 -8
- package/src/utils.ts +1 -1
- package/src/webhooks.ts +4 -4
- package/static/docs/swagger.json +1 -1
- package/static/docs/swagger.min.json +1 -1
- package/static/function/client.js +3 -1
- package/static/function/index.html +3 -1
|
@@ -59,16 +59,16 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
59
59
|
this.removeAllListeners();
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
public
|
|
63
|
-
return
|
|
62
|
+
public keepUntil() {
|
|
63
|
+
return 0;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
public getPageId
|
|
66
|
+
public getPageId(page: Page): string {
|
|
67
67
|
// @ts-ignore
|
|
68
68
|
return page.target()._targetId;
|
|
69
|
-
}
|
|
69
|
+
}
|
|
70
70
|
|
|
71
|
-
protected
|
|
71
|
+
protected async onTargetCreated(target: Target) {
|
|
72
72
|
if (target.type() === 'page') {
|
|
73
73
|
const page = await target.page().catch((e) => {
|
|
74
74
|
this.logger.error(`Error in ${this.constructor.name} new page ${e}`);
|
|
@@ -130,11 +130,13 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
130
130
|
this.emit('newPage', page);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
-
}
|
|
133
|
+
}
|
|
134
134
|
|
|
135
|
-
public isRunning
|
|
135
|
+
public isRunning(): boolean {
|
|
136
|
+
return this.running;
|
|
137
|
+
}
|
|
136
138
|
|
|
137
|
-
public
|
|
139
|
+
public async newPage(): Promise<Page> {
|
|
138
140
|
if (!this.browser) {
|
|
139
141
|
throw new ServerError(
|
|
140
142
|
`${this.constructor.name} hasn't been launched yet!`,
|
|
@@ -142,9 +144,9 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
return this.browser.newPage();
|
|
145
|
-
}
|
|
147
|
+
}
|
|
146
148
|
|
|
147
|
-
public
|
|
149
|
+
public async close(): Promise<void> {
|
|
148
150
|
if (this.browser) {
|
|
149
151
|
this.logger.info(
|
|
150
152
|
`Closing ${this.constructor.name} process and all listeners`,
|
|
@@ -157,13 +159,17 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
157
159
|
this.browser = null;
|
|
158
160
|
this.browserWSEndpoint = null;
|
|
159
161
|
}
|
|
160
|
-
}
|
|
162
|
+
}
|
|
161
163
|
|
|
162
|
-
public
|
|
164
|
+
public async pages(): Promise<Page[]> {
|
|
165
|
+
return this.browser?.pages() || [];
|
|
166
|
+
}
|
|
163
167
|
|
|
164
|
-
public process
|
|
168
|
+
public process() {
|
|
169
|
+
return this.browser?.process() || null;
|
|
170
|
+
}
|
|
165
171
|
|
|
166
|
-
public
|
|
172
|
+
public async launch(options: CDPLaunchOptions = {}): Promise<Browser> {
|
|
167
173
|
this.port = await getPort();
|
|
168
174
|
this.logger.info(`${this.constructor.name} got open port ${this.port}`);
|
|
169
175
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -205,7 +211,7 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
205
211
|
`Launching ${this.constructor.name} Handler`,
|
|
206
212
|
);
|
|
207
213
|
this.browser = (await launch(finalOptions)) as Browser;
|
|
208
|
-
this.browser.on('targetcreated', this.onTargetCreated);
|
|
214
|
+
this.browser.on('targetcreated', this.onTargetCreated.bind(this));
|
|
209
215
|
this.running = true;
|
|
210
216
|
this.browserWSEndpoint = this.browser.wsEndpoint();
|
|
211
217
|
this.logger.info(
|
|
@@ -213,11 +219,13 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
213
219
|
);
|
|
214
220
|
|
|
215
221
|
return this.browser;
|
|
216
|
-
}
|
|
222
|
+
}
|
|
217
223
|
|
|
218
|
-
public wsEndpoint
|
|
224
|
+
public wsEndpoint(): string | null {
|
|
225
|
+
return this.browserWSEndpoint;
|
|
226
|
+
}
|
|
219
227
|
|
|
220
|
-
public publicWSEndpoint
|
|
228
|
+
public publicWSEndpoint(token: string | null): string | null {
|
|
221
229
|
if (!this.browserWSEndpoint) {
|
|
222
230
|
return null;
|
|
223
231
|
}
|
|
@@ -232,14 +240,14 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
232
240
|
}
|
|
233
241
|
|
|
234
242
|
return externalURL.href;
|
|
235
|
-
}
|
|
243
|
+
}
|
|
236
244
|
|
|
237
|
-
public
|
|
245
|
+
public async proxyPageWebSocket(
|
|
238
246
|
req: Request,
|
|
239
247
|
socket: Duplex,
|
|
240
248
|
head: Buffer,
|
|
241
|
-
): Promise<void>
|
|
242
|
-
new Promise(async (resolve, reject) => {
|
|
249
|
+
): Promise<void> {
|
|
250
|
+
return new Promise(async (resolve, reject) => {
|
|
243
251
|
if (!this.browserWSEndpoint || !this.browser) {
|
|
244
252
|
throw new ServerError(
|
|
245
253
|
`No browserWSEndpoint found, did you launch first?`,
|
|
@@ -280,13 +288,14 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
280
288
|
},
|
|
281
289
|
);
|
|
282
290
|
});
|
|
291
|
+
}
|
|
283
292
|
|
|
284
|
-
public
|
|
293
|
+
public async proxyWebSocket(
|
|
285
294
|
req: Request,
|
|
286
295
|
socket: Duplex,
|
|
287
296
|
head: Buffer,
|
|
288
|
-
): Promise<void>
|
|
289
|
-
new Promise((resolve, reject) => {
|
|
297
|
+
): Promise<void> {
|
|
298
|
+
return new Promise((resolve, reject) => {
|
|
290
299
|
if (!this.browserWSEndpoint) {
|
|
291
300
|
throw new ServerError(
|
|
292
301
|
`No browserWSEndpoint found, did you launch first?`,
|
|
@@ -330,4 +339,5 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
330
339
|
},
|
|
331
340
|
);
|
|
332
341
|
});
|
|
342
|
+
}
|
|
333
343
|
}
|
|
@@ -43,13 +43,15 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
43
43
|
this.removeAllListeners();
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
public
|
|
47
|
-
return
|
|
46
|
+
public keepUntil() {
|
|
47
|
+
return 0;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
public isRunning
|
|
50
|
+
public isRunning(): boolean {
|
|
51
|
+
return this.running;
|
|
52
|
+
}
|
|
51
53
|
|
|
52
|
-
public
|
|
54
|
+
public async close(): Promise<void> {
|
|
53
55
|
if (this.browser) {
|
|
54
56
|
this.logger.info(
|
|
55
57
|
`Closing ${this.constructor.name} process and all listeners`,
|
|
@@ -61,23 +63,25 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
61
63
|
this.browser = null;
|
|
62
64
|
this.browserWSEndpoint = null;
|
|
63
65
|
}
|
|
64
|
-
}
|
|
66
|
+
}
|
|
65
67
|
|
|
66
|
-
public
|
|
68
|
+
public async pages(): Promise<[]> {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
67
71
|
|
|
68
|
-
public getPageId
|
|
72
|
+
public getPageId(): string {
|
|
69
73
|
throw new ServerError(
|
|
70
74
|
`#getPageId is not yet supported with ${this.constructor.name}.`,
|
|
71
75
|
);
|
|
72
|
-
}
|
|
76
|
+
}
|
|
73
77
|
|
|
74
|
-
public makeLiveURL
|
|
78
|
+
public makeLiveURL(): void {
|
|
75
79
|
throw new ServerError(
|
|
76
80
|
`Live URLs are not yet supported with ${this.constructor.name}. In the future this will be at "${this.config.getExternalAddress()}"`,
|
|
77
81
|
);
|
|
78
|
-
}
|
|
82
|
+
}
|
|
79
83
|
|
|
80
|
-
public
|
|
84
|
+
public async newPage(): Promise<Page> {
|
|
81
85
|
if (!this.browser || !this.browserWSEndpoint) {
|
|
82
86
|
throw new ServerError(
|
|
83
87
|
`${this.constructor.name} hasn't been launched yet!`,
|
|
@@ -85,12 +89,12 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
85
89
|
}
|
|
86
90
|
const browser = await playwright.chromium.connect(this.browserWSEndpoint);
|
|
87
91
|
return await browser.newPage();
|
|
88
|
-
}
|
|
92
|
+
}
|
|
89
93
|
|
|
90
|
-
public
|
|
94
|
+
public async launch(
|
|
91
95
|
options: BrowserServerOptions = {},
|
|
92
96
|
version?: string,
|
|
93
|
-
): Promise<playwright.BrowserServer>
|
|
97
|
+
): Promise<playwright.BrowserServer> {
|
|
94
98
|
this.logger.info(`Launching ${this.constructor.name} Handler`);
|
|
95
99
|
|
|
96
100
|
const opts = {
|
|
@@ -115,11 +119,13 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
115
119
|
this.browserWSEndpoint = browserWSEndpoint;
|
|
116
120
|
|
|
117
121
|
return this.browser;
|
|
118
|
-
}
|
|
122
|
+
}
|
|
119
123
|
|
|
120
|
-
public wsEndpoint
|
|
124
|
+
public wsEndpoint(): string | null {
|
|
125
|
+
return this.browserWSEndpoint;
|
|
126
|
+
}
|
|
121
127
|
|
|
122
|
-
public publicWSEndpoint
|
|
128
|
+
public publicWSEndpoint(token: string | null): string | null {
|
|
123
129
|
if (!this.browserWSEndpoint) {
|
|
124
130
|
return null;
|
|
125
131
|
}
|
|
@@ -134,18 +140,18 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
return externalURL.href;
|
|
137
|
-
}
|
|
143
|
+
}
|
|
138
144
|
|
|
139
|
-
public
|
|
145
|
+
public async proxyPageWebSocket() {
|
|
140
146
|
this.logger.warn(`${this.constructor.name} Not yet implemented`);
|
|
141
|
-
}
|
|
147
|
+
}
|
|
142
148
|
|
|
143
|
-
public
|
|
149
|
+
public async proxyWebSocket(
|
|
144
150
|
req: Request,
|
|
145
151
|
socket: Duplex,
|
|
146
152
|
head: Buffer,
|
|
147
|
-
): Promise<void>
|
|
148
|
-
new Promise((resolve, reject) => {
|
|
153
|
+
): Promise<void> {
|
|
154
|
+
return new Promise((resolve, reject) => {
|
|
149
155
|
if (!this.browserWSEndpoint) {
|
|
150
156
|
throw new ServerError(
|
|
151
157
|
`No browserWSEndpoint found, did you launch first?`,
|
|
@@ -179,4 +185,5 @@ export class ChromiumPlaywright extends EventEmitter {
|
|
|
179
185
|
},
|
|
180
186
|
);
|
|
181
187
|
});
|
|
188
|
+
}
|
|
182
189
|
}
|
|
@@ -42,13 +42,15 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
42
42
|
this.removeAllListeners();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
public
|
|
46
|
-
return
|
|
45
|
+
public keepUntil() {
|
|
46
|
+
return 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
public isRunning
|
|
49
|
+
public isRunning(): boolean {
|
|
50
|
+
return this.running;
|
|
51
|
+
}
|
|
50
52
|
|
|
51
|
-
public
|
|
53
|
+
public async close(): Promise<void> {
|
|
52
54
|
if (this.browser) {
|
|
53
55
|
this.logger.trace(
|
|
54
56
|
`Closing ${this.constructor.name} process and all listeners`,
|
|
@@ -60,33 +62,34 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
60
62
|
this.browser = null;
|
|
61
63
|
this.browserWSEndpoint = null;
|
|
62
64
|
}
|
|
63
|
-
}
|
|
65
|
+
}
|
|
64
66
|
|
|
65
|
-
public
|
|
67
|
+
public async pages(): Promise<[]> {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
66
70
|
|
|
67
|
-
public getPageId
|
|
71
|
+
public getPageId(): string {
|
|
68
72
|
throw new ServerError(
|
|
69
73
|
`#getPageId is not yet supported with ${this.constructor.name}.`,
|
|
70
74
|
);
|
|
71
|
-
}
|
|
75
|
+
}
|
|
72
76
|
|
|
73
|
-
public makeLiveURL
|
|
77
|
+
public makeLiveURL(): void {
|
|
74
78
|
throw new ServerError(
|
|
75
79
|
`Live URLs are not yet supported with ${this.constructor.name}.`,
|
|
76
80
|
);
|
|
77
|
-
}
|
|
81
|
+
}
|
|
78
82
|
|
|
79
|
-
public
|
|
83
|
+
public async newPage(): Promise<Page> {
|
|
80
84
|
throw new ServerError(
|
|
81
85
|
`Can't create new page with ${this.constructor.name}`,
|
|
82
86
|
);
|
|
83
|
-
}
|
|
87
|
+
}
|
|
84
88
|
|
|
85
|
-
public
|
|
89
|
+
public async launch(
|
|
86
90
|
options: BrowserServerOptions = {},
|
|
87
91
|
version?: string,
|
|
88
|
-
): Promise<playwright.BrowserServer>
|
|
89
|
-
|
|
92
|
+
): Promise<playwright.BrowserServer> {
|
|
90
93
|
this.logger.info(`Launching ${this.constructor.name} Handler`);
|
|
91
94
|
const opts = {
|
|
92
95
|
...options,
|
|
@@ -109,11 +112,13 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
109
112
|
this.running = true;
|
|
110
113
|
|
|
111
114
|
return this.browser;
|
|
112
|
-
}
|
|
115
|
+
}
|
|
113
116
|
|
|
114
|
-
public wsEndpoint
|
|
117
|
+
public wsEndpoint(): string | null {
|
|
118
|
+
return this.browserWSEndpoint;
|
|
119
|
+
}
|
|
115
120
|
|
|
116
|
-
public publicWSEndpoint
|
|
121
|
+
public publicWSEndpoint(token: string | null): string | null {
|
|
117
122
|
if (!this.browserWSEndpoint) {
|
|
118
123
|
return null;
|
|
119
124
|
}
|
|
@@ -128,18 +133,18 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
128
133
|
}
|
|
129
134
|
|
|
130
135
|
return externalURL.href;
|
|
131
|
-
}
|
|
136
|
+
}
|
|
132
137
|
|
|
133
|
-
public
|
|
138
|
+
public async proxyPageWebSocket() {
|
|
134
139
|
this.logger.warn(`Not yet implemented in ${this.constructor.name}`);
|
|
135
|
-
}
|
|
140
|
+
}
|
|
136
141
|
|
|
137
|
-
public
|
|
142
|
+
public async proxyWebSocket(
|
|
138
143
|
req: Request,
|
|
139
144
|
socket: Duplex,
|
|
140
145
|
head: Buffer,
|
|
141
|
-
): Promise<void>
|
|
142
|
-
new Promise((resolve, reject) => {
|
|
146
|
+
): Promise<void> {
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
143
148
|
if (!this.browserWSEndpoint) {
|
|
144
149
|
throw new ServerError(
|
|
145
150
|
`No browserWSEndpoint found, did you launch first?`,
|
|
@@ -173,4 +178,5 @@ export class FirefoxPlaywright extends EventEmitter {
|
|
|
173
178
|
},
|
|
174
179
|
);
|
|
175
180
|
});
|
|
181
|
+
}
|
|
176
182
|
}
|
package/src/browsers/index.ts
CHANGED
|
@@ -37,7 +37,7 @@ import path from 'path';
|
|
|
37
37
|
|
|
38
38
|
export class BrowserManager {
|
|
39
39
|
protected browsers: Map<BrowserInstance, BrowserlessSession> = new Map();
|
|
40
|
-
protected timers: Map<string,
|
|
40
|
+
protected timers: Map<string, NodeJS.Timeout> = new Map();
|
|
41
41
|
protected log = new Logger('browser-manager');
|
|
42
42
|
protected chromeBrowsers = [ChromiumCDP, ChromeCDP];
|
|
43
43
|
protected playwrightBrowserNames = [
|
|
@@ -52,10 +52,13 @@ export class BrowserManager {
|
|
|
52
52
|
protected hooks: Hooks,
|
|
53
53
|
) {}
|
|
54
54
|
|
|
55
|
-
protected browserIsChrome
|
|
56
|
-
this.chromeBrowsers.some(
|
|
55
|
+
protected browserIsChrome(b: BrowserInstance) {
|
|
56
|
+
return this.chromeBrowsers.some(
|
|
57
|
+
(chromeBrowser) => b instanceof chromeBrowser,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
57
60
|
|
|
58
|
-
protected
|
|
61
|
+
protected async removeUserDataDir(userDataDir: string | null) {
|
|
59
62
|
if (userDataDir && (await exists(userDataDir))) {
|
|
60
63
|
this.log.info(`Deleting data directory "${userDataDir}"`);
|
|
61
64
|
await deleteAsync(userDataDir, { force: true }).catch((err) => {
|
|
@@ -64,18 +67,18 @@ export class BrowserManager {
|
|
|
64
67
|
);
|
|
65
68
|
});
|
|
66
69
|
}
|
|
67
|
-
}
|
|
70
|
+
}
|
|
68
71
|
|
|
69
|
-
protected
|
|
70
|
-
await this.hooks.page({ meta: req.parsed, page });
|
|
71
|
-
}
|
|
72
|
+
protected async onNewPage(req: Request, page: Page) {
|
|
73
|
+
return await this.hooks.page({ meta: req.parsed, page });
|
|
74
|
+
}
|
|
72
75
|
|
|
73
76
|
/**
|
|
74
77
|
* Returns the /json/protocol API contents from Chromium or Chrome, whichever is installed,
|
|
75
78
|
* and modifies URLs to set them to the appropriate addresses configured.
|
|
76
79
|
* When both Chrome and Chromium are installed, defaults to Chromium.
|
|
77
80
|
*/
|
|
78
|
-
public
|
|
81
|
+
public async getProtocolJSON(logger: Logger): Promise<object> {
|
|
79
82
|
const Browser = (await availableBrowsers).find((InstalledBrowser) =>
|
|
80
83
|
this.chromeBrowsers.some(
|
|
81
84
|
(ChromeBrowser) => InstalledBrowser === ChromeBrowser,
|
|
@@ -104,14 +107,14 @@ export class BrowserManager {
|
|
|
104
107
|
browser.close();
|
|
105
108
|
|
|
106
109
|
return protocolJSON;
|
|
107
|
-
}
|
|
110
|
+
}
|
|
108
111
|
|
|
109
112
|
/**
|
|
110
113
|
* Returns the /json/version API from Chromium or Chrome, whichever is installed,
|
|
111
114
|
* and modifies URLs to set them to the appropriate addresses configured.
|
|
112
115
|
* When both Chrome and Chromium are installed, defaults to Chromium.
|
|
113
116
|
*/
|
|
114
|
-
public
|
|
117
|
+
public async getVersionJSON(logger: Logger): Promise<CDPJSONPayload> {
|
|
115
118
|
this.log.info(`Launching Chromium to generate /json/version results`);
|
|
116
119
|
const Browser = (await availableBrowsers).find((InstalledBrowser) =>
|
|
117
120
|
this.chromeBrowsers.some(
|
|
@@ -149,14 +152,14 @@ export class BrowserManager {
|
|
|
149
152
|
'Debugger-Version': debuggerVersion,
|
|
150
153
|
webSocketDebuggerUrl: this.config.getExternalWebSocketAddress(),
|
|
151
154
|
};
|
|
152
|
-
}
|
|
155
|
+
}
|
|
153
156
|
|
|
154
157
|
/**
|
|
155
158
|
* Returns a list of all Chrome-like browsers (both Chromium and Chrome) with
|
|
156
159
|
* their respective /json/list contents. URLs are modified so that subsequent
|
|
157
160
|
* calls can be forwarded to the appropriate destination
|
|
158
161
|
*/
|
|
159
|
-
public
|
|
162
|
+
public async getJSONList(): Promise<Array<CDPJSONPayload>> {
|
|
160
163
|
const externalAddress = this.config.getExternalWebSocketAddress();
|
|
161
164
|
const externalURL = new URL(externalAddress);
|
|
162
165
|
const sessions = Array.from(this.browsers);
|
|
@@ -214,19 +217,19 @@ export class BrowserManager {
|
|
|
214
217
|
return cdpResponse
|
|
215
218
|
.flat()
|
|
216
219
|
.filter((_) => _ !== null) as Array<CDPJSONPayload>;
|
|
217
|
-
}
|
|
220
|
+
}
|
|
218
221
|
|
|
219
|
-
protected
|
|
222
|
+
protected async generateSessionJson(
|
|
220
223
|
browser: BrowserInstance,
|
|
221
224
|
session: BrowserlessSession,
|
|
222
|
-
)
|
|
225
|
+
) {
|
|
223
226
|
const serverAddress = this.config.getExternalAddress();
|
|
224
227
|
|
|
225
228
|
const sessions = [
|
|
226
229
|
{
|
|
227
230
|
...session,
|
|
228
231
|
browser: browser.constructor.name,
|
|
229
|
-
browserId:
|
|
232
|
+
browserId: session.id,
|
|
230
233
|
initialConnectURL: new URL(session.initialConnectURL, serverAddress)
|
|
231
234
|
.href,
|
|
232
235
|
killURL: session.id
|
|
@@ -262,35 +265,63 @@ export class BrowserManager {
|
|
|
262
265
|
}
|
|
263
266
|
}
|
|
264
267
|
return sessions;
|
|
265
|
-
}
|
|
268
|
+
}
|
|
266
269
|
|
|
267
|
-
public
|
|
270
|
+
public async close(
|
|
268
271
|
browser: BrowserInstance,
|
|
269
272
|
session: BrowserlessSession,
|
|
270
|
-
): Promise<void>
|
|
273
|
+
): Promise<void> {
|
|
274
|
+
const now = Date.now();
|
|
275
|
+
const keepUntil = browser.keepUntil();
|
|
276
|
+
const connected = session.numbConnected;
|
|
277
|
+
const hasKeepUntil = keepUntil > now;
|
|
278
|
+
const keepOpen = connected > 0 || hasKeepUntil;
|
|
271
279
|
const cleanupACtions: Array<() => Promise<void>> = [];
|
|
272
|
-
this.
|
|
280
|
+
const priorTimer = this.timers.get(session.id);
|
|
273
281
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
282
|
+
if (priorTimer) {
|
|
283
|
+
this.log.info(`Deleting prior keep-until timer for "${session.id}"`);
|
|
284
|
+
global.clearTimeout(priorTimer);
|
|
277
285
|
}
|
|
278
286
|
|
|
279
|
-
this.log.info(
|
|
280
|
-
|
|
287
|
+
this.log.info(
|
|
288
|
+
`${session.numbConnected} Client(s) are currently connected, Keep-until: ${keepUntil}`,
|
|
289
|
+
);
|
|
281
290
|
|
|
282
|
-
if (
|
|
283
|
-
|
|
284
|
-
|
|
291
|
+
if (hasKeepUntil) {
|
|
292
|
+
const timeout = keepUntil - now;
|
|
293
|
+
this.log.trace(
|
|
294
|
+
`Setting timer ${timeout.toLocaleString()} for "${session.id}"`,
|
|
295
|
+
);
|
|
296
|
+
this.timers.set(
|
|
297
|
+
session.id,
|
|
298
|
+
global.setTimeout(() => {
|
|
299
|
+
const session = this.browsers.get(browser);
|
|
300
|
+
if (session) {
|
|
301
|
+
this.log.trace(`Timer hit for "${session.id}"`),
|
|
302
|
+
this.close(browser, session);
|
|
303
|
+
}
|
|
304
|
+
}, timeout),
|
|
285
305
|
);
|
|
286
|
-
this.browsers.delete(browser);
|
|
287
|
-
cleanupACtions.push(() => this.removeUserDataDir(session.userDataDir));
|
|
288
306
|
}
|
|
289
307
|
|
|
290
|
-
|
|
291
|
-
|
|
308
|
+
if (!keepOpen) {
|
|
309
|
+
this.log.info(`Closing browser session`);
|
|
310
|
+
cleanupACtions.push(() => browser.close());
|
|
292
311
|
|
|
293
|
-
|
|
312
|
+
if (session.isTempDataDir) {
|
|
313
|
+
this.log.info(
|
|
314
|
+
`Deleting "${session.userDataDir}" user-data-dir and session from memory`,
|
|
315
|
+
);
|
|
316
|
+
this.browsers.delete(browser);
|
|
317
|
+
cleanupACtions.push(() => this.removeUserDataDir(session.userDataDir));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
await Promise.all(cleanupACtions.map((a) => a()));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
public async getAllSessions(): Promise<BrowserlessSessionJSON[]> {
|
|
294
325
|
const sessions = Array.from(this.browsers);
|
|
295
326
|
|
|
296
327
|
const formattedSessions: BrowserlessSessionJSON[] = [];
|
|
@@ -299,9 +330,9 @@ export class BrowserManager {
|
|
|
299
330
|
formattedSessions.push(...formattedSession);
|
|
300
331
|
}
|
|
301
332
|
return formattedSessions;
|
|
302
|
-
}
|
|
333
|
+
}
|
|
303
334
|
|
|
304
|
-
public
|
|
335
|
+
public async complete(browser: BrowserInstance): Promise<void> {
|
|
305
336
|
const session = this.browsers.get(browser);
|
|
306
337
|
if (!session) {
|
|
307
338
|
this.log.info(
|
|
@@ -319,13 +350,13 @@ export class BrowserManager {
|
|
|
319
350
|
--session.numbConnected;
|
|
320
351
|
|
|
321
352
|
this.close(browser, session);
|
|
322
|
-
}
|
|
353
|
+
}
|
|
323
354
|
|
|
324
|
-
public
|
|
355
|
+
public async getBrowserForRequest(
|
|
325
356
|
req: Request,
|
|
326
357
|
router: BrowserHTTPRoute | BrowserWebsocketRoute,
|
|
327
358
|
logger: Logger,
|
|
328
|
-
): Promise<BrowserInstance>
|
|
359
|
+
): Promise<BrowserInstance> {
|
|
329
360
|
const { browser: Browser } = router;
|
|
330
361
|
const blockAds = parseBooleanParam(
|
|
331
362
|
req.parsed.searchParams,
|
|
@@ -459,8 +490,14 @@ export class BrowserManager {
|
|
|
459
490
|
userDataDir,
|
|
460
491
|
});
|
|
461
492
|
|
|
493
|
+
const match = (req.headers['user-agent'] || '').match(pwVersionRegex);
|
|
494
|
+
const pwVersion = match ? match[1] : 'default';
|
|
495
|
+
|
|
496
|
+
await browser.launch(launchOptions as object, pwVersion);
|
|
497
|
+
await this.hooks.browser({ browser, meta: req.parsed });
|
|
498
|
+
|
|
462
499
|
const session: BrowserlessSession = {
|
|
463
|
-
id:
|
|
500
|
+
id: browser.wsEndpoint()?.split('/').pop() as string,
|
|
464
501
|
initialConnectURL:
|
|
465
502
|
path.join(req.parsed.pathname, req.parsed.search) || '',
|
|
466
503
|
isTempDataDir: !manualUserDataDir,
|
|
@@ -475,21 +512,15 @@ export class BrowserManager {
|
|
|
475
512
|
|
|
476
513
|
this.browsers.set(browser, session);
|
|
477
514
|
|
|
478
|
-
const match = (req.headers['user-agent'] || '').match(pwVersionRegex);
|
|
479
|
-
const pwVersion = match ? match[1] : 'default';
|
|
480
|
-
|
|
481
|
-
await browser.launch(launchOptions as object, pwVersion);
|
|
482
|
-
await this.hooks.browser({ browser, meta: req.parsed });
|
|
483
|
-
|
|
484
515
|
browser.on('newPage', async (page) => {
|
|
485
516
|
await this.onNewPage(req, page);
|
|
486
517
|
(router.onNewPage || noop)(req.parsed || '', page);
|
|
487
518
|
});
|
|
488
519
|
|
|
489
520
|
return browser;
|
|
490
|
-
}
|
|
521
|
+
}
|
|
491
522
|
|
|
492
|
-
public
|
|
523
|
+
public async shutdown(): Promise<void> {
|
|
493
524
|
this.log.info(`Closing down browser instances`);
|
|
494
525
|
const sessions = Array.from(this.browsers);
|
|
495
526
|
await Promise.all(sessions.map(([b]) => b.close()));
|
|
@@ -500,10 +531,10 @@ export class BrowserManager {
|
|
|
500
531
|
this.timers = new Map();
|
|
501
532
|
await this.stop();
|
|
502
533
|
this.log.info(`Shutdown complete`);
|
|
503
|
-
}
|
|
534
|
+
}
|
|
504
535
|
|
|
505
536
|
/**
|
|
506
537
|
* Left blank for downstream SDK modules to optionally implement.
|
|
507
538
|
*/
|
|
508
|
-
public stop
|
|
539
|
+
public stop() {}
|
|
509
540
|
}
|