Skip to content

Commit 4bd5405

Browse files
committed
feat: ensure close page
Closes #28
1 parent b286a59 commit 4bd5405

File tree

5 files changed

+69
-72
lines changed

5 files changed

+69
-72
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ These devices are used for emulation purposes.
260260

261261
#### .getDevice(deviceName)
262262

263-
Get an specific device descriptor settings by descriptor name.
263+
Get a specific device descriptor settings by descriptor name.
264264

265265
```js
266266
const browserless = require('browserless')
@@ -299,7 +299,7 @@ const browserless = require('browserless')
299299

300300
### .evaluate(page, response)
301301

302-
It exposes an interface for creating your own evaluate function.
302+
It exposes an interface for creating your own evaluate function, passing you the `page` and `response`.
303303

304304
```js
305305
const browserless = require('browserless')()
@@ -323,7 +323,9 @@ const getUrlInfo = browserless.evaluate((page, response) => ({
323323
})()
324324
```
325325

326-
Internally the method performs a [.goto](#gotopage-options) operation and it will pass you the `page` and `reponse`.
326+
Note you don't need to close the page; It will be done under the hood.
327+
328+
Internally the method performs a [.goto](#gotopage-options).
327329

328330
### .goto(page, options)
329331

packages/browserless/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"debug": "~4.1.0",
3333
"extract-domain": "~2.0.4",
3434
"is-tracking-domain": "~1.1.6",
35+
"p-timeout": "~2.0.1",
3536
"require-one-of": "~1.0.2"
3637
},
3738
"devDependencies": {

packages/browserless/src/index.js

Lines changed: 43 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const extractDomain = require('extract-domain')
44
const requireOneOf = require('require-one-of')
55
const debug = require('debug')('browserless')
6+
const pTimeout = require('p-timeout')
67

78
const { getDevice } = require('./devices')
89
const isTracker = require('./is-tracker')
@@ -18,11 +19,7 @@ const isExternalUrl = (domainOne, domainTwo) => domainOne !== domainTwo
1819
const isEmpty = val => val == null || !(Object.keys(val) || val).length
1920

2021
module.exports = ({
21-
puppeteer = requireOneOf([
22-
'puppeteer',
23-
'puppeteer-core',
24-
'puppeteer-firefox'
25-
]),
22+
puppeteer = requireOneOf(['puppeteer', 'puppeteer-core', 'puppeteer-firefox']),
2623
incognito = false,
2724
timeout = 30000,
2825
...launchOpts
@@ -49,14 +46,28 @@ module.exports = ({
4946

5047
const newPage = () =>
5148
Promise.resolve(browser).then(async browser => {
52-
const context = incognito
53-
? await browser.createIncognitoBrowserContext()
54-
: browser
49+
const context = incognito ? await browser.createIncognitoBrowserContext() : browser
5550
const page = await context.newPage()
5651
page.setDefaultNavigationTimeout(timeout)
5752
return page
5853
})
5954

55+
const wrapError = fn => async (...args) => {
56+
const page = await newPage()
57+
let error
58+
let res
59+
60+
try {
61+
res = await pTimeout(fn(page)(...args), timeout)
62+
} catch (err) {
63+
error = err
64+
}
65+
66+
await page.close()
67+
if (error) throw error
68+
return res
69+
}
70+
6071
const goto = async (
6172
page,
6273
{
@@ -96,8 +107,7 @@ module.exports = ({
96107
return req.continue()
97108
})
98109

99-
const { userAgent: deviceUserAgent, viewport: deviceViewport } =
100-
getDevice(device) || {}
110+
const { userAgent: deviceUserAgent, viewport: deviceViewport } = getDevice(device) || {}
101111

102112
const userAgent = deviceUserAgent || fallbackUserAgent
103113
if (userAgent) await page.setUserAgent(userAgent)
@@ -109,50 +119,32 @@ module.exports = ({
109119
return response
110120
}
111121

112-
const evaluate = fn => async (url, opts = {}) => {
113-
const {
114-
abortTrackers = true,
115-
abortTypes = [
116-
'image',
117-
'imageset',
118-
'media',
119-
'stylesheet',
120-
'font',
121-
'object',
122-
'sub_frame'
123-
],
124-
...args
125-
} = opts
126-
127-
const page = await newPage()
128-
const response = await goto(page, {
129-
url,
130-
abortTrackers,
131-
abortTypes,
132-
...args
122+
const evaluate = fn =>
123+
wrapError(page => async (url, opts = {}) => {
124+
const {
125+
abortTrackers = true,
126+
abortTypes = ['image', 'imageset', 'media', 'stylesheet', 'font', 'object', 'sub_frame'],
127+
...args
128+
} = opts
129+
130+
const response = await goto(page, {
131+
url,
132+
abortTrackers,
133+
abortTypes,
134+
...args
135+
})
136+
137+
return fn(page, response)
133138
})
134-
const content = await fn(page, response)
135-
await page.close()
136-
return content
137-
}
138139

139-
const screenshot = async (url, opts = {}) => {
140-
const {
141-
device = 'macbook pro 13',
142-
tmpOpts,
143-
type = 'png',
144-
viewport,
145-
...args
146-
} = opts
140+
const screenshot = wrapError(page => async (url, opts = {}) => {
141+
const { device = 'macbook pro 13', tmpOpts, type = 'png', viewport, ...args } = opts
147142

148-
const page = await newPage()
149143
await goto(page, { url, device, ...args })
150-
const file = await page.screenshot({ type, ...args })
151-
await page.close()
152-
return file
153-
}
144+
return page.screenshot({ type, ...args })
145+
})
154146

155-
const pdf = async (url, opts = {}) => {
147+
const pdf = wrapError(page => async (url, opts = {}) => {
156148
const {
157149
format = 'A4',
158150
margin = {
@@ -169,19 +161,16 @@ module.exports = ({
169161
...args
170162
} = opts
171163

172-
const page = await newPage()
173164
await page.emulateMedia(media)
174165
await goto(page, { url, ...args })
175-
const file = await page.pdf({
166+
return page.pdf({
176167
margin,
177168
format,
178169
printBackground,
179170
scale,
180171
...args
181172
})
182-
await page.close()
183-
return file
184-
}
173+
})
185174

186175
return {
187176
browser,

packages/browserless/test/spec.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ module.exports = createBrowserless => {
2828
path: filepath
2929
})
3030

31-
t.true(
32-
await looksSame(filepath, path.resolve(__dirname, 'fixtures/example.png'))
33-
)
31+
t.true(await looksSame(filepath, path.resolve(__dirname, 'fixtures/example.png')))
3432
})
3533
;(isCI ? test.skip : test)('.screenshot (jpeg)', async t => {
3634
const browserless = createBrowserless()
@@ -40,12 +38,7 @@ module.exports = createBrowserless => {
4038
path: filepath
4139
})
4240

43-
t.true(
44-
await looksSame(
45-
filepath,
46-
path.resolve(__dirname, 'fixtures/example.jpeg')
47-
)
48-
)
41+
t.true(await looksSame(filepath, path.resolve(__dirname, 'fixtures/example.jpeg')))
4942
})
5043
;(isCI ? test.skip : test)('devices', async t => {
5144
const browserless = createBrowserless()
@@ -55,17 +48,28 @@ module.exports = createBrowserless => {
5548
path: filepath
5649
})
5750

58-
t.true(
59-
await looksSame(
60-
filepath,
61-
path.resolve(__dirname, 'fixtures/example-iphone.png')
62-
)
63-
)
51+
t.true(await looksSame(filepath, path.resolve(__dirname, 'fixtures/example-iphone.png')))
6452
})
6553
;(isCI ? test.skip : test)('.pdf', async t => {
6654
const browserless = createBrowserless()
6755
const buffer = await browserless.pdf('http://example.com')
6856
const data = await pdf(buffer)
6957
t.snapshot(data.text.trim())
7058
})
59+
;['pdf', 'screenshot', 'html', 'text'].forEach(method => {
60+
test(`.${method} wrap errors`, async t => {
61+
const browserless = createBrowserless()
62+
const timeout = 500
63+
64+
const error = await t.throwsAsync(browserless[method]('https://example.com', { timeout }))
65+
66+
t.is(error.name, 'TimeoutError')
67+
t.is(error.message, `Navigation Timeout Exceeded: ${timeout}ms exceeded`)
68+
69+
const browser = await browserless.browser
70+
const pages = await browser.pages()
71+
72+
t.is(pages.length, 1) // about:page is always open
73+
})
74+
})
7175
}

packages/examples/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "",
44
"devDependencies": {
55
"browserless": "latest",
6+
"puppeteer": "latest",
67
"lodash": "latest",
78
"p-event": "latest",
89
"term-img": "latest"

0 commit comments

Comments
 (0)