codeceptjs 4.0.0-beta.5 → 4.0.0-beta.6.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.
Files changed (179) hide show
  1. package/README.md +0 -45
  2. package/bin/codecept.js +46 -57
  3. package/lib/actor.js +15 -11
  4. package/lib/ai.js +6 -5
  5. package/lib/assert/empty.js +9 -8
  6. package/lib/assert/equal.js +15 -17
  7. package/lib/assert/error.js +2 -2
  8. package/lib/assert/include.js +9 -11
  9. package/lib/assert/throws.js +1 -1
  10. package/lib/assert/truth.js +8 -5
  11. package/lib/assert.js +18 -18
  12. package/lib/codecept.js +66 -107
  13. package/lib/colorUtils.js +48 -50
  14. package/lib/command/check.js +32 -27
  15. package/lib/command/configMigrate.js +11 -10
  16. package/lib/command/definitions.js +16 -10
  17. package/lib/command/dryRun.js +16 -16
  18. package/lib/command/generate.js +29 -26
  19. package/lib/command/gherkin/init.js +36 -38
  20. package/lib/command/gherkin/snippets.js +14 -14
  21. package/lib/command/gherkin/steps.js +21 -18
  22. package/lib/command/info.js +8 -8
  23. package/lib/command/init.js +34 -31
  24. package/lib/command/interactive.js +11 -10
  25. package/lib/command/list.js +10 -9
  26. package/lib/command/run-multiple/chunk.js +5 -5
  27. package/lib/command/run-multiple/collection.js +5 -5
  28. package/lib/command/run-multiple/run.js +3 -3
  29. package/lib/command/run-multiple.js +16 -13
  30. package/lib/command/run-rerun.js +6 -7
  31. package/lib/command/run-workers.js +10 -24
  32. package/lib/command/run.js +8 -8
  33. package/lib/command/utils.js +20 -18
  34. package/lib/command/workers/runTests.js +117 -269
  35. package/lib/config.js +111 -49
  36. package/lib/container.js +299 -102
  37. package/lib/data/context.js +6 -5
  38. package/lib/data/dataScenarioConfig.js +1 -1
  39. package/lib/data/dataTableArgument.js +1 -1
  40. package/lib/data/table.js +1 -1
  41. package/lib/effects.js +94 -10
  42. package/lib/els.js +11 -9
  43. package/lib/event.js +11 -10
  44. package/lib/globals.js +141 -0
  45. package/lib/heal.js +12 -12
  46. package/lib/helper/AI.js +1 -1
  47. package/lib/helper/ApiDataFactory.js +16 -13
  48. package/lib/helper/FileSystem.js +32 -12
  49. package/lib/helper/GraphQL.js +1 -1
  50. package/lib/helper/GraphQLDataFactory.js +1 -1
  51. package/lib/helper/JSONResponse.js +19 -30
  52. package/lib/helper/Mochawesome.js +9 -28
  53. package/lib/helper/Playwright.js +668 -265
  54. package/lib/helper/Puppeteer.js +284 -169
  55. package/lib/helper/REST.js +29 -12
  56. package/lib/helper/WebDriver.js +191 -71
  57. package/lib/helper/errors/ConnectionRefused.js +6 -6
  58. package/lib/helper/errors/ElementAssertion.js +11 -16
  59. package/lib/helper/errors/ElementNotFound.js +5 -9
  60. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  61. package/lib/helper/extras/Console.js +11 -11
  62. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  63. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  64. package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
  65. package/lib/helper/extras/Popup.js +1 -1
  66. package/lib/helper/extras/React.js +29 -30
  67. package/lib/helper/network/actions.js +33 -48
  68. package/lib/helper/network/utils.js +76 -83
  69. package/lib/helper/scripts/blurElement.js +6 -6
  70. package/lib/helper/scripts/focusElement.js +6 -6
  71. package/lib/helper/scripts/highlightElement.js +9 -9
  72. package/lib/helper/scripts/isElementClickable.js +34 -34
  73. package/lib/helper.js +2 -1
  74. package/lib/history.js +23 -20
  75. package/lib/hooks.js +10 -10
  76. package/lib/html.js +90 -100
  77. package/lib/index.js +48 -21
  78. package/lib/listener/config.js +8 -9
  79. package/lib/listener/emptyRun.js +6 -7
  80. package/lib/listener/exit.js +4 -3
  81. package/lib/listener/globalRetry.js +5 -5
  82. package/lib/listener/globalTimeout.js +11 -10
  83. package/lib/listener/helpers.js +33 -14
  84. package/lib/listener/mocha.js +3 -4
  85. package/lib/listener/result.js +4 -5
  86. package/lib/listener/steps.js +7 -18
  87. package/lib/listener/store.js +3 -3
  88. package/lib/locator.js +213 -192
  89. package/lib/mocha/asyncWrapper.js +108 -75
  90. package/lib/mocha/bdd.js +99 -13
  91. package/lib/mocha/cli.js +60 -27
  92. package/lib/mocha/factory.js +75 -19
  93. package/lib/mocha/featureConfig.js +1 -1
  94. package/lib/mocha/gherkin.js +57 -25
  95. package/lib/mocha/hooks.js +12 -3
  96. package/lib/mocha/index.js +13 -4
  97. package/lib/mocha/inject.js +22 -5
  98. package/lib/mocha/scenarioConfig.js +2 -2
  99. package/lib/mocha/suite.js +9 -2
  100. package/lib/mocha/test.js +10 -13
  101. package/lib/mocha/ui.js +28 -31
  102. package/lib/output.js +11 -9
  103. package/lib/parser.js +44 -44
  104. package/lib/pause.js +15 -16
  105. package/lib/plugin/analyze.js +19 -12
  106. package/lib/plugin/auth.js +20 -21
  107. package/lib/plugin/autoDelay.js +12 -8
  108. package/lib/plugin/coverage.js +12 -8
  109. package/lib/plugin/customLocator.js +3 -3
  110. package/lib/plugin/customReporter.js +3 -2
  111. package/lib/plugin/heal.js +14 -9
  112. package/lib/plugin/pageInfo.js +10 -10
  113. package/lib/plugin/pauseOnFail.js +4 -3
  114. package/lib/plugin/retryFailedStep.js +47 -5
  115. package/lib/plugin/screenshotOnFail.js +75 -37
  116. package/lib/plugin/stepByStepReport.js +14 -14
  117. package/lib/plugin/stepTimeout.js +4 -3
  118. package/lib/plugin/subtitles.js +6 -5
  119. package/lib/recorder.js +33 -23
  120. package/lib/rerun.js +69 -26
  121. package/lib/result.js +4 -4
  122. package/lib/secret.js +18 -17
  123. package/lib/session.js +95 -89
  124. package/lib/step/base.js +6 -6
  125. package/lib/step/config.js +1 -1
  126. package/lib/step/func.js +3 -3
  127. package/lib/step/helper.js +3 -3
  128. package/lib/step/meta.js +4 -4
  129. package/lib/step/record.js +11 -11
  130. package/lib/step/retry.js +3 -3
  131. package/lib/step/section.js +3 -3
  132. package/lib/step.js +7 -10
  133. package/lib/steps.js +9 -5
  134. package/lib/store.js +1 -1
  135. package/lib/timeout.js +1 -7
  136. package/lib/transform.js +8 -8
  137. package/lib/translation.js +32 -18
  138. package/lib/utils.js +68 -97
  139. package/lib/workerStorage.js +16 -17
  140. package/lib/workers.js +145 -171
  141. package/package.json +63 -57
  142. package/translations/de-DE.js +2 -2
  143. package/translations/fr-FR.js +2 -2
  144. package/translations/index.js +23 -10
  145. package/translations/it-IT.js +2 -2
  146. package/translations/ja-JP.js +2 -2
  147. package/translations/nl-NL.js +2 -2
  148. package/translations/pl-PL.js +2 -2
  149. package/translations/pt-BR.js +2 -2
  150. package/translations/ru-RU.js +2 -2
  151. package/translations/utils.js +11 -2
  152. package/translations/zh-CN.js +2 -2
  153. package/translations/zh-TW.js +2 -2
  154. package/typings/index.d.ts +7 -18
  155. package/typings/promiseBasedTypes.d.ts +3769 -5450
  156. package/typings/types.d.ts +3953 -5778
  157. package/bin/test-server.js +0 -53
  158. package/lib/element/WebElement.js +0 -327
  159. package/lib/helper/Nightmare.js +0 -1486
  160. package/lib/helper/Protractor.js +0 -1840
  161. package/lib/helper/TestCafe.js +0 -1391
  162. package/lib/helper/clientscripts/nightmare.js +0 -213
  163. package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
  164. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  165. package/lib/helper/testcafe/testcafe-utils.js +0 -61
  166. package/lib/listener/retryEnhancer.js +0 -85
  167. package/lib/plugin/allure.js +0 -15
  168. package/lib/plugin/autoLogin.js +0 -5
  169. package/lib/plugin/commentStep.js +0 -141
  170. package/lib/plugin/eachElement.js +0 -127
  171. package/lib/plugin/fakerTransform.js +0 -49
  172. package/lib/plugin/htmlReporter.js +0 -1947
  173. package/lib/plugin/retryTo.js +0 -16
  174. package/lib/plugin/selenoid.js +0 -364
  175. package/lib/plugin/standardActingHelpers.js +0 -6
  176. package/lib/plugin/tryTo.js +0 -16
  177. package/lib/plugin/wdio.js +0 -247
  178. package/lib/test-server.js +0 -323
  179. package/lib/within.js +0 -90
