@browserless/goto 9.2.0 → 9.2.20

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@browserless/goto",
3
3
  "description": "Go to a page aborting unnecessary requests",
4
4
  "homepage": "https://browserless.js.org/#/?id=gotopage-options",
5
- "version": "9.2.0",
5
+ "version": "9.2.20",
6
6
  "main": "src/index.js",
7
7
  "author": {
8
8
  "email": "hello@microlink.io",
@@ -30,7 +30,7 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "@browserless/devices": "^9.1.6",
33
- "@cliqz/adblocker-puppeteer": "~1.22.2",
33
+ "@cliqz/adblocker-puppeteer": "~1.23.0",
34
34
  "debug-logfmt": "~1.0.4",
35
35
  "got": "~11.8.2",
36
36
  "is-url-http": "~2.2.4",
@@ -39,7 +39,7 @@
39
39
  "pretty-ms": "~7.0.1",
40
40
  "shallow-equal": "~1.2.1",
41
41
  "time-span": "~4.0.0",
42
- "top-user-agents": "~1.0.29",
42
+ "top-user-agents": "~1.0.38",
43
43
  "tough-cookie": "~4.0.0",
44
44
  "unique-random-array": "~2.0.0"
45
45
  },
@@ -68,5 +68,5 @@
68
68
  "timeout": "2m",
69
69
  "verbose": true
70
70
  },
71
- "gitHead": "e57a3f4412a8b30dce40f7a479d44205d1222604"
71
+ "gitHead": "58b992afb012bb270f3dfe27c2d57a1f91f8051f"
72
72
  }
package/src/engine.bin CHANGED
Binary file
package/src/index.js CHANGED
@@ -29,15 +29,14 @@ const isEmpty = val => val == null || !(Object.keys(val) || val).length
29
29
 
30
30
  const castArray = value => [].concat(value).filter(Boolean)
31
31
 
32
- const getInjectKey = (ext, value) =>
33
- isUrl(value) ? 'url' : value.endsWith(`.${ext}`) ? 'path' : 'content'
34
-
35
- const injectCSS = (page, css) =>
36
- pReflect(
37
- page.addStyleTag({
38
- content: css
39
- })
40
- )
32
+ const run = async ({ fn, timeout, debug: props }) => {
33
+ const debugProps = { duration: timeSpan() }
34
+ const result = await pReflect(pTimeout(fn, timeout))
35
+ debugProps.duration = prettyMs(debugProps.duration())
36
+ if (result.isRejected) debugProps.error = result.reason.message || result.reason
37
+ debug(props, debugProps)
38
+ return result
39
+ }
41
40
 
42
41
  const parseCookies = (url, str) =>
