browserless 10.7.7 → 10.7.9-beta.0
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 +2 -2
- package/src/index.js +49 -40
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "browserless",
|
|
3
3
|
"description": "The headless Chrome/Chromium performance driver for Node.js",
|
|
4
4
|
"homepage": "https://browserless.js.org",
|
|
5
|
-
"version": "10.7.
|
|
5
|
+
"version": "10.7.9-beta.0",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"author": {
|
|
8
8
|
"email": "hello@microlink.io",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"timeout": "2m",
|
|
65
65
|
"workerThreads": false
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "112999584d7b7137fb0eab858d31396eaf3c52e8"
|
|
68
68
|
}
|
package/src/index.js
CHANGED
|
@@ -79,12 +79,13 @@ module.exports = ({ timeout: globalTimeout = 30000, ...launchOpts } = {}) => {
|
|
|
79
79
|
const getBrowserContext = () => _contextPromise
|
|
80
80
|
|
|
81
81
|
const createPage = async name => {
|
|
82
|
+
const duration = debug.duration('createPage')
|
|
82
83
|
const [browserProcess, browserContext] = await Promise.all([
|
|
83
84
|
getBrowser(),
|
|
84
85
|
getBrowserContext()
|
|
85
86
|
])
|
|
86
87
|
const page = await browserContext.newPage()
|
|
87
|
-
|
|
88
|
+
duration({
|
|
88
89
|
name,
|
|
89
90
|
id: page._client().id(),
|
|
90
91
|
contextId: browserContext.id,
|
|
@@ -95,12 +96,13 @@ module.exports = ({ timeout: globalTimeout = 30000, ...launchOpts } = {}) => {
|
|
|
95
96
|
|
|
96
97
|
const closePage = async (page, name) => {
|
|
97
98
|
if (page && !page.isClosed()) {
|
|
99
|
+
const duration = debug.duration('closePage')
|
|
98
100
|
const [browserProcess, browserContext] = await Promise.all([
|
|
99
101
|
getBrowser(),
|
|
100
102
|
getBrowserContext(),
|
|
101
103
|
pReflect(page.close())
|
|
102
104
|
])
|
|
103
|
-
|
|
105
|
+
duration({
|
|
104
106
|
name,
|
|
105
107
|
id: page._client().id(),
|
|
106
108
|
contextId: browserContext.id,
|
|
@@ -109,48 +111,55 @@ module.exports = ({ timeout: globalTimeout = 30000, ...launchOpts } = {}) => {
|
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
114
|
+
/**
|
|
115
|
+
* FIXME: Apparently there is a kind of race condition if you have more than one context and you close the page,
|
|
116
|
+
* the browser context is closed but the browser process is broken
|
|
117
|
+
* Related: https://github.com/search?q=repo%3Apuppeteer%2Fpuppeteer%20waitForScreenshotOperations&type=code
|
|
118
|
+
*/
|
|
119
|
+
const withPage = (fn, { closePage: withClosePage = true, timeout: evaluateTimeout } = {}) => {
|
|
120
|
+
const name = fn.name || 'anonymous'
|
|
121
|
+
|
|
122
|
+
return async (...args) => {
|
|
123
|
+
let isRejected = false
|
|
124
|
+
|
|
125
|
+
async function run () {
|
|
126
|
+
let page
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
page = await createPage(name)
|
|
130
|
+
setTimeout(() => closePage(page, `${name}:timeout`), timeout).unref()
|
|
131
|
+
const value = await fn(page, goto)(...args)
|
|
132
|
+
if (withClosePage) await closePage(page, `${name}:success`)
|
|
133
|
+
return value
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (withClosePage) await closePage(page, `${name}:error`)
|
|
136
|
+
if (!isRejected) throw ensureError(error)
|
|
130
137
|
}
|
|
138
|
+
}
|
|
131
139
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
const { message, attemptNumber, retriesLeft } = error
|
|
143
|
-
debug('retry', { attemptNumber, retriesLeft, message })
|
|
140
|
+
const task = () =>
|
|
141
|
+
pRetry(run, {
|
|
142
|
+
retries: retry,
|
|
143
|
+
onFailedAttempt: async error => {
|
|
144
|
+
debug('onFailedAttempt', { name: error.name, code: error.code, isRejected })
|
|
145
|
+
if (error.name === 'AbortError') throw error
|
|
146
|
+
if (isRejected || isDestroyedForced) throw new AbortError()
|
|
147
|
+
if (error.code === 'EBRWSRCONTEXTCONNRESET') {
|
|
148
|
+
_contextPromise = createBrowserContext(contextOpts)
|
|
144
149
|
}
|
|
145
|
-
|
|
150
|
+
const { message, attemptNumber, retriesLeft } = error
|
|
151
|
+
debug('retry', { attemptNumber, retriesLeft, message })
|
|
152
|
+
}
|
|
153
|
+
})
|
|
146
154
|
|
|
147
|
-
|
|
155
|
+
const timeout = evaluateTimeout || contextTimeout || globalTimeout
|
|
148
156
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
return pTimeout(task(), timeout, () => {
|
|
158
|
+
isRejected = true
|
|
159
|
+
throw browserTimeout({ timeout })
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
}
|
|
154
163
|
|
|
155
164
|
const evaluate = (fn, gotoOpts) =>
|
|
156
165
|
withPage(
|
|
@@ -188,7 +197,7 @@ module.exports = ({ timeout: globalTimeout = 30000, ...launchOpts } = {}) => {
|
|
|
188
197
|
html: evaluate(page => page.content()),
|
|
189
198
|
page: createPage,
|
|
190
199
|
pdf: withPage(createPdf({ goto })),
|
|
191
|
-
screenshot: withPage(createScreenshot({ goto })),
|
|
200
|
+
screenshot: withPage(createScreenshot({ goto }), { closePage: false }),
|
|
192
201
|
text: evaluate(page => page.evaluate(() => document.body.innerText)),
|
|
193
202
|
getDevice: goto.getDevice,
|
|
194
203
|
destroyContext,
|