Skip to content

Commit

Permalink
Merge 35c7b06 into e4242d5
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jun 3, 2023
2 parents e4242d5 + 35c7b06 commit d2c65af
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 35 deletions.
1 change: 1 addition & 0 deletions packages/browserless/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@browserless/screenshot": "^9.10.2",
"debug-logfmt": "~1.0.4",
"kill-process-group": "~1.0.3",
"p-cancelable": "2.1.1",
"p-reflect": "~2.1.0",
"p-retry": "~4.6.1",
"p-timeout": "~4.1.0",
Expand Down
73 changes: 39 additions & 34 deletions packages/browserless/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const createScreenshot = require('@browserless/screenshot')
const debug = require('debug-logfmt')('browserless')
const createGoto = require('@browserless/goto')
const createPdf = require('@browserless/pdf')
const PCancelable = require('p-cancelable')
const { withLock } = require('superlock')
const pReflect = require('p-reflect')
const pTimeout = require('p-timeout')
Expand Down Expand Up @@ -107,46 +108,50 @@ module.exports = ({ timeout: globalTimeout = 30000, ...launchOpts } = {}) => {
}
}

const withPage = (fn, { timeout: evaluateTimeout } = {}) => async (...args) => {
let isRejected = false

async function run () {
let page

try {
page = await createPage(args)
setTimeout(() => closePage(page), timeout)
const value = await fn(page)(...args)
await closePage(page)
return value
} catch (error) {
await closePage(page)
if (!isRejected) throw ensureError(error)
const withPage = (fn, { timeout: evaluateTimeout } = {}) =>
PCancelable.fn(async (...args) => {
const onCancel = args.pop()
let isRejected = false

async function run () {
let page

try {
page = await createPage(args)
const close = () => closePage(page)
onCancel(close)
setTimeout(close, timeout).unref()
const value = await fn(page)(...args)
await closePage(page)
return value
} catch (error) {
await closePage(page)
if (!isRejected) throw ensureError(error)
}
}
}

const task = () =>
pRetry(run, {
retries: retry,
onFailedAttempt: async error => {
debug('onFailedAttempt', { name: error.name, code: error.code, isRejected })
if (error.name === 'AbortError') throw error
if (isRejected) throw new AbortError()
if (error.code === 'EBRWSRCONTEXTCONNRESET') {
_contextPromise = createBrowserContext(contextOpts)
const task = () =>
pRetry(run, {
retries: retry,
onFailedAttempt: async error => {
debug('onFailedAttempt', { name: error.name, code: error.code, isRejected })
if (error.name === 'AbortError') throw error
if (isRejected) throw new AbortError()
if (error.code === 'EBRWSRCONTEXTCONNRESET') {
_contextPromise = createBrowserContext(contextOpts)
}
const { message, attemptNumber, retriesLeft } = error
debug('retry', { attemptNumber, retriesLeft, message })
}
const { message, attemptNumber, retriesLeft } = error
debug('retry', { attemptNumber, retriesLeft, message })
}
})
})

const timeout = evaluateTimeout || contextTimeout || globalTimeout
const timeout = evaluateTimeout || contextTimeout || globalTimeout

return pTimeout(task(), timeout, () => {
isRejected = true
throw browserTimeout({ timeout })
return pTimeout(task(), timeout, () => {
isRejected = true
throw browserTimeout({ timeout })
})
})
}

const evaluate = (fn, gotoOpts) =>
withPage(
Expand Down
21 changes: 21 additions & 0 deletions packages/browserless/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,24 @@ test('ensure to destroy browser contexts', async t => {

t.is(browser.browserContexts().length, 1)
})
;[
{ method: 'evaluate', isDecorator: true },
{ method: 'withPage', isDecorator: true },
{ method: 'html' },
{ method: 'pdf' },
{ method: 'screenshot' },
{ method: 'text' }
].forEach(({ method, isDecorator = false }) => {
test(`.${method} is cancelable`, async t => {
const browserless = await getBrowserContext(t)

const fn = isDecorator
? browserless[method](() => {})
: () => browserless[method]('about:blank')

const promise = fn()
promise.catch(() => {})
t.is(!!promise.cancel, true)
promise.cancel()
})
})
4 changes: 3 additions & 1 deletion packages/cli/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const path = require('path')
const mri = require('mri')
const fs = require('fs')

const noop = () => {}

const commands = fs.readdirSync(path.resolve(__dirname, 'commands'))

const { _, ...flags } = mri(process.argv.slice(2), {
Expand All @@ -32,7 +34,7 @@ const cli = {

const { verbose, headless } = cli.flags

const spinner = verbose ? require('./spinner') : { start: () => {}, stop: () => {} }
const spinner = verbose ? require('./spinner') : { start: noop, stop: noop, clear: noop }

process.on('SIGINT', () => {
spinner.stop({ force: true })
Expand Down

0 comments on commit d2c65af

Please sign in to comment.