codeceptjs 3.6.10 → 3.7.0-beta.1

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 (105) hide show
  1. package/README.md +81 -110
  2. package/bin/codecept.js +2 -2
  3. package/docs/webapi/clearCookie.mustache +1 -1
  4. package/lib/actor.js +46 -36
  5. package/lib/assert/empty.js +3 -5
  6. package/lib/assert/equal.js +4 -7
  7. package/lib/assert/include.js +4 -6
  8. package/lib/assert/throws.js +2 -4
  9. package/lib/assert/truth.js +2 -2
  10. package/lib/codecept.js +87 -83
  11. package/lib/command/configMigrate.js +2 -4
  12. package/lib/command/definitions.js +5 -25
  13. package/lib/command/generate.js +10 -14
  14. package/lib/command/gherkin/snippets.js +10 -8
  15. package/lib/command/gherkin/steps.js +1 -1
  16. package/lib/command/info.js +1 -3
  17. package/lib/command/init.js +8 -12
  18. package/lib/command/interactive.js +1 -1
  19. package/lib/command/list.js +1 -1
  20. package/lib/command/run-multiple.js +12 -35
  21. package/lib/command/run-workers.js +10 -10
  22. package/lib/command/utils.js +5 -6
  23. package/lib/command/workers/runTests.js +14 -17
  24. package/lib/container.js +327 -237
  25. package/lib/data/context.js +10 -13
  26. package/lib/data/dataScenarioConfig.js +8 -8
  27. package/lib/data/dataTableArgument.js +6 -6
  28. package/lib/data/table.js +5 -11
  29. package/lib/els.js +177 -0
  30. package/lib/event.js +1 -0
  31. package/lib/heal.js +78 -80
  32. package/lib/helper/ApiDataFactory.js +3 -6
  33. package/lib/helper/Appium.js +15 -30
  34. package/lib/helper/FileSystem.js +3 -3
  35. package/lib/helper/GraphQLDataFactory.js +3 -3
  36. package/lib/helper/JSONResponse.js +57 -37
  37. package/lib/helper/Nightmare.js +35 -53
  38. package/lib/helper/Playwright.js +189 -251
  39. package/lib/helper/Protractor.js +54 -77
  40. package/lib/helper/Puppeteer.js +134 -232
  41. package/lib/helper/REST.js +5 -17
  42. package/lib/helper/TestCafe.js +21 -44
  43. package/lib/helper/WebDriver.js +103 -162
  44. package/lib/helper/testcafe/testcafe-utils.js +26 -27
  45. package/lib/listener/artifacts.js +2 -2
  46. package/lib/listener/emptyRun.js +58 -0
  47. package/lib/listener/exit.js +4 -4
  48. package/lib/listener/{retry.js → globalRetry.js} +5 -5
  49. package/lib/listener/{timeout.js → globalTimeout.js} +8 -8
  50. package/lib/listener/helpers.js +15 -15
  51. package/lib/listener/mocha.js +1 -1
  52. package/lib/listener/steps.js +17 -12
  53. package/lib/listener/store.js +12 -0
  54. package/lib/mocha/asyncWrapper.js +204 -0
  55. package/lib/{interfaces → mocha}/bdd.js +3 -3
  56. package/lib/mocha/cli.js +257 -0
  57. package/lib/mocha/factory.js +104 -0
  58. package/lib/{interfaces → mocha}/featureConfig.js +11 -12
  59. package/lib/{interfaces → mocha}/gherkin.js +26 -28
  60. package/lib/mocha/hooks.js +83 -0
  61. package/lib/mocha/index.js +12 -0
  62. package/lib/mocha/inject.js +24 -0
  63. package/lib/{interfaces → mocha}/scenarioConfig.js +10 -6
  64. package/lib/mocha/suite.js +55 -0
  65. package/lib/mocha/test.js +60 -0
  66. package/lib/mocha/types.d.ts +31 -0
  67. package/lib/mocha/ui.js +219 -0
  68. package/lib/output.js +28 -10
  69. package/lib/pause.js +159 -135
  70. package/lib/plugin/autoDelay.js +4 -4
  71. package/lib/plugin/autoLogin.js +6 -7
  72. package/lib/plugin/commentStep.js +1 -1
  73. package/lib/plugin/coverage.js +10 -19
  74. package/lib/plugin/customLocator.js +3 -3
  75. package/lib/plugin/debugErrors.js +2 -2
  76. package/lib/plugin/eachElement.js +1 -1
  77. package/lib/plugin/fakerTransform.js +1 -1
  78. package/lib/plugin/heal.js +6 -9
  79. package/lib/plugin/retryFailedStep.js +4 -4
  80. package/lib/plugin/retryTo.js +2 -2
  81. package/lib/plugin/screenshotOnFail.js +9 -36
  82. package/lib/plugin/selenoid.js +15 -35
  83. package/lib/plugin/stepByStepReport.js +51 -13
  84. package/lib/plugin/stepTimeout.js +4 -11
  85. package/lib/plugin/subtitles.js +4 -4
  86. package/lib/plugin/tryTo.js +1 -1
  87. package/lib/plugin/wdio.js +8 -10
  88. package/lib/recorder.js +142 -121
  89. package/lib/secret.js +1 -1
  90. package/lib/step.js +160 -144
  91. package/lib/store.js +6 -2
  92. package/lib/template/heal.js +2 -11
  93. package/lib/utils.js +224 -216
  94. package/lib/within.js +73 -55
  95. package/lib/workers.js +265 -261
  96. package/package.json +46 -47
  97. package/typings/index.d.ts +172 -184
  98. package/typings/promiseBasedTypes.d.ts +53 -516
  99. package/typings/types.d.ts +127 -587
  100. package/lib/cli.js +0 -256
  101. package/lib/helper/ExpectHelper.js +0 -391
  102. package/lib/helper/SoftExpectHelper.js +0 -381
  103. package/lib/mochaFactory.js +0 -113
  104. package/lib/scenario.js +0 -224
  105. package/lib/ui.js +0 -236