package/lib/recorder.js CHANGED
@@ -1,9 +1,10 @@
1
- const debug = require('debug')('codeceptjs:recorder')
2
- const promiseRetry = require('promise-retry')
3
- const chalk = require('chalk')
4
- const { printObjectProperties } = require('./utils')
5
- const { log } = require('./output')
6
- const { TimeoutError } = require('./timeout')
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'
7
8
  const MAX_TASKS = 100
8
9
 
9
10
  let promise
@@ -28,7 +29,7 @@ const defaultRetryOptions = {
28
29
  * @alias recorder
29
30
  * @interface
30
31
  */
31
- module.exports = {
32
+ export default {
32
33
  /**
33
34
  * @type {Array<Object<string, *>>}
34
35
  * @inner
@@ -90,7 +91,7 @@ module.exports = {
90
91
  queueId++
91
92
  sessionId = null
92
93
  asyncErr = null
93
- log(`${currentQueue()} Starting recording promises`)
94
+ output.log(`${currentQueue()} Starting recording promises`)
94
95
  promise = Promise.resolve()
95
96
  oldPromises = []
96
97
  tasks = []
@@ -201,7 +202,7 @@ module.exports = {
201
202
 
202
203
  const retryRules = this.retries.slice().reverse()
203
204
  return promiseRetry(Object.assign(defaultRetryOptions, retryOpts), (retry, number) => {
204
- if (number > 1) log(`${currentQueue()}Retrying... Attempt #${number}`)
205
+ if (number > 1) output.log(`${currentQueue()}Retrying... Attempt #${number}`)
205
206
  const [promise, timer] = getTimeoutPromise(timeout, taskName)
206
207
  return Promise.race([promise, Promise.resolve(res).then(fn)])
207
208
  .finally(() => clearTimeout(timer))
@@ -231,7 +232,9 @@ module.exports = {
231
232
  if (Number.isInteger(opts)) {
232
233
  opts = { retries: opts }
233
234
  }
234
- return this.add(() => this.retries.push(opts))
235
+ // Push retry options immediately so first step can see them
236
+ this.retries.push(opts)
237
+ return Promise.resolve()
235
238
  },
236
239
 
237
240
  /**
@@ -246,8 +249,9 @@ module.exports = {
246
249
  .replace(/\n/g, ' ')
247
250
  ?.slice(0, 50)
248
251
  debug(chalk.gray(`${currentQueue()} Queued | catch with error handler ${fnDescription || ''}`))
252
+ if (!promise) promise = Promise.resolve()
249
253
  return (promise = promise.catch(err => {
250
- log(`${currentQueue()}Error | ${err} ${fnDescription}...`)
254
+ output.log(`${currentQueue()}Error | ${err} ${fnDescription}...`)
251
255
  if (!(err instanceof Error)) {
252
256
  // strange things may happen
253
257
  err = new Error(`[Wrapped Error] ${printObjectProperties(err)}`) // we should be prepared for them
@@ -272,15 +276,30 @@ module.exports = {
272
276
  ?.replace(/\s{2,}/g, ' ')
273
277
  .replace(/\n/g, ' ')
274
278
  ?.slice(0, 50)
279
+ if (!promise) promise = Promise.resolve()
275
280
  return (promise = promise.catch(err => {
276
281
  if (ignoredErrs.includes(err)) return // already caught
277
- log(`${currentQueue()} Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`)
282
+
283
+ // Handle terminal errors - don't continue, re-throw immediately
284
+ 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'))))) {
285
+ output.log(`${currentQueue()} Terminal Error | ${err} | ${fnDescription || ''}...`)
286
+ throw err // Re-throw terminal errors immediately
287
+ }
288
+
289
+ output.log(`${currentQueue()} Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`)
278
290
  if (!(err instanceof Error)) {
279
291
  // strange things may happen
280
292
  err = new Error(`[Wrapped Error] ${JSON.stringify(err)}`) // we should be prepared for them
281
293
  }
282
294
  if (customErrFn) {
283
- return customErrFn(err)
295
+ try {
296
+ const result = customErrFn(err)
297
+ // If customErrFn returns a value (not throwing), treat it as handled
298
+ return result
299
+ } catch (thrownErr) {
300
+ // If customErrFn throws an error, propagate it up
301
+ throw thrownErr
302
+ }
284
303
  }
285
304
  }))
286
305
  },
@@ -338,7 +357,7 @@ module.exports = {
338
357
  */
339
358
  stop() {
340
359
  debug(this.toString())
341
- log(`${currentQueue()} Stopping recording promises`)
360
+ output.log(`${currentQueue()} Stopping recording promises`)
342
361
  running = false
343
362
  },
344
363
 
@@ -379,15 +398,6 @@ module.exports = {
379
398
  toString() {
380
399
  return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}`
381
400
  },
382
-
383
- /**
384
- * Get current session ID
385
- * @return {string|null}
386
- * @inner
387
- */
388
- getCurrentSessionId() {
389
- return sessionId
390
- },
391
401
  }
392
402
 
393
403
  function getTimeoutPromise(timeoutMs, taskName) {
package/lib/rerun.js CHANGED
@@ -1,34 +1,77 @@
1
- const fsPath = require('path')
2
- const container = require('./container')
3
- const event = require('./event')
4
- const BaseCodecept = require('./codecept')
5
- const output = require('./output')
1
+ import fsPath from 'path'
2
+ import container from './container.js'
3
+ import event from './event.js'
4
+ import BaseCodecept from './codecept.js'
5
+ import output from './output.js'
6
+ import { createRequire } from 'module'
7
+
8
+ const require = createRequire(import.meta.url)
6
9
 
7
10
  class CodeceptRerunner extends BaseCodecept {
8
- runOnce(test) {
9
- return new Promise((resolve, reject) => {
10
- // @ts-ignore
11
- container.createMocha()
12
- const mocha = container.mocha()
13
- this.testFiles.forEach(file => {
14
- delete require.cache[file]
15
- })
16
- mocha.files = this.testFiles
17
- if (test) {
18
- if (!fsPath.isAbsolute(test)) {
19
- test = fsPath.join(global.codecept_dir, test)
20
- }
21
- mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test)
22
- }
11
+ async runOnce(test) {
12
+ await container.started()
13
+
14
+ // Ensure translations are loaded for Gherkin features
15
+ try {
16
+ const { loadTranslations } = await import('./mocha/gherkin.js')
17
+ await loadTranslations()
18
+ } catch (e) {
19
+ // Ignore if gherkin module not available
20
+ }
21
+
22
+ return new Promise(async (resolve, reject) => {
23
23
  try {
24
- mocha.run(failures => {
25
- if (failures === 0) {
26
- resolve()
24
+ // Create a fresh Mocha instance for each run
25
+ // @ts-ignore
26
+ container.createMocha()
27
+ const mocha = container.mocha()
28
+
29
+ let filesToRun = this.testFiles
30
+ if (test) {
31
+ if (!fsPath.isAbsolute(test)) {
32
+ test = fsPath.join(global.codecept_dir, test)
33
+ }
34
+ filesToRun = this.testFiles.filter(t => fsPath.basename(t, '.js') === test || t === test)
35
+ }
36
+
37
+ // Clear any existing tests/suites
38
+ mocha.suite.suites = []
39
+ mocha.suite.tests = []
40
+
41
+ // Manually load each test file by importing it
42
+ for (const file of filesToRun) {
43
+ try {
44
+ // Clear CommonJS cache if available (for mixed environments)
45
+ try {
46
+ delete require.cache[file]
47
+ } catch (e) {
48
+ // ESM modules don't have require.cache, ignore
49
+ }
50
+
51
+ // Force reload the module by using a cache-busting query parameter
52
+ const fileUrl = `${fsPath.resolve(file)}?t=${Date.now()}`
53
+ await import(fileUrl)
54
+ } catch (e) {
55
+ console.error(`Error loading test file ${file}:`, e)
56
+ }
57
+ }
58
+
59
+ const done = () => {
60
+ event.emit(event.all.result, container.result())
61
+ event.emit(event.all.after, this)
62
+
63
+ // Check if there were any failures
64
+ if (container.result().hasFailed) {
65
+ reject(new Error('Test run failed'))
27
66
  } else {
28
- reject(new Error(`${failures} tests fail`))
67
+ resolve(undefined)
29
68
  }
30
- })
69
+ }
70
+
71
+ event.emit(event.all.before, this)
72
+ mocha.run(() => done())
31
73
  } catch (e) {
74
+ output.error(e.stack)
32
75
  reject(e)
33
76
  }
34
77
  })
@@ -79,4 +122,4 @@ class CodeceptRerunner extends BaseCodecept {
79
122
  }
80
123
  }
81
124
 
82
- module.exports = CodeceptRerunner
125
+ export default CodeceptRerunner
package/lib/result.js CHANGED
@@ -1,6 +1,6 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
- const { serializeTest } = require('./mocha/test')
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { serializeTest } from './mocha/test.js'
4
4
 
5
5
  /**
6
6
  * Result of the test run
@@ -158,4 +158,4 @@ class Result {
158
158
  }
159
159
  }
160
160
 
161
- module.exports = Result
161
+ export default Result
package/lib/secret.js CHANGED
@@ -1,20 +1,20 @@
1
- const { deepClone } = require('./utils');
1
+ import { deepClone } from './utils.js'
2
2
 
3
- const maskedString = '*****';
3
+ const maskedString = '*****'
4
4
 
5
5
  /** @param {string} secret */
6
6
  class Secret {
7
7
  constructor(secret) {
8
- this._secret = secret;
8
+ this._secret = secret
9
9
  }
10
10
 
11
11
  /** @returns {string} */
12
12
  toString() {
13
- return this._secret;
13
+ return this._secret
14
14
  }
15
15
 
16
16
  getMasked() {
17
- return maskedString;
17
+ return maskedString
18
18
  }
19
19
 
20
20
  /**
@@ -23,11 +23,11 @@ class Secret {
23
23
  */
24
24
  static secret(secret) {
25
25
  if (typeof secret === 'object') {
26
- const fields = Array.from(arguments);
27
- fields.shift();
28
- return secretObject(secret, fields);
26
+ const fields = Array.from(arguments)
27
+ fields.shift()
28
+ return secretObject(secret, fields)
29
29
  }
30
- return new Secret(secret);
30
+ return new Secret(secret)
31
31
  }
32
32
  }
33
33
 
@@ -36,16 +36,17 @@ function secretObject(obj, fieldsToHide = []) {
36
36
  get(obj, prop) {
37
37
  if (prop === 'toString') {
38
38
  return function () {
39
- const maskedObject = deepClone(obj);
40
- fieldsToHide.forEach(f => (maskedObject[f] = maskedString));
41
- return JSON.stringify(maskedObject);
42
- };
39
+ const maskedObject = deepClone(obj)
40
+ fieldsToHide.forEach(f => (maskedObject[f] = maskedString))
41
+ return JSON.stringify(maskedObject)
42
+ }
43
43
  }
44
- return fieldsToHide.includes(prop) ? new Secret(obj[prop]) : obj[prop];
44
+ return fieldsToHide.includes(prop) ? new Secret(obj[prop]) : obj[prop]
45
45
  },
46
- };
46
+ }
47
47
 
48
- return new Proxy(obj, handler);
48
+ return new Proxy(obj, handler)
49
49
  }
50
50
 
51
- module.exports = Secret;
51
+ export default Secret
52
+ export const secret = Secret.secret
package/lib/session.js CHANGED
@@ -1,19 +1,13 @@
1
- const recorder = require('./recorder');
2
- const container = require('./container');
3
- const event = require('./event');
4
- const output = require('./output');
5
- const store = require('./store');
6
- const { isAsyncFunction } = require('./utils');
7
-
8
- const sessionColors = [
9
- 'cyan',
10
- 'blue',
11
- 'red',
12
- 'magenta',
13
- 'yellow',
14
- ];
15
-
16
- const savedSessions = {};
1
+ import recorder from './recorder.js'
2
+ import container from './container.js'
3
+ import event from './event.js'
4
+ import output from './output.js'
5
+ import store from './store.js'
6
+ import { isAsyncFunction } from './utils.js'
7
+
8
+ const sessionColors = ['cyan', 'blue', 'red', 'magenta', 'yellow']
9
+
10
+ const savedSessions = {}
17
11
 
18
12
  /**
19
13
  * @param {CodeceptJS.LocatorOrString} sessionName
@@ -24,109 +18,121 @@ const savedSessions = {};
24
18
  function session(sessionName, config, fn) {
25
19
  if (typeof config === 'function') {
26
20
  if (typeof fn === 'function') {
27
- config = config();
21
+ config = config()
28
22
  } else {
29
23
  // no config but with function
30
- fn = config;
31
- config = {};
24
+ fn = config
25
+ config = {}
32
26
  }
33
27
  }
34
28
  // session helpers won't use beforeSuite and afterSuite hooks...
35
29
  // restart: false options are not allowed as well
36
30
  // but those helpers should be already started so inside listener/helpers.js the `_init` method should already be called
37
31
 
38
- const helpers = container.helpers();
32
+ const helpers = container.helpers()
39
33
 
40
34
  if (!savedSessions[sessionName]) {
41
35
  for (const helper in helpers) {
42
- if (!helpers[helper]._session) continue;
36
+ if (!helpers[helper]._session) continue
43
37
  savedSessions[sessionName] = {
44
38
  start: () => null,
45
39
  stop: () => null,
46
40
  loadVars: () => null,
47
41
  restoreVars: () => null,
48
42
  ...(store.dryRun ? {} : helpers[helper]._session()),
49
- };
50
- break;
43
+ }
44
+ break
51
45
  }
52
46
 
53
47
  const closeBrowsers = () => {
54
- const session = savedSessions[sessionName];
55
- if (!session) return;
56
- session.stop(session.vars);
57
- delete savedSessions[sessionName];
58
- };
48
+ const session = savedSessions[sessionName]
49
+ if (!session) return
50
+ session.stop(session.vars)
51
+ delete savedSessions[sessionName]
52
+ }
59
53
 
60
54
  event.dispatcher.once(event.test.after, () => {
61
- recorder.add('close session browsers', closeBrowsers);
62
- });
55
+ recorder.add('close session browsers', closeBrowsers)
56
+ })
63
57
 
64
58
  if (!savedSessions[sessionName]) {
65
- throw new Error('Configured helpers do not support starting sessions. Please use a helper with session support.');
59
+ throw new Error('Configured helpers do not support starting sessions. Please use a helper with session support.')
66
60
  }
67
61
 
68
62
  recorder.add('save vars', async () => {
69
- savedSessions[sessionName].vars = await savedSessions[sessionName].start(sessionName, config);
70
- });
63
+ savedSessions[sessionName].vars = await savedSessions[sessionName].start(sessionName, config)
64
+ })
71
65
  }
72
66
 
73
67
  // pick random color
74
- const color = sessionColors[Object.keys(savedSessions).indexOf(sessionName) % sessionColors.length];
75
-
76
- const addContextToStep = (step) => {
77
- step.actor = `${output.colors[color](sessionName)}: I`;
78
- };
79
-
80
- if (!fn) return; // no current session steps
81
-
82
- return recorder.add('register session wrapper', async () => {
83
- const session = savedSessions[sessionName];
84
- recorder.session.start(`session:${sessionName}`);
85
- event.dispatcher.on(event.step.after, addContextToStep);
86
- recorder.add('switch to browser', () => {
87
- const session = savedSessions[sessionName];
88
- return session.loadVars(session.vars);
89
- });
90
-
91
- const finalize = () => {
92
- recorder.add('Finalize session', async () => {
93
- output.stepShift = 0;
94
- event.dispatcher.removeListener(event.step.after, addContextToStep);
95
- await session.restoreVars();
96
- recorder.session.restore(`session:${sessionName}`);
97
- });
98
- };
99
-
100
- // Indicate when executing this function that we are in a session
101
- if (isAsyncFunction(fn)) {
102
- return fn.apply(null).then((res) => {
103
- finalize();
104
- return recorder.promise().then(() => res);
105
- }).catch((e) => {
106
- output.stepShift = 0;
107
- session.restoreVars(sessionName);
108
- event.dispatcher.removeListener(event.step.after, addContextToStep);
109
- recorder.throw(e);
110
- return recorder.promise();
111
- });
112
- }
68
+ const color = sessionColors[Object.keys(savedSessions).indexOf(sessionName) % sessionColors.length]
113
69
 
114
- let res;
115
- try {
116
- res = fn.apply(null);
117
- } catch (err) {
118
- recorder.throw(err);
119
- } finally {
120
- recorder.catch((e) => {
121
- session.restoreVars(sessionName);
122
- output.stepShift = 0;
123
- event.dispatcher.removeListener(event.step.after, addContextToStep);
124
- throw e;
125
- });
126
- }
127
- finalize();
128
- return recorder.promise().then(() => res);
129
- }, false, false);
70
+ const addContextToStep = step => {
71
+ step.actor = `${output.colors[color](sessionName)}: I`
72
+ }
73
+
74
+ if (!fn) return // no current session steps
75
+
76
+ return recorder.add(
77
+ 'register session wrapper',
78
+ async () => {
79
+ const session = savedSessions[sessionName]
80
+ if (!session) {
81
+ throw new Error(`Session "${sessionName}" not found. It may have been closed already.`)
82
+ }
83
+ recorder.session.start(`session:${sessionName}`)
84
+ event.dispatcher.on(event.step.after, addContextToStep)
85
+ recorder.add('switch to browser', () => {
86
+ const session = savedSessions[sessionName]
87
+ return session.loadVars(session.vars)
88
+ })
89
+
90
+ const finalize = () => {
91
+ recorder.add('Finalize session', async () => {
92
+ output.stepShift = 0
93
+ event.dispatcher.removeListener(event.step.after, addContextToStep)
94
+ await session.restoreVars()
95
+ recorder.session.restore(`session:${sessionName}`)
96
+ })
97
+ }
98
+
99
+ // Indicate when executing this function that we are in a session
100
+ if (isAsyncFunction(fn)) {
101
+ return fn
102
+ .apply(null)
103
+ .then(async res => {
104
+ finalize()
105
+ await recorder.promise()
106
+ return res
107
+ })
108
+ .catch(e => {
109
+ output.stepShift = 0
110
+ session.restoreVars(sessionName)
111
+ event.dispatcher.removeListener(event.step.after, addContextToStep)
112
+ recorder.throw(e)
113
+ return recorder.promise()
114
+ })
115
+ }
116
+
117
+ let res
118
+ try {
119
+ res = fn.apply(null)
120
+ } catch (err) {
121
+ recorder.throw(err)
122
+ } finally {
123
+ recorder.catch(e => {
124
+ session.restoreVars(sessionName)
125
+ output.stepShift = 0
126
+ event.dispatcher.removeListener(event.step.after, addContextToStep)
127
+ throw e
128
+ })
129
+ }
130
+ finalize()
131
+ return recorder.promise().then(() => res)
132
+ },
133
+ false,
134
+ false,
135
+ )
130
136
  }
131
137
 
132
- module.exports = session;
138
+ export default session
package/lib/step/base.js CHANGED
@@ -1,8 +1,8 @@
1
- const color = require('chalk')
2
- const Secret = require('../secret')
3
- const { getCurrentTimeout } = require('../timeout')
4
- const { ucfirst, humanizeString, serializeError } = require('../utils')
5
- const recordStep = require('./record')
1
+ import color from 'chalk'
2
+ import Secret from '../secret.js'
3
+ import { getCurrentTimeout } from '../timeout.js'
4
+ import { ucfirst, humanizeString, serializeError } from '../utils.js'
5
+ import recordStep from './record.js'
6
6
 
7
7
  const STACK_LINE = 5
8
8
 
@@ -236,4 +236,4 @@ class Step {
236
236
  }
237
237
  }
238
238
 
239
- module.exports = Step
239
+ export default Step
@@ -47,4 +47,4 @@ class StepConfig {
47
47
  }
48
48
  }
49
49
 
50
- module.exports = StepConfig
50
+ export default StepConfig
package/lib/step/func.js CHANGED
@@ -1,5 +1,5 @@
1
- const BaseStep = require('./base')
2
- const store = require('../store')
1
+ import BaseStep from './base.js'
2
+ import store from '../store.js'
3
3
 
4
4
  /**
5
5
  * Function executed as a step
@@ -43,4 +43,4 @@ class FuncStep extends BaseStep {
43
43
  }
44
44
  }
45
45
 
46
- module.exports = FuncStep
46
+ export default FuncStep
@@ -1,5 +1,5 @@
1
- const Step = require('./base')
2
- const store = require('../store')
1
+ import Step from './base.js'
2
+ import store from '../store.js'
3
3
 
4
4
  class HelperStep extends Step {
5
5
  constructor(helper, name) {
@@ -38,7 +38,7 @@ class HelperStep extends Step {
38
38
  }
39
39
  }
40
40
 
41
- module.exports = HelperStep
41
+ export default HelperStep
42
42
 
43
43
  function dryRunResolver() {
44
44
  return {
package/lib/step/meta.js CHANGED
@@ -1,6 +1,6 @@
1
- const Step = require('./base')
2
- const event = require('../event')
3
- const { humanizeString } = require('../utils')
1
+ import Step from './base.js'
2
+ import event from '../event.js'
3
+ import { humanizeString } from '../utils.js'
4
4
 
5
5
  class MetaStep extends Step {
6
6
  constructor(actor, method) {
@@ -96,4 +96,4 @@ class MetaStep extends Step {
96
96
  }
97
97
  }
98
98
 
99
- module.exports = MetaStep
99
+ export default MetaStep
@@ -1,10 +1,10 @@
1
- const event = require('../event')
2
- const recorder = require('../recorder')
3
- const StepConfig = require('./config')
4
- const { debug } = require('../output')
5
- const store = require('../store')
6
- const { TIMEOUT_ORDER } = require('../timeout')
7
- const retryStep = require('./retry')
1
+ import event from '../event.js'
2
+ import recorder from '../recorder.js'
3
+ import StepConfig from './config.js'
4
+ import output from '../output.js'
5
+ import store from '../store.js'
6
+ import { TIMEOUT_ORDER } from '../timeout.js'
7
+ import retryStep from './retry.js'
8
8
  function recordStep(step, args) {
9
9
  step.status = 'queued'
10
10
 
@@ -15,12 +15,12 @@ function recordStep(step, args) {
15
15
  const { opts, timeout, retry } = stepConfig.getConfig()
16
16
 
17
17
  if (opts) {
18
- debug(`Step ${step.name}: options applied ${JSON.stringify(opts)}`)
18
+ output.debug(`Step ${step.name}: options applied ${JSON.stringify(opts)}`)
19
19
  store.stepOptions = opts
20
20
  step.opts = opts
21
21
  }
22
22
  if (timeout) {
23
- debug(`Step ${step.name} timeout ${timeout}s`)
23
+ output.debug(`Step ${step.name} timeout ${timeout}s`)
24
24
  step.setTimeout(timeout * 1000, TIMEOUT_ORDER.codeLimitTime)
25
25
  }
26
26
  if (retry) retryStep(retry)
@@ -57,7 +57,7 @@ function recordStep(step, args) {
57
57
  event.emit(event.step.finished, step)
58
58
  })
59
59
 
60
- recorder.catchWithoutStop(err => {
60
+ recorder.catch(err => {
61
61
  step.status = 'failed'
62
62
  step.endTime = +Date.now()
63
63
  event.emit(event.step.failed, step, err)
@@ -71,4 +71,4 @@ function recordStep(step, args) {
71
71
  return recorder.promise()
72
72
  }
73
73
 
74
- module.exports = recordStep
74
+ export default recordStep