43
42
  str.split(';').reduce((acc, cookieStr) => {
@@ -66,28 +65,19 @@ const getMediaFeatures = ({ animations, colorScheme }) => {
66
65
  return prefers
67
66
  }
68
67
 
69
- const injectScripts = (page, values, attributes) =>
70
- Promise.all(
71
- castArray(values).map(value =>
72
- pReflect(
73
- page.addScriptTag({
74
- [getInjectKey('js', value)]: value,
75
- ...attributes
76
- })
77
- )
78
- )
79
- )
68
+ const injectScript = (page, value, attributes) =>
69
+ page.addScriptTag({
70
+ [getInjectKey('js', value)]: value,
71
+ ...attributes
72
+ })
80
73
 
81
- const injectStyles = (page, styles) =>
82
- Promise.all(
83
- castArray(styles).map(style =>
84
- pReflect(
85
- page.addStyleTag({
86
- [getInjectKey('css', style)]: style
87
- })
88
- )
89
- )
90
- )
74
+ const injectStyle = (page, style) =>
75
+ page.addStyleTag({
76
+ [getInjectKey('css', style)]: style
77
+ })
78
+
79
+ const getInjectKey = (ext, value) =>
80
+ isUrl(value) ? 'url' : value.endsWith(`.${ext}`) ? 'path' : 'content'
91
81
 
92
82
  const disableAnimations = `
93
83
  *,
@@ -101,29 +91,22 @@ const disableAnimations = `
101
91
  }
102
92
  `.trim()
103
93
 
104
- const run = async ({ fn, debug: props }) => {
105
- const debugProps = { duration: timeSpan() }
106
- const result = await pReflect(fn)
107
- debugProps.duration = prettyMs(debugProps.duration())
108
- if (result.isRejected) debugProps.error = result.reason.message || result.reason
109
- debug(props, debugProps)
110
- return result
111
- }
112
-
113
94
  // related https://github.com/puppeteer/puppeteer/issues/1353
114
95
  const createWaitUntilAuto = defaultOpts => (page, opts) => {
115
96
  const { timeout } = { ...defaultOpts, ...opts }
116
97
 
117
- return run({
118
- fn: pTimeout(
119
- Promise.all([
120
- page.waitForNavigation({ waitUntil: 'networkidle2' }),
121
- page.evaluate(() => window.history.pushState(null, null, null))
122
- ]),
123
- timeout * (1 / 8)
124
- ),
125
- debug: { isWaitUntilAuto: true }
126
- })
98
+ return Promise.all(
99
+ [
100
+ {
101
+ fn: () => page.waitForNavigation({ waitUntil: 'networkidle2' }),
102
+ debug: 'waitUntilAuto:waitForNavigation'
103
+ },
104
+ {
105
+ fn: () => page.evaluate(() => window.history.pushState(null, null, null)),
106
+ debug: 'waitUntilAuto:pushState'
107
+ }
108
+ ].map(({ fn, ...opts }) => run({ fn: fn(), timeout, ...opts }))
109
+ )
127
110
  }
128
111
 
129
112
  module.exports = ({
@@ -133,14 +116,12 @@ module.exports = ({
133
116
  ...deviceOpts
134
117
  }) => {
135
118
  const baseTimeout = globalTimeout * (1 / 2)
119
+ const actionTimeout = baseTimeout * (1 / 8)
120
+
136
121
  const getDevice = createDevices(deviceOpts)
137
122
  const { viewport: defaultViewport } = getDevice.findDevice(defaultDevice)
138
123
 
139
- const applyEvasions = castArray(evasions)
140
- .filter(Boolean)
141
- .reduce((acc, key) => [...acc, EVASIONS[key]], [])
142
-
143
- const _waitUntilAuto = createWaitUntilAuto({ timeout: baseTimeout })
124
+ const _waitUntilAuto = createWaitUntilAuto({ timeout: actionTimeout })
144
125
 
145
126
  const goto = async (
146
127
  page,
@@ -178,13 +159,20 @@ module.exports = ({
178
159
  const prePromises = []
179
160
 
180
161
  if (adblock) {
181
- prePromises.push(engine.enableBlockingInPage(page))
162
+ prePromises.push(
163
+ run({
164
+ fn: engine.enableBlockingInPage(page),
165
+ timeout: actionTimeout,
166
+ debug: 'adblock'
167
+ })
168
+ )
182
169
  }
183
170
 
184
171
  if (javascript === false) {
185
172
  prePromises.push(
186
173
  run({
187
174
  fn: page.setJavaScriptEnabled(false),
175
+ timeout: actionTimeout,
188
176
  debug: { javascript }
189
177
  })
190
178
  )
@@ -200,6 +188,7 @@ module.exports = ({
200
188
  prePromises.push(
201
189
  run({
202
190
  fn: page.setViewport(device.viewport),
191
+ timeout: actionTimeout,
203
192
  debug: 'viewport'
204
193
  })
205
194
  )
@@ -213,6 +202,7 @@ module.exports = ({
213
202
  prePromises.push(
214
203
  run({
215
204
  fn: page.setCookie(...cookies),
205
+ timeout: actionTimeout,
216
206
  debug: ['cookies', ...cookies.map(({ name }) => name)]
217
207
  })
218
208
  )
@@ -222,6 +212,7 @@ module.exports = ({
222
212
  prePromises.push(
223
213
  run({
224
214
  fn: page.setUserAgent(headers['user-agent']),
215
+ timeout: actionTimeout,
225
216
  debug: { 'user-agent': headers['user-agent'] }
226
217
  })
227
218
  )
@@ -230,6 +221,7 @@ module.exports = ({
230
221
  prePromises.push(
231
222
  run({
232
223
  fn: page.setExtraHTTPHeaders(headers),
224
+ timeout: actionTimeout,
233
225
  debug: { headers: headersKeys }
234
226
  })
235
227
  )
@@ -239,6 +231,7 @@ module.exports = ({
239
231
  prePromises.push(
240
232
  run({
241
233
  fn: page.emulateMediaType(mediaType),
234
+ timeout: actionTimeout,
242
235
  debug: { mediaType }
243
236
  })
244
237
  )
@@ -248,6 +241,7 @@ module.exports = ({
248
241
  prePromises.push(
249
242
  run({
250
243
  fn: page.emulateTimezone(timezone),
244
+ timeout: actionTimeout,
251
245
  debug: { timezone }
252
246
  })
253
247
  )
@@ -259,14 +253,26 @@ module.exports = ({
259
253
  prePromises.push(
260
254
  run({
261
255
  fn: page.emulateMediaFeatures(mediaFeatures),
262
- debug: { mediaFeatures: mediaFeatures.length }
256
+ timeout: actionTimeout,
257
+ debug: { mediaFeatures: mediaFeatures.map(({ name }) => name) }
263
258
  })
264
259
  )
265
260
  }
266
261
 
267
- await Promise.all(prePromises.concat(applyEvasions.map(fn => fn(page))))
262
+ const applyEvasions = castArray(evasions)
263
+ .filter(Boolean)
264
+ .map(key =>
265
+ run({
266
+ fn: EVASIONS[key](page),
267
+ timeout: actionTimeout,
268
+ debug: key
269
+ })
270
+ )
271
+
272
+ await Promise.all(prePromises.concat(applyEvasions))
268
273
 
269
274
  if (abortTypes.length > 0) {
275
+ await page.setRequestInterception(true)
270
276
  page.on('request', req => {
271
277
  const resourceType = req.resourceType()
272
278
  if (!abortTypes.includes(resourceType)) return req.continue()
@@ -276,7 +282,8 @@ module.exports = ({
276
282
  }
277
283
 
278
284
  const { value } = await run({
279
- fn: pTimeout(html ? page.setContent(html, args) : page.goto(url, args), timeout),
285
+ fn: html ? page.setContent(html, args) : page.goto(url, args),
286
+ timeout,
280
287
  debug: html ? 'html' : 'url'
281
288
  })
282
289
 
@@ -286,40 +293,71 @@ module.exports = ({
286
293
  waitForFunction,
287
294
  waitForTimeout
288
295
  })) {
289
- if (value) await run({ fn: page[key](value), debug: { [key]: value } })
296
+ if (value) {
297
+ await run({ fn: page[key](value), timeout: actionTimeout, debug: { [key]: value } })
298
+ }
290
299
  }
291
300
 
292
301
  const postPromises = []
293
302
 
294
303
  if (animations === false) {
295
- postPromises.push(injectCSS(page, disableAnimations))
304
+ postPromises.push(
305
+ run({
306
+ fn: injectStyle(page, disableAnimations),
307
+ timeout: actionTimeout,
308
+ debug: 'disableAnimations'
309
+ })
310
+ )
311
+ }
312
+
313
+ if (hide) {
314
+ postPromises.push(
315
+ run({
316
+ fn: injectStyle(page, `${castArray(hide).join(', ')} { visibility: hidden !important; }`),
317
+ timeout: actionTimeout,
318
+ debug: 'hide'
319
+ })
320
+ )
296
321
  }
297
322
 
298
- const hideOrRemove = [
299
- hide && injectCSS(page, `${castArray(hide).join(', ')} { visibility: hidden !important; }`),
300
- remove && injectCSS(page, `${castArray(remove).join(', ')} { display: none !important; }`)
301
- ].filter(Boolean)
323
+ if (remove) {
324
+ postPromises.push(
325
+ run({
326
+ fn: injectStyle(page, `${castArray(remove).join(', ')} { display: none !important; }`),
327
+ timeout: actionTimeout,
328
+ debug: 'remove'
329
+ })
330
+ )
331
+ }
302
332
 
303
- if (hideOrRemove.length > 0) {
333
+ if (modules) {
304
334
  postPromises.push(
305
335
  run({
306
- fn: Promise.all(hideOrRemove),
307
- debug: { hideOrRemove: hideOrRemove.length }
336
+ fn: Promise.all(
337
+ castArray(modules).map(value => injectScript(page, value, { type: 'modules' }))
338
+ ),
339
+ timeout: actionTimeout,
340
+ debug: 'modules'
308
341
  })
309
342
  )
310
343
  }
311
344
 
312
- const injections = [
313
- modules && injectScripts(page, modules, { type: 'modules' }),
314
- scripts && injectScripts(page, scripts),
315
- styles && injectStyles(page, styles)
316
- ].filter(Boolean)
345
+ if (scripts) {
346
+ postPromises.push(
347
+ run({
348
+ fn: Promise.all(castArray(scripts).map(value => injectScript(page, value))),
349
+ timeout: actionTimeout,
350
+ debug: 'scripts'
351
+ })
352
+ )
353
+ }
317
354
 
318
- if (injections.length > 0) {
355
+ if (styles) {
319
356
  postPromises.push(
320
357
  run({
321
- fn: Promise.all(injections),
322
- debug: { injections: injections.length }
358
+ fn: Promise.all(castArray(styles).map(style => injectStyle(page, style))),
359
+ timeout: actionTimeout,
360
+ debug: 'styles'
323
361
  })
324
362
  )
325
363
  }
@@ -328,18 +366,21 @@ module.exports = ({
328
366
 
329
367
  if (click) {
330
368
  for (const selector of castArray(click)) {
331
- await run({ fn: page.click(selector), debug: { click: selector } })
369
+ await run({ fn: page.click(selector), timeout: actionTimeout, debug: { click: selector } })
332
370
  }
333
371
  }
334
372
 
335
373
  if (scroll) {
336
374
  await run({
337
375
  fn: page.$eval(scroll, el => el.scrollIntoView()),
376
+ timeout: actionTimeout,
338
377
  debug: { scroll }
339
378
  })
340
379
  }
341
380
 
342
- if (isWaitUntilAuto) await waitUntilAuto(page, { response: value, timeout })
381
+ if (isWaitUntilAuto) {
382
+ await waitUntilAuto(page, { response: value, timeout: actionTimeout * 2 })
383
+ }
343
384
 
344
385
  return { response: value, device }
345
386
  }
@@ -351,11 +392,13 @@ module.exports = ({
351
392
  goto.defaultViewport = defaultViewport
352
393
  goto.waitUntilAuto = _waitUntilAuto
353
394
  goto.timeout = baseTimeout
395
+ goto.actionTimeout = actionTimeout
396
+ goto.run = run
354
397
 
355
398
  return goto
356
399
  }
357
400
 
358
401
  module.exports.parseCookies = parseCookies
359
- module.exports.injectScripts = injectScripts
360
- module.exports.injectStyles = injectStyles
402
+ module.exports.injectScript = injectScript
403
+ module.exports.injectStyle = injectStyle
361
404
  module.exports.evasions = ALL_EVASIONS_KEYS