@@ -76,14 +76,14 @@ const defaultConfig = {
76
76
  * ```
77
77
  *
78
78
  */
79
- module.exports = (config) => {
79
+ module.exports = config => {
80
80
  config = Object.assign(defaultConfig, config)
81
81
  config.ignoredSteps = config.ignoredSteps.concat(config.defaultIgnoredSteps)
82
82
  const customWhen = config.when
83
83
 
84
84
  let enableRetry = false
85
85
 
86
- const when = (err) => {
86
+ const when = err => {
87
87
  if (!enableRetry) return
88
88
  const store = require('../store')
89
89
  if (store.debugMode) return false
@@ -92,7 +92,7 @@ module.exports = (config) => {
92
92
  }
93
93
  config.when = when
94
94
 
95
- event.dispatcher.on(event.step.started, (step) => {
95
+ event.dispatcher.on(event.step.started, step => {
96
96
  if (process.env.TRY_TO === 'true') {
97
97
  log('Info: RetryFailedStep plugin is disabled inside tryTo block')
98
98
  return
@@ -112,7 +112,7 @@ module.exports = (config) => {
112
112
  enableRetry = false
113
113
  })
114
114
 
115
- event.dispatcher.on(event.test.before, (test) => {
115
+ event.dispatcher.on(event.test.before, test => {
116
116
  if (test && test.disableRetryFailedStep) return // disable retry when a test is not active
117
117
  // this env var is used to set the retries inside _before() block of helpers
118
118
  process.env.FAILED_STEP_RETRIES = config.retries
@@ -100,7 +100,7 @@ module.exports = function (config) {
100
100
  })
101
101
 
102
102
  // Catch errors and retry
103
- recorder.session.catch((err) => {
103
+ recorder.session.catch(err => {
104
104
  recorder.session.restore(`retryTo ${tries}`)
105
105
  if (tries <= maxTries) {
106
106
  debug(`Error ${err}... Retrying`)
@@ -112,7 +112,7 @@ module.exports = function (config) {
112
112
  })
113
113
  }
114
114
 
115
- recorder.add('retryTo', tryBlock).catch((err) => {
115
+ recorder.add('retryTo', tryBlock).catch(err => {
116
116
  console.error('An error occurred:', err)
117
117
  done(null)
118
118
  })
@@ -63,9 +63,7 @@ module.exports = function (config) {
63
63
  }
64
64
 
65
65
  if (Codeceptjs.container.mocha()) {
66
- options.reportDir =
67
- Codeceptjs.container.mocha().options.reporterOptions &&
68
- Codeceptjs.container.mocha().options.reporterOptions.reportDir
66
+ options.reportDir = Codeceptjs.container.mocha().options.reporterOptions && Codeceptjs.container.mocha().options.reporterOptions.reportDir
69
67
  }
70
68
 
71
69
  if (options.disableScreenshots) {
@@ -73,12 +71,9 @@ module.exports = function (config) {
73
71
  return
74
72
  }
75
73
 
76
- event.dispatcher.on(event.test.failed, (test) => {
74
+ event.dispatcher.on(event.test.failed, test => {
77
75
  if (test.ctx?._runnable.title.includes('hook: ')) {
78
- output.plugin(
79
- 'screenshotOnFail',
80
- 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.',
81
- )
76
+ output.plugin('screenshotOnFail', 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.')
82
77
  return
83
78
  }
84
79
  recorder.add(
@@ -90,8 +85,7 @@ module.exports = function (config) {
90
85
  if (fileName.indexOf('{') !== -1) {
91
86
  fileName = fileName.substr(0, fileName.indexOf('{') - 3).trim()
92
87
  }
93
- if (test.ctx && test.ctx.test && test.ctx.test.type === 'hook')
94
- fileName = clearString(`${test.title}_${test.ctx.test.title}`)
88
+ if (test.ctx && test.ctx.test && test.ctx.test.type === 'hook') fileName = clearString(`${test.title}_${test.ctx.test.title}`)
95
89
  if (options.uniqueScreenshotNames && test) {
96
90
  const uuid = _getUUID(test)
97
91
  fileName = `${fileName.substring(0, 10)}_${uuid}.failed.png`
@@ -112,34 +106,20 @@ module.exports = function (config) {
112
106
 
113
107
  if (!test.artifacts) test.artifacts = {}
114
108
  test.artifacts.screenshot = path.join(global.output_dir, fileName)
115
- if (
116
- Container.mocha().options.reporterOptions['mocha-junit-reporter'] &&
117
- Container.mocha().options.reporterOptions['mocha-junit-reporter'].options.attachments
118
- ) {
109
+ if (Container.mocha().options.reporterOptions['mocha-junit-reporter'] && Container.mocha().options.reporterOptions['mocha-junit-reporter'].options.attachments) {
119
110
  test.attachments = [path.join(global.output_dir, fileName)]
120
111
  }
121
112
 
122
113
  const allureReporter = Container.plugins('allure')
123
114
  if (allureReporter) {
124
- allureReporter.addAttachment(
125
- 'Main session - Last Seen Screenshot',
126
- fs.readFileSync(path.join(global.output_dir, fileName)),
127
- dataType,
128
- )
115
+ allureReporter.addAttachment('Main session - Last Seen Screenshot', fs.readFileSync(path.join(global.output_dir, fileName)), dataType)
129
116
 
130
117
  if (helper.activeSessionName) {
131
118
  const sessions = helper.sessionPages || helper.sessionWindows
132
119
  for (const sessionName in sessions) {
133
120
  const screenshotFileName = `${sessionName}_${fileName}`
134
- test.artifacts[`${sessionName.replace(/ /g, '_')}_screenshot`] = path.join(
135
- global.output_dir,
136
- screenshotFileName,
137
- )
138
- allureReporter.addAttachment(
139
- `${sessionName} - Last Seen Screenshot`,
140
- fs.readFileSync(path.join(global.output_dir, screenshotFileName)),
141
- dataType,
142
- )
121
+ test.artifacts[`${sessionName.replace(/ /g, '_')}_screenshot`] = path.join(global.output_dir, screenshotFileName)
122
+ allureReporter.addAttachment(`${sessionName} - Last Seen Screenshot`, fs.readFileSync(path.join(global.output_dir, screenshotFileName)), dataType)
143
123
  }
144
124
  }
145
125
  }
@@ -150,14 +130,7 @@ module.exports = function (config) {
150
130
  }
151
131
  } catch (err) {
152
132
  output.plugin(err)
153
- if (
154
- err &&
155
- err.type &&
156
- err.type === 'RuntimeError' &&
157
- err.message &&
158
- (err.message.indexOf('was terminated due to') > -1 ||
159
- err.message.indexOf('no such window: target window already closed') > -1)
160
- ) {
133
+ if (err && err.type && err.type === 'RuntimeError' && err.message && (err.message.indexOf('was terminated due to') > -1 || err.message.indexOf('no such window: target window already closed') > -1)) {
161
134
  output.log(`Can't make screenshot, ${err}`)
162
135
  helper.isRunning = false
163
136
  }
