codeceptjs 4.0.0-beta.1 → 4.0.0-beta.10.esm-aria
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/README.md +133 -120
- package/bin/codecept.js +107 -96
- package/bin/test-server.js +64 -0
- package/docs/webapi/clearCookie.mustache +1 -1
- package/docs/webapi/click.mustache +5 -1
- package/lib/actor.js +71 -103
- package/lib/ai.js +159 -188
- package/lib/assert/empty.js +22 -24
- package/lib/assert/equal.js +30 -37
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +43 -48
- package/lib/assert/throws.js +11 -11
- package/lib/assert/truth.js +22 -22
- package/lib/assert.js +20 -18
- package/lib/codecept.js +238 -162
- package/lib/colorUtils.js +50 -52
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +56 -51
- package/lib/command/definitions.js +96 -109
- package/lib/command/dryRun.js +77 -79
- package/lib/command/generate.js +234 -194
- package/lib/command/gherkin/init.js +42 -33
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +20 -17
- package/lib/command/info.js +74 -38
- package/lib/command/init.js +300 -290
- package/lib/command/interactive.js +41 -32
- package/lib/command/list.js +28 -27
- package/lib/command/run-multiple/chunk.js +51 -48
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +5 -1
- package/lib/command/run-multiple.js +97 -97
- package/lib/command/run-rerun.js +19 -25
- package/lib/command/run-workers.js +68 -92
- package/lib/command/run.js +39 -27
- package/lib/command/utils.js +80 -64
- package/lib/command/workers/runTests.js +388 -226
- package/lib/config.js +124 -50
- package/lib/container.js +751 -260
- package/lib/data/context.js +60 -61
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +32 -32
- package/lib/data/table.js +22 -22
- package/lib/effects.js +307 -0
- package/lib/element/WebElement.js +327 -0
- package/lib/els.js +160 -0
- package/lib/event.js +173 -163
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -85
- package/lib/helper/AI.js +131 -41
- package/lib/helper/ApiDataFactory.js +107 -75
- package/lib/helper/Appium.js +542 -404
- package/lib/helper/FileSystem.js +100 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +52 -52
- package/lib/helper/JSONResponse.js +126 -88
- package/lib/helper/Mochawesome.js +54 -29
- package/lib/helper/Playwright.js +2547 -1316
- package/lib/helper/Puppeteer.js +1578 -1181
- package/lib/helper/REST.js +209 -68
- package/lib/helper/WebDriver.js +1482 -1342
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightReactVueLocator.js +17 -8
- package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +27 -28
- package/lib/helper/network/actions.js +36 -42
- package/lib/helper/network/utils.js +78 -84
- package/lib/helper/scripts/blurElement.js +5 -5
- package/lib/helper/scripts/focusElement.js +5 -5
- package/lib/helper/scripts/highlightElement.js +8 -8
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -3
- package/lib/history.js +23 -19
- package/lib/hooks.js +8 -8
- package/lib/html.js +94 -104
- package/lib/index.js +38 -27
- package/lib/listener/config.js +30 -23
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/enhancedGlobalRetry.js +110 -0
- package/lib/listener/exit.js +16 -18
- package/lib/listener/globalRetry.js +70 -0
- package/lib/listener/globalTimeout.js +181 -0
- package/lib/listener/helpers.js +76 -51
- package/lib/listener/mocha.js +10 -11
- package/lib/listener/result.js +11 -0
- package/lib/listener/retryEnhancer.js +85 -0
- package/lib/listener/steps.js +71 -59
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +214 -197
- package/lib/mocha/asyncWrapper.js +274 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +163 -0
- package/lib/mocha/featureConfig.js +89 -0
- package/lib/mocha/gherkin.js +231 -0
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +184 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +242 -0
- package/lib/output.js +141 -71
- package/lib/parser.js +47 -44
- package/lib/pause.js +173 -145
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +178 -79
- package/lib/plugin/autoDelay.js +36 -40
- package/lib/plugin/coverage.js +131 -78
- package/lib/plugin/customLocator.js +22 -21
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/enhancedRetryFailedStep.js +99 -0
- package/lib/plugin/heal.js +101 -110
- package/lib/plugin/htmlReporter.js +3648 -0
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +12 -11
- package/lib/plugin/retryFailedStep.js +82 -47
- package/lib/plugin/screenshotOnFail.js +111 -92
- package/lib/plugin/stepByStepReport.js +159 -101
- package/lib/plugin/stepTimeout.js +20 -25
- package/lib/plugin/subtitles.js +38 -38
- package/lib/recorder.js +193 -130
- package/lib/rerun.js +94 -49
- package/lib/result.js +238 -0
- package/lib/retryCoordinator.js +207 -0
- package/lib/secret.js +20 -18
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -329
- package/lib/steps.js +54 -0
- package/lib/store.js +38 -7
- package/lib/template/heal.js +3 -12
- package/lib/template/prompts/generatePageObject.js +31 -0
- package/lib/template/prompts/healStep.js +13 -0
- package/lib/template/prompts/writeStep.js +9 -0
- package/lib/test-server.js +334 -0
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +34 -21
- package/lib/utils/mask_data.js +47 -0
- package/lib/utils.js +411 -228
- package/lib/workerStorage.js +37 -34
- package/lib/workers.js +532 -296
- package/package.json +115 -95
- package/translations/de-DE.js +5 -3
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +22 -12
- package/translations/it-IT.js +4 -3
- package/translations/ja-JP.js +4 -3
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +4 -3
- package/translations/pt-BR.js +4 -3
- package/translations/ru-RU.js +4 -3
- package/translations/utils.js +10 -0
- package/translations/zh-CN.js +4 -3
- package/translations/zh-TW.js +4 -3
- package/typings/index.d.ts +546 -185
- package/typings/promiseBasedTypes.d.ts +150 -879
- package/typings/types.d.ts +547 -996
- package/lib/cli.js +0 -249
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
- package/lib/helper/ExpectHelper.js +0 -399
- package/lib/helper/MockServer.js +0 -223
- package/lib/helper/Nightmare.js +0 -1411
- package/lib/helper/Protractor.js +0 -1835
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1410
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -63
- package/lib/interfaces/bdd.js +0 -98
- package/lib/interfaces/featureConfig.js +0 -69
- package/lib/interfaces/gherkin.js +0 -195
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/retry.js +0 -68
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -110
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -121
- package/lib/plugin/selenoid.js +0 -371
- package/lib/plugin/standardActingHelpers.js +0 -9
- package/lib/plugin/tryTo.js +0 -105
- package/lib/plugin/wdio.js +0 -246
- package/lib/scenario.js +0 -222
- package/lib/ui.js +0 -238
- package/lib/within.js +0 -70
package/lib/recorder.js
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const MAX_TASKS = 100
|
|
9
|
-
|
|
10
|
-
let promise
|
|
11
|
-
let running = false
|
|
12
|
-
let errFn
|
|
13
|
-
let queueId = 0
|
|
14
|
-
let sessionId = null
|
|
15
|
-
let
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
let
|
|
1
|
+
import debugModule from 'debug'
|
|
2
|
+
const debug = debugModule('codeceptjs:recorder')
|
|
3
|
+
import promiseRetry from 'promise-retry'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import { printObjectProperties } from './utils.js'
|
|
6
|
+
import output from './output.js'
|
|
7
|
+
import { TimeoutError } from './timeout.js'
|
|
8
|
+
const MAX_TASKS = 100
|
|
9
|
+
|
|
10
|
+
let promise
|
|
11
|
+
let running = false
|
|
12
|
+
let errFn
|
|
13
|
+
let queueId = 0
|
|
14
|
+
let sessionId = null
|
|
15
|
+
let sessionStack = [] // Stack to support nested sessions
|
|
16
|
+
let asyncErr = null
|
|
17
|
+
let ignoredErrs = []
|
|
18
|
+
|
|
19
|
+
let tasks = []
|
|
20
|
+
let oldPromises = []
|
|
20
21
|
|
|
21
22
|
const defaultRetryOptions = {
|
|
22
23
|
retries: 0,
|
|
23
24
|
minTimeout: 150,
|
|
24
25
|
maxTimeout: 10000,
|
|
25
|
-
}
|
|
26
|
+
}
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Singleton object to record all test steps as promises and run them in chain.
|
|
@@ -30,7 +31,6 @@ const defaultRetryOptions = {
|
|
|
30
31
|
* @interface
|
|
31
32
|
*/
|
|
32
33
|
export default {
|
|
33
|
-
|
|
34
34
|
/**
|
|
35
35
|
* @type {Array<Object<string, *>>}
|
|
36
36
|
* @inner
|
|
@@ -44,12 +44,11 @@ export default {
|
|
|
44
44
|
* @inner
|
|
45
45
|
*/
|
|
46
46
|
start() {
|
|
47
|
-
debug('Starting recording promises')
|
|
48
|
-
running = true
|
|
49
|
-
asyncErr = null
|
|
50
|
-
errFn = null
|
|
51
|
-
|
|
52
|
-
this.reset();
|
|
47
|
+
debug('Starting recording promises')
|
|
48
|
+
running = true
|
|
49
|
+
asyncErr = null
|
|
50
|
+
errFn = null
|
|
51
|
+
this.reset()
|
|
53
52
|
},
|
|
54
53
|
|
|
55
54
|
/**
|
|
@@ -57,7 +56,7 @@ export default {
|
|
|
57
56
|
* @inner
|
|
58
57
|
*/
|
|
59
58
|
isRunning() {
|
|
60
|
-
return running
|
|
59
|
+
return running
|
|
61
60
|
},
|
|
62
61
|
|
|
63
62
|
/**
|
|
@@ -66,7 +65,7 @@ export default {
|
|
|
66
65
|
*/
|
|
67
66
|
startUnlessRunning() {
|
|
68
67
|
if (!this.isRunning()) {
|
|
69
|
-
this.start()
|
|
68
|
+
this.start()
|
|
70
69
|
}
|
|
71
70
|
},
|
|
72
71
|
|
|
@@ -78,7 +77,7 @@ export default {
|
|
|
78
77
|
* @inner
|
|
79
78
|
*/
|
|
80
79
|
errHandler(fn) {
|
|
81
|
-
errFn = fn
|
|
80
|
+
errFn = fn
|
|
82
81
|
},
|
|
83
82
|
|
|
84
83
|
/**
|
|
@@ -89,16 +88,17 @@ export default {
|
|
|
89
88
|
* @inner
|
|
90
89
|
*/
|
|
91
90
|
reset() {
|
|
92
|
-
if (promise && running) this.catch()
|
|
93
|
-
queueId
|
|
94
|
-
sessionId = null
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
if (promise && running) this.catch()
|
|
92
|
+
queueId++
|
|
93
|
+
sessionId = null
|
|
94
|
+
sessionStack = [] // Clear the session stack
|
|
95
|
+
asyncErr = null
|
|
96
|
+
output.log(`${currentQueue()} Starting recording promises`)
|
|
97
|
+
promise = Promise.resolve()
|
|
98
|
+
oldPromises = []
|
|
99
|
+
tasks = []
|
|
100
|
+
ignoredErrs = []
|
|
101
|
+
this.session.running = false
|
|
102
102
|
// reset this retries makes the retryFailedStep plugin won't work if there is Before/BeforeSuit block due to retries is undefined on Scenario
|
|
103
103
|
// this.retries = [];
|
|
104
104
|
},
|
|
@@ -125,12 +125,21 @@ export default {
|
|
|
125
125
|
* @inner
|
|
126
126
|
*/
|
|
127
127
|
start(name) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
128
|
+
if (sessionId) {
|
|
129
|
+
debug(`${currentQueue()}Session already started as ${sessionId}, nesting session ${name}`)
|
|
130
|
+
// Push current session to stack instead of restoring it
|
|
131
|
+
sessionStack.push({
|
|
132
|
+
id: sessionId,
|
|
133
|
+
promise: promise,
|
|
134
|
+
running: this.running,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
debug(`${currentQueue()}Starting <${name}> session`)
|
|
138
|
+
tasks.push('--->')
|
|
139
|
+
oldPromises.push(promise)
|
|
140
|
+
this.running = true
|
|
141
|
+
sessionId = name
|
|
142
|
+
promise = Promise.resolve()
|
|
134
143
|
},
|
|
135
144
|
|
|
136
145
|
/**
|
|
@@ -138,12 +147,21 @@ export default {
|
|
|
138
147
|
* @inner
|
|
139
148
|
*/
|
|
140
149
|
restore(name) {
|
|
141
|
-
tasks.push('<---')
|
|
142
|
-
debug(`${currentQueue()}Finalize <${name}> session`)
|
|
143
|
-
this.running = false
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
150
|
+
tasks.push('<---')
|
|
151
|
+
debug(`${currentQueue()}Finalize <${name}> session`)
|
|
152
|
+
this.running = false
|
|
153
|
+
this.catch(errFn)
|
|
154
|
+
promise = promise.then(() => oldPromises.pop())
|
|
155
|
+
|
|
156
|
+
// Restore parent session from stack if available
|
|
157
|
+
if (sessionStack.length > 0) {
|
|
158
|
+
const parentSession = sessionStack.pop()
|
|
159
|
+
sessionId = parentSession.id
|
|
160
|
+
this.running = parentSession.running
|
|
161
|
+
debug(`${currentQueue()}Restored parent session <${sessionId}>`)
|
|
162
|
+
} else {
|
|
163
|
+
sessionId = null
|
|
164
|
+
}
|
|
147
165
|
},
|
|
148
166
|
|
|
149
167
|
/**
|
|
@@ -151,9 +169,8 @@ export default {
|
|
|
151
169
|
* @inner
|
|
152
170
|
*/
|
|
153
171
|
catch(fn) {
|
|
154
|
-
promise = promise.catch(fn)
|
|
172
|
+
promise = promise.catch(fn)
|
|
155
173
|
},
|
|
156
|
-
|
|
157
174
|
},
|
|
158
175
|
|
|
159
176
|
/**
|
|
@@ -165,50 +182,56 @@ export default {
|
|
|
165
182
|
* @param {boolean} [force=false]
|
|
166
183
|
* @param {boolean} [retry]
|
|
167
184
|
* undefined: `add(fn)` -> `false` and `add('step',fn)` -> `true`
|
|
168
|
-
* true: it will
|
|
185
|
+
* true: it will retries if `retryOpts` set.
|
|
169
186
|
* false: ignore `retryOpts` and won't retry.
|
|
170
187
|
* @param {number} [timeout]
|
|
171
|
-
* @return {Promise
|
|
188
|
+
* @return {Promise<*>}
|
|
172
189
|
* @inner
|
|
173
190
|
*/
|
|
174
191
|
add(taskName, fn = undefined, force = false, retry = undefined, timeout = undefined) {
|
|
175
192
|
if (typeof taskName === 'function') {
|
|
176
|
-
fn = taskName
|
|
177
|
-
taskName = fn.toString()
|
|
178
|
-
if (retry === undefined) retry = false
|
|
193
|
+
fn = taskName
|
|
194
|
+
taskName = fn.toString()
|
|
195
|
+
if (retry === undefined) retry = false
|
|
179
196
|
}
|
|
180
|
-
if (retry === undefined) retry = true
|
|
197
|
+
if (retry === undefined) retry = true
|
|
181
198
|
if (!running && !force) {
|
|
182
|
-
return
|
|
199
|
+
return Promise.resolve()
|
|
183
200
|
}
|
|
184
|
-
tasks.push(taskName)
|
|
185
|
-
debug(chalk.gray(`${currentQueue()} Queued | ${taskName}`))
|
|
201
|
+
tasks.push(taskName)
|
|
202
|
+
debug(chalk.gray(`${currentQueue()} Queued | ${taskName}`))
|
|
186
203
|
|
|
187
|
-
return promise = Promise.resolve(promise).then(
|
|
204
|
+
return (promise = Promise.resolve(promise).then(res => {
|
|
188
205
|
// prefer options for non-conditional retries
|
|
189
|
-
const retryOpts = this.retries
|
|
206
|
+
const retryOpts = this.retries
|
|
207
|
+
.sort((r1, r2) => r1.when && !r2.when)
|
|
208
|
+
.slice(-1)
|
|
209
|
+
.pop()
|
|
190
210
|
// no retries or unnamed tasks
|
|
211
|
+
debug(`${currentQueue()} Running | ${taskName} | Timeout: ${timeout || 'None'}`)
|
|
212
|
+
if (retryOpts) debug(`${currentQueue()} Retry opts`, JSON.stringify(retryOpts))
|
|
213
|
+
|
|
191
214
|
if (!retryOpts || !taskName || !retry) {
|
|
192
|
-
const [promise, timer] = getTimeoutPromise(timeout, taskName)
|
|
193
|
-
return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer))
|
|
215
|
+
const [promise, timer] = getTimeoutPromise(timeout, taskName)
|
|
216
|
+
return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer))
|
|
194
217
|
}
|
|
195
218
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const retryRules = this.retries.slice().reverse();
|
|
219
|
+
const retryRules = this.retries.slice().reverse()
|
|
199
220
|
return promiseRetry(Object.assign(defaultRetryOptions, retryOpts), (retry, number) => {
|
|
200
|
-
if (number > 1) output.
|
|
201
|
-
const [promise, timer] = getTimeoutPromise(timeout, taskName)
|
|
202
|
-
return Promise.race([promise, Promise.resolve(res).then(fn)])
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
221
|
+
if (number > 1) output.log(`${currentQueue()}Retrying... Attempt #${number}`)
|
|
222
|
+
const [promise, timer] = getTimeoutPromise(timeout, taskName)
|
|
223
|
+
return Promise.race([promise, Promise.resolve(res).then(fn)])
|
|
224
|
+
.finally(() => clearTimeout(timer))
|
|
225
|
+
.catch(err => {
|
|
226
|
+
if (ignoredErrs.includes(err)) return
|
|
227
|
+
for (const retryObj of retryRules) {
|
|
228
|
+
if (!retryObj.when) return retry(err)
|
|
229
|
+
if (retryObj.when && retryObj.when(err)) return retry(err)
|
|
230
|
+
}
|
|
231
|
+
throw err
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
}))
|
|
212
235
|
},
|
|
213
236
|
|
|
214
237
|
/**
|
|
@@ -217,15 +240,17 @@ export default {
|
|
|
217
240
|
* @inner
|
|
218
241
|
*/
|
|
219
242
|
retry(opts) {
|
|
220
|
-
if (!promise) return
|
|
243
|
+
if (!promise) return
|
|
221
244
|
|
|
222
245
|
if (opts === null) {
|
|
223
|
-
opts = {}
|
|
246
|
+
opts = {}
|
|
224
247
|
}
|
|
225
248
|
if (Number.isInteger(opts)) {
|
|
226
|
-
opts = { retries: opts }
|
|
249
|
+
opts = { retries: opts }
|
|
227
250
|
}
|
|
228
|
-
|
|
251
|
+
// Push retry options immediately so first step can see them
|
|
252
|
+
this.retries.push(opts)
|
|
253
|
+
return Promise.resolve()
|
|
229
254
|
},
|
|
230
255
|
|
|
231
256
|
/**
|
|
@@ -234,20 +259,26 @@ export default {
|
|
|
234
259
|
* @inner
|
|
235
260
|
*/
|
|
236
261
|
catch(customErrFn) {
|
|
237
|
-
const fnDescription = customErrFn
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
262
|
+
const fnDescription = customErrFn
|
|
263
|
+
?.toString()
|
|
264
|
+
?.replace(/\s{2,}/g, ' ')
|
|
265
|
+
.replace(/\n/g, ' ')
|
|
266
|
+
?.slice(0, 50)
|
|
267
|
+
debug(chalk.gray(`${currentQueue()} Queued | catch with error handler ${fnDescription || ''}`))
|
|
268
|
+
if (!promise) promise = Promise.resolve()
|
|
269
|
+
return (promise = promise.catch(err => {
|
|
270
|
+
output.log(`${currentQueue()}Error | ${err} ${fnDescription}...`)
|
|
271
|
+
if (!(err instanceof Error)) {
|
|
272
|
+
// strange things may happen
|
|
273
|
+
err = new Error(`[Wrapped Error] ${printObjectProperties(err)}`) // we should be prepared for them
|
|
243
274
|
}
|
|
244
275
|
if (customErrFn) {
|
|
245
|
-
customErrFn(err)
|
|
276
|
+
customErrFn(err)
|
|
246
277
|
} else if (errFn) {
|
|
247
|
-
errFn(err)
|
|
278
|
+
errFn(err)
|
|
248
279
|
}
|
|
249
|
-
this.stop()
|
|
250
|
-
})
|
|
280
|
+
this.stop()
|
|
281
|
+
}))
|
|
251
282
|
},
|
|
252
283
|
|
|
253
284
|
/**
|
|
@@ -256,17 +287,37 @@ export default {
|
|
|
256
287
|
* @inner
|
|
257
288
|
*/
|
|
258
289
|
catchWithoutStop(customErrFn) {
|
|
259
|
-
const fnDescription = customErrFn
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
290
|
+
const fnDescription = customErrFn
|
|
291
|
+
?.toString()
|
|
292
|
+
?.replace(/\s{2,}/g, ' ')
|
|
293
|
+
.replace(/\n/g, ' ')
|
|
294
|
+
?.slice(0, 50)
|
|
295
|
+
if (!promise) promise = Promise.resolve()
|
|
296
|
+
return (promise = promise.catch(err => {
|
|
297
|
+
if (ignoredErrs.includes(err)) return // already caught
|
|
298
|
+
|
|
299
|
+
// Handle terminal errors - don't continue, re-throw immediately
|
|
300
|
+
if (err && (err.isTerminal || (err.message && (err.message.includes('ERR_ABORTED') || err.message.includes('frame was detached') || err.message.includes('Target page, context or browser has been closed'))))) {
|
|
301
|
+
output.log(`${currentQueue()} Terminal Error | ${err} | ${fnDescription || ''}...`)
|
|
302
|
+
throw err // Re-throw terminal errors immediately
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
output.log(`${currentQueue()} Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`)
|
|
306
|
+
if (!(err instanceof Error)) {
|
|
307
|
+
// strange things may happen
|
|
308
|
+
err = new Error(`[Wrapped Error] ${JSON.stringify(err)}`) // we should be prepared for them
|
|
265
309
|
}
|
|
266
310
|
if (customErrFn) {
|
|
267
|
-
|
|
311
|
+
try {
|
|
312
|
+
const result = customErrFn(err)
|
|
313
|
+
// If customErrFn returns a value (not throwing), treat it as handled
|
|
314
|
+
return result
|
|
315
|
+
} catch (thrownErr) {
|
|
316
|
+
// If customErrFn throws an error, propagate it up
|
|
317
|
+
throw thrownErr
|
|
318
|
+
}
|
|
268
319
|
}
|
|
269
|
-
})
|
|
320
|
+
}))
|
|
270
321
|
},
|
|
271
322
|
|
|
272
323
|
/**
|
|
@@ -278,15 +329,15 @@ export default {
|
|
|
278
329
|
*/
|
|
279
330
|
|
|
280
331
|
throw(err) {
|
|
281
|
-
if (ignoredErrs.includes(err)) return promise
|
|
332
|
+
if (ignoredErrs.includes(err)) return promise // already caught
|
|
282
333
|
return this.add(`throw error: ${err.message}`, () => {
|
|
283
|
-
if (ignoredErrs.includes(err)) return
|
|
284
|
-
throw err
|
|
285
|
-
})
|
|
334
|
+
if (ignoredErrs.includes(err)) return // already caught
|
|
335
|
+
throw err
|
|
336
|
+
})
|
|
286
337
|
},
|
|
287
338
|
|
|
288
339
|
ignoreErr(err) {
|
|
289
|
-
ignoredErrs.push(err)
|
|
340
|
+
ignoredErrs.push(err)
|
|
290
341
|
},
|
|
291
342
|
|
|
292
343
|
/**
|
|
@@ -295,7 +346,7 @@ export default {
|
|
|
295
346
|
*/
|
|
296
347
|
saveFirstAsyncError(err) {
|
|
297
348
|
if (asyncErr === null) {
|
|
298
|
-
asyncErr = err
|
|
349
|
+
asyncErr = err
|
|
299
350
|
}
|
|
300
351
|
},
|
|
301
352
|
|
|
@@ -304,7 +355,7 @@ export default {
|
|
|
304
355
|
* @inner
|
|
305
356
|
*/
|
|
306
357
|
getAsyncErr() {
|
|
307
|
-
return asyncErr
|
|
358
|
+
return asyncErr
|
|
308
359
|
},
|
|
309
360
|
|
|
310
361
|
/**
|
|
@@ -312,7 +363,7 @@ export default {
|
|
|
312
363
|
* @inner
|
|
313
364
|
*/
|
|
314
365
|
cleanAsyncErr() {
|
|
315
|
-
asyncErr = null
|
|
366
|
+
asyncErr = null
|
|
316
367
|
},
|
|
317
368
|
|
|
318
369
|
/**
|
|
@@ -321,11 +372,9 @@ export default {
|
|
|
321
372
|
* @inner
|
|
322
373
|
*/
|
|
323
374
|
stop() {
|
|
324
|
-
|
|
325
|
-
output.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
running = false;
|
|
375
|
+
debug(this.toString())
|
|
376
|
+
output.log(`${currentQueue()} Stopping recording promises`)
|
|
377
|
+
running = false
|
|
329
378
|
},
|
|
330
379
|
|
|
331
380
|
/**
|
|
@@ -336,7 +385,7 @@ export default {
|
|
|
336
385
|
* @inner
|
|
337
386
|
*/
|
|
338
387
|
promise() {
|
|
339
|
-
return promise
|
|
388
|
+
return promise
|
|
340
389
|
},
|
|
341
390
|
|
|
342
391
|
/**
|
|
@@ -345,7 +394,7 @@ export default {
|
|
|
345
394
|
* @inner
|
|
346
395
|
*/
|
|
347
396
|
scheduled() {
|
|
348
|
-
return tasks.slice(-MAX_TASKS).join('\n')
|
|
397
|
+
return tasks.slice(-MAX_TASKS).join('\n')
|
|
349
398
|
},
|
|
350
399
|
|
|
351
400
|
/**
|
|
@@ -354,7 +403,7 @@ export default {
|
|
|
354
403
|
* @inner
|
|
355
404
|
*/
|
|
356
405
|
getQueueId() {
|
|
357
|
-
return queueId
|
|
406
|
+
return queueId
|
|
358
407
|
},
|
|
359
408
|
|
|
360
409
|
/**
|
|
@@ -363,20 +412,34 @@ export default {
|
|
|
363
412
|
* @inner
|
|
364
413
|
*/
|
|
365
414
|
toString() {
|
|
366
|
-
return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}
|
|
415
|
+
return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}`
|
|
416
|
+
},
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Get current session ID
|
|
420
|
+
* @return {string|null}
|
|
421
|
+
* @inner
|
|
422
|
+
*/
|
|
423
|
+
getCurrentSessionId() {
|
|
424
|
+
return sessionId
|
|
367
425
|
},
|
|
368
|
-
}
|
|
426
|
+
}
|
|
369
427
|
|
|
370
428
|
function getTimeoutPromise(timeoutMs, taskName) {
|
|
371
|
-
let timer
|
|
372
|
-
if (timeoutMs) debug(`Timing out in ${timeoutMs}ms`)
|
|
373
|
-
return [
|
|
374
|
-
|
|
375
|
-
|
|
429
|
+
let timer
|
|
430
|
+
if (timeoutMs) debug(`Timing out in ${timeoutMs}ms`)
|
|
431
|
+
return [
|
|
432
|
+
new Promise((done, reject) => {
|
|
433
|
+
timer = setTimeout(() => {
|
|
434
|
+
reject(new TimeoutError(`Action ${taskName} was interrupted on timeout ${timeoutMs}ms`))
|
|
435
|
+
}, timeoutMs || 2e9)
|
|
436
|
+
}),
|
|
437
|
+
timer,
|
|
438
|
+
]
|
|
376
439
|
}
|
|
377
440
|
|
|
378
441
|
function currentQueue() {
|
|
379
|
-
let session = ''
|
|
380
|
-
if (sessionId) session = `<${sessionId}>
|
|
381
|
-
return `[${queueId}] ${session}
|
|
442
|
+
let session = ''
|
|
443
|
+
if (sessionId) session = `<${sessionId}> `
|
|
444
|
+
return `[${queueId}] ${session}`
|
|
382
445
|
}
|