@@ -41,12 +41,7 @@ const dockerCreateScriptArr = [
41
41
  'aerokube/selenoid:latest-release -log-output-dir /opt/selenoid/logs',
42
42
  ]
43
43
 
44
- const dockerImageCheckScript = [
45
- 'docker images',
46
- "--filter reference='selenoid/video-recorder'",
47
- "--filter reference='selenoid/chrome:latest'",
48
- "--filter reference='selenoid/firefox:latest'",
49
- ].join(' ')
44
+ const dockerImageCheckScript = ['docker images', "--filter reference='selenoid/video-recorder'", "--filter reference='selenoid/chrome:latest'", "--filter reference='selenoid/firefox:latest'"].join(' ')
50
45
 
51
46
  let dockerCreateScript = dockerCreateScriptArr.join(' ')
52
47
  let dockerStartScript = 'docker start $name$'
@@ -56,8 +51,8 @@ let seleniumUrl = 'http://localhost:$port$'
56
51
  const supportedHelpers = ['WebDriver']
57
52
  const SELENOID_START_TIMEOUT = 2000
58
53
  const SELENOID_STOP_TIMEOUT = 10000
59
- const wait = (time) =>
60
- new Promise((res) => {
54
+ const wait = time =>
55
+ new Promise(res => {
61
56
  setTimeout(() => {
62
57
  // @ts-ignore
63
58
  res()
@@ -179,7 +174,7 @@ const wait = (time) =>
179
174
  *
180
175
  */
181
176
 
182
- const selenoid = (config) => {
177
+ const selenoid = config => {
183
178
  const helpers = container.helpers()
184
179
  let helperName
185
180
 
@@ -194,14 +189,7 @@ const selenoid = (config) => {
194
189
  return // no helpers for Selenoid
195
190
  }
196
191
 
197
- const {
198
- autoStart,
199
- name = 'selenoid',
200
- deletePassed = true,
201
- additionalParams = '',
202
- autoCreate = true,
203
- port = 4444,
204
- } = config
192
+ const { autoStart, name = 'selenoid', deletePassed = true, additionalParams = '', autoCreate = true, port = 4444 } = config
205
193
  const passedTests = []
206
194
 
207
195
  recorder.startUnlessRunning()
@@ -213,7 +201,7 @@ const selenoid = (config) => {
213
201
  output.debug('Staring Selenoid... ')
214
202
  return createAndStart(autoCreate)
215
203
  .then(() => output.debug('Selenoid started'))
216
- .catch((err) => {
204
+ .catch(err => {
217
205
  throw new Error(err.stack)
218
206
  })
219
207
  })
@@ -226,7 +214,7 @@ const selenoid = (config) => {
226
214
  .then(() => deletePassedTests(passedTests))
227
215
  .then(stopSelenoid)
228
216
  .then(() => output.debug('Selenoid stopped'))
229
- .catch((err) => {
217
+ .catch(err => {
230
218
  throw new Error(err.stack)
231
219
  })
232
220
  })
@@ -241,7 +229,7 @@ const selenoid = (config) => {
241
229
  }
242
230
  })
243
231
 
244
- event.dispatcher.on(event.test.before, (test) => {
232
+ event.dispatcher.on(event.test.before, test => {
245
233
  switch (helperName) {
246
234
  case 'WebDriver':
247
235
  setTestConfigForWebdriver(test)
@@ -250,7 +238,7 @@ const selenoid = (config) => {
250
238
  })
251
239
 
252
240
  if (config.enableVideo) {
253
- event.dispatcher.on(event.test.passed, (test) => {
241
+ event.dispatcher.on(event.test.passed, test => {
254
242
  if (deletePassed) {
255
243
  passedTests.push(test.title)
256
244
  } else {
@@ -258,7 +246,7 @@ const selenoid = (config) => {
258
246
  }
259
247
  })
260
248
 
261
- event.dispatcher.on(event.test.failed, (test) => {
249
+ event.dispatcher.on(event.test.failed, test => {
262
250
  test.artifacts.video = videoSaved(test)
263
251
  })
264
252
  }
@@ -312,16 +300,12 @@ const pullImage = async () => {
312
300
  console.time('Pulled containers')
313
301
  if (!stdout.includes('selenoid/video-recorder')) {
314
302
  output.debug('Pulling selenoid/video-recorder...')
315
- resultPromise = exec('docker pull selenoid/video-recorder:latest-release').then(() =>
316
- output.debug('Pulled in selenoid/video-recorder'),
317
- )
303
+ resultPromise = exec('docker pull selenoid/video-recorder:latest-release').then(() => output.debug('Pulled in selenoid/video-recorder'))
318
304
  pulls.push(resultPromise)
319
305
  }
320
306
  if (!stdout.includes('selenoid/chrome')) {
321
307
  output.debug('Pulling selenoid/chrome...')
322
- resultPromise = exec('docker pull selenoid/chrome:latest').then(() =>
323
- output.debug('Pulled in selenoid/video-recorder'),
324
- )
308
+ resultPromise = exec('docker pull selenoid/chrome:latest').then(() => output.debug('Pulled in selenoid/video-recorder'))
325
309
  pulls.push(resultPromise)
326
310
  }
327
311
  if (!stdout.includes('selenoid/firefox')) {
@@ -341,16 +325,12 @@ function createAndStart(autoCreate) {
341
325
  }
342
326
 
343
327
  function deletePassedTests(passedTests) {
344
- const deleteVideoPromiseList = passedTests
345
- .map(clearString)
346
- .map((test) => axios.delete(`${seleniumUrl}/video/${test}.mp4`))
347
- const deleteLogPromiseList = passedTests
348
- .map(clearString)
349
- .map((test) => axios.delete(`${seleniumUrl}/logs/${test}.log`))
328
+ const deleteVideoPromiseList = passedTests.map(clearString).map(test => axios.delete(`${seleniumUrl}/video/${test}.mp4`))
329
+ const deleteLogPromiseList = passedTests.map(clearString).map(test => axios.delete(`${seleniumUrl}/logs/${test}.log`))
350
330
 
351
331
  return Promise.all(deleteVideoPromiseList.concat(deleteLogPromiseList))
352
332
  .then(() => output.debug('Deleted videos and logs for all passed tests'))
353
- .catch((err) => output.error(`Error while deleting video and log files ${err.stack}`))
333
+ .catch(err => output.error(`Error while deleting video and log files ${err.stack}`))
354
334
  }
355
335
 
356
336
  function setOptionsForWebdriver(config) {
@@ -4,6 +4,7 @@ const figures = require('figures')
4
4
  const fs = require('fs')
5
5
  const mkdirp = require('mkdirp')
6
6
  const path = require('path')
7
+ const cheerio = require('cheerio')
7
8
 
8
9
  const Container = require('../container')
9
10
  const recorder = require('../recorder')
@@ -88,11 +89,11 @@ module.exports = function (config) {
88
89
  const pad = '0000'
89
90
  const reportDir = config.output ? path.resolve(global.codecept_dir, config.output) : defaultConfig.output
90
91
 
91
- event.dispatcher.on(event.suite.before, (suite) => {
92
+ event.dispatcher.on(event.suite.before, suite => {
92
93
  stepNum = -1
93
94
  })
94
95
 
95
- event.dispatcher.on(event.test.before, (test) => {
96
+ event.dispatcher.on(event.test.before, test => {
96
97
  const sha256hash = crypto
97
98
  .createHash('sha256')
98
99
  .update(test.file + test.title)
@@ -106,15 +107,15 @@ module.exports = function (config) {
106
107
  currentTest = test
107
108
  })
108
109
 
109
- event.dispatcher.on(event.step.failed, (step) => {
110
+ event.dispatcher.on(event.step.failed, step => {
110
111
  recorder.add('screenshot of failed test', async () => persistStep(step), true)
111
112
  })
112
113
 
113
- event.dispatcher.on(event.step.after, (step) => {
114
+ event.dispatcher.on(event.step.after, step => {
114
115
  recorder.add('screenshot of step of test', async () => persistStep(step), true)
115
116
  })
116
117
 
117
- event.dispatcher.on(event.test.passed, (test) => {
118
+ event.dispatcher.on(event.test.passed, test => {
118
119
  if (!config.deleteSuccessful) return persist(test)
119
120
  // cleanup
120
121
  deleteDir(dir)
@@ -122,10 +123,7 @@ module.exports = function (config) {
122
123
 
123
124
  event.dispatcher.on(event.test.failed, (test, err) => {
124
125
  if (test.ctx._runnable.title.includes('hook: ')) {
125
- output.plugin(
126
- 'stepByStepReport',
127
- 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.',
128
- )
126
+ output.plugin('stepByStepReport', 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.')
129
127
  return
130
128
  }
131
129
  persist(test, err)
@@ -133,7 +131,49 @@ module.exports = function (config) {
133
131
 
134
132
  event.dispatcher.on(event.all.result, () => {
135
133
  if (Object.keys(recordedTests).length === 0 || !Object.keys(slides).length) return
134
+ generateRecordsHtml(recordedTests)
135
+ })
136
+
137
+ event.dispatcher.on(event.workers.result, async () => {
138
+ await recorder.add(() => {
139
+ const recordedTests = getRecordFoldersWithDetails(reportDir)
140
+ generateRecordsHtml(recordedTests)
141
+ })
142
+ })
136
143
 
144
+ function getRecordFoldersWithDetails(dirPath) {
145
+ let results = {}
146
+
147
+ try {
148
+ const items = fs.readdirSync(dirPath, { withFileTypes: true })
149
+
150
+ items.forEach(item => {
151
+ if (item.isDirectory() && item.name.startsWith('record_')) {
152
+ const recordFolderPath = path.join(dirPath, item.name)
153
+ const indexPath = path.join(recordFolderPath, 'index.html')
154
+
155
+ let name = ''
156
+ if (fs.existsSync(indexPath)) {
157
+ try {
158
+ const htmlContent = fs.readFileSync(indexPath, 'utf-8')
159
+ const $ = cheerio.load(htmlContent)
160
+ name = $('.navbar-brand').text().trim()
161
+ } catch (err) {
162
+ console.error(`Error reading index.html in ${recordFolderPath}:`, err.message)
163
+ }
164
+ }
165
+
166
+ results[name || 'Unkown'] = `${item.name}/index.html`
167
+ }
168
+ })
169
+ } catch (err) {
170
+ console.error(`Error reading directory ${dirPath}:`, err.message)
171
+ }
172
+
173
+ return results
174
+ }
175
+
176
+ function generateRecordsHtml(recordedTests) {
137
177
  let links = ''
138
178
 
139
179
  for (const link in recordedTests) {
@@ -147,10 +187,8 @@ module.exports = function (config) {
147
187
 
148
188
  fs.writeFileSync(path.join(reportDir, 'records.html'), indexHTML)
149
189
 
150
- output.print(
151
- `${figures.circleFilled} Step-by-step preview: ${colors.white.bold(`file://${reportDir}/records.html`)}`,
152
- )
153
- })
190
+ output.print(`${figures.circleFilled} Step-by-step preview: ${colors.white.bold(`file://${reportDir}/records.html`)}`)
191
+ }
154
192
 
155
193
  async function persistStep(step) {
156
194
  if (stepNum === -1) return // Ignore steps from BeforeSuite function
@@ -61,12 +61,12 @@ const defaultConfig = {
61
61
  * ```
62
62
  *
63
63
  */
64
- module.exports = (config) => {
64
+ module.exports = config => {
65
65
  config = Object.assign(defaultConfig, config)
66
66
  // below override rule makes sure customTimeoutSteps go first but then they override noTimeoutSteps in case of exact pattern match
67
67
  config.customTimeoutSteps = config.customTimeoutSteps.concat(config.noTimeoutSteps).concat(config.customTimeoutSteps)
68
68
 
69
- event.dispatcher.on(event.step.before, (step) => {
69
+ event.dispatcher.on(event.step.before, step => {
70
70
  let stepTimeout
71
71
  for (let stepRule of config.customTimeoutSteps) {
72
72
  let customTimeout = 0
@@ -74,19 +74,12 @@ module.exports = (config) => {
74
74
  if (stepRule.length > 1) customTimeout = stepRule[1]
75
75
  stepRule = stepRule[0]
76
76
  }
77
- if (
78
- stepRule instanceof RegExp
79
- ? step.name.match(stepRule)
80
- : step.name === stepRule || (stepRule.indexOf('*') && step.name.startsWith(stepRule.slice(0, -1)))
81
- ) {
77
+ if (stepRule instanceof RegExp ? step.name.match(stepRule) : step.name === stepRule || (stepRule.indexOf('*') && step.name.startsWith(stepRule.slice(0, -1)))) {
82
78
  stepTimeout = customTimeout
83
79
  break
84
80
  }
85
81
  }
86
82
  stepTimeout = stepTimeout === undefined ? config.timeout : stepTimeout
87
- step.setTimeout(
88
- stepTimeout * 1000,
89
- config.overrideStepLimits ? TIMEOUT_ORDER.stepTimeoutHard : TIMEOUT_ORDER.stepTimeoutSoft,
90
- )
83
+ step.setTimeout(stepTimeout * 1000, config.overrideStepLimits ? TIMEOUT_ORDER.stepTimeoutHard : TIMEOUT_ORDER.stepTimeoutSoft)
91
84
  })
92
85
  }
@@ -29,12 +29,12 @@ let testStartedAt
29
29
  * ```
30
30
  */
31
31
  module.exports = function () {
32
- event.dispatcher.on(event.test.before, (_) => {
32
+ event.dispatcher.on(event.test.before, _ => {
33
33
  testStartedAt = Date.now()
34
34
  steps = {}
35
35
  })
36
36
 
37
- event.dispatcher.on(event.step.started, (step) => {
37
+ event.dispatcher.on(event.step.started, step => {
38
38
  const stepStartedAt = Date.now()
39
39
  step.id = uuidv4()
40
40
 
@@ -50,13 +50,13 @@ module.exports = function () {
50
50
  }
51
51
  })
52
52
 
53
- event.dispatcher.on(event.step.finished, (step) => {
53
+ event.dispatcher.on(event.step.finished, step => {
54
54
  if (step && step.id && steps[step.id]) {
55
55
  steps[step.id].end = formatTimestamp(Date.now() - testStartedAt)
56
56
  }
57
57
  })
58
58
 
59
- event.dispatcher.on(event.test.after, async (test) => {
59
+ event.dispatcher.on(event.test.after, async test => {
60
60
  if (test && test.artifacts && test.artifacts.video) {
61
61
  const stepsSortedByStartTime = Object.values(steps)
62
62
  stepsSortedByStartTime.sort((stepA, stepB) => {
@@ -92,7 +92,7 @@ function tryTo(callback) {
92
92
  recorder.session.restore('tryTo')
93
93
  return result
94
94
  })
95
- recorder.session.catch((err) => {
95
+ recorder.session.catch(err => {
96
96
  result = false
97
97
  const msg = err.inspect ? err.inspect() : err.toString()
98
98
  debug(`Unsuccessful try > ${msg}`)
@@ -81,7 +81,7 @@ let restartsSession
81
81
  * * ... - additional configuration passed into services.
82
82
  *
83
83
  */
84
- module.exports = (config) => {
84
+ module.exports = config => {
85
85
  // Keep initial configs to pass as options to wdio services
86
86
  const wdioOptions = { ...config }
87
87
  const webDriver = container.helpers('WebDriver')
@@ -116,9 +116,7 @@ module.exports = (config) => {
116
116
  continue
117
117
  }
118
118
 
119
- throw new Error(
120
- `Couldn't initialize service ${name} from wdio plugin config.\nIt should be available either in '@wdio/${name.toLowerCase()}-service' package`,
121
- )
119
+ throw new Error(`Couldn't initialize service ${name} from wdio plugin config.\nIt should be available either in '@wdio/${name.toLowerCase()}-service' package`)
122
120
  }
123
121
 
124
122
  debug(`services ${services}, launchers ${launchers}`)
@@ -144,7 +142,7 @@ module.exports = (config) => {
144
142
  }
145
143
 
146
144
  if (service.afterSession) {
147
- event.dispatcher.on(event.all.result, (result) => {
145
+ event.dispatcher.on(event.all.result, result => {
148
146
  recorder.add(`service ${name} all.after`, async () => {
149
147
  await service.afterSession(result)
150
148
  })
@@ -152,21 +150,21 @@ module.exports = (config) => {
152
150
  }
153
151
 
154
152
  if (service.beforeSuite) {
155
- event.dispatcher.on(event.suite.before, (suite) => {
153
+ event.dispatcher.on(event.suite.before, suite => {
156
154
  debug(`suite started: ${suite.title}`)
157
155
  recorder.add(`service ${name} suite.before`, () => service.beforeSuite(suite))
158
156
  })
159
157
  }
160
158
 
161
159
  if (service.afterSuite) {
162
- event.dispatcher.on(event.suite.after, (suite) => {
160
+ event.dispatcher.on(event.suite.after, suite => {
163
161
  debug(`suite finished: ${suite.title}`)
164
162
  recorder.add(`service ${name} suite.after`, () => service.afterSuite(suite))
165
163
  })
166
164
  }
167
165
 
168
166
  if (service.beforeTest) {
169
- event.dispatcher.on(event.test.started, async (test) => {
167
+ event.dispatcher.on(event.test.started, async test => {
170
168
  if (test.parent) {
171
169
  test.parent.toString = () => test.parent.title
172
170
  }
@@ -181,7 +179,7 @@ module.exports = (config) => {
181
179
  }
182
180
 
183
181
  if (service.afterTest) {
184
- event.dispatcher.on(event.test.finished, async (test) => {
182
+ event.dispatcher.on(event.test.finished, async test => {
185
183
  debug(`test finished: ${test.title}`)
186
184
  await service.afterTest(test)
187
185
  })
@@ -206,7 +204,7 @@ module.exports = (config) => {
206
204
  }
207
205
 
208
206
  if (!restartsSession && service.after) {
209
- event.dispatcher.on(event.all.result, (result) => service.after(result))
207
+ event.dispatcher.on(event.all.result, result => service.after(result))
210
208
  }
211
209
  }
212
210