codeceptjs 3.6.7 → 4.0.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 (149) hide show
  1. package/bin/codecept.js +81 -84
  2. package/lib/actor.js +13 -13
  3. package/lib/ai.js +13 -10
  4. package/lib/assert/empty.js +21 -20
  5. package/lib/assert/equal.js +39 -37
  6. package/lib/assert/error.js +14 -14
  7. package/lib/assert/include.js +47 -46
  8. package/lib/assert/throws.js +11 -13
  9. package/lib/assert/truth.js +22 -19
  10. package/lib/assert.js +2 -4
  11. package/lib/cli.js +49 -57
  12. package/lib/codecept.js +155 -142
  13. package/lib/colorUtils.js +3 -3
  14. package/lib/command/configMigrate.js +52 -58
  15. package/lib/command/definitions.js +89 -88
  16. package/lib/command/dryRun.js +68 -71
  17. package/lib/command/generate.js +188 -197
  18. package/lib/command/gherkin/init.js +16 -27
  19. package/lib/command/gherkin/snippets.js +20 -20
  20. package/lib/command/gherkin/steps.js +8 -8
  21. package/lib/command/info.js +38 -40
  22. package/lib/command/init.js +288 -290
  23. package/lib/command/interactive.js +32 -32
  24. package/lib/command/list.js +26 -26
  25. package/lib/command/run-multiple/chunk.js +5 -5
  26. package/lib/command/run-multiple/collection.js +3 -3
  27. package/lib/command/run-multiple/run.js +2 -6
  28. package/lib/command/run-multiple.js +93 -113
  29. package/lib/command/run-rerun.js +25 -20
  30. package/lib/command/run-workers.js +66 -64
  31. package/lib/command/run.js +29 -26
  32. package/lib/command/utils.js +65 -80
  33. package/lib/command/workers/runTests.js +10 -10
  34. package/lib/config.js +9 -10
  35. package/lib/container.js +48 -40
  36. package/lib/data/context.js +59 -60
  37. package/lib/data/dataScenarioConfig.js +47 -47
  38. package/lib/data/dataTableArgument.js +29 -29
  39. package/lib/data/table.js +20 -26
  40. package/lib/dirname.js +5 -0
  41. package/lib/event.js +167 -163
  42. package/lib/heal.js +17 -13
  43. package/lib/helper/AI.js +41 -130
  44. package/lib/helper/ApiDataFactory.js +69 -73
  45. package/lib/helper/Appium.js +381 -412
  46. package/lib/helper/Expect.js +425 -0
  47. package/lib/helper/ExpectHelper.js +48 -40
  48. package/lib/helper/FileSystem.js +79 -80
  49. package/lib/helper/GraphQL.js +43 -44
  50. package/lib/helper/GraphQLDataFactory.js +50 -50
  51. package/lib/helper/JSONResponse.js +62 -65
  52. package/lib/helper/Mochawesome.js +28 -28
  53. package/lib/helper/MockServer.js +14 -12
  54. package/lib/helper/Nightmare.js +566 -662
  55. package/lib/helper/Playwright.js +1216 -1361
  56. package/lib/helper/Protractor.js +627 -663
  57. package/lib/helper/Puppeteer.js +1128 -1231
  58. package/lib/helper/REST.js +68 -159
  59. package/lib/helper/SoftExpectHelper.js +2 -2
  60. package/lib/helper/TestCafe.js +484 -490
  61. package/lib/helper/WebDriver.js +1156 -1297
  62. package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
  63. package/lib/helper/errors/ConnectionRefused.js +1 -1
  64. package/lib/helper/errors/ElementAssertion.js +2 -2
  65. package/lib/helper/errors/ElementNotFound.js +2 -2
  66. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
  67. package/lib/helper/extras/Console.js +1 -1
  68. package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +18 -21
  71. package/lib/helper/extras/Popup.js +1 -1
  72. package/lib/helper/extras/React.js +3 -3
  73. package/lib/helper/network/actions.js +7 -14
  74. package/lib/helper/network/utils.js +2 -3
  75. package/lib/helper/scripts/blurElement.js +1 -1
  76. package/lib/helper/scripts/focusElement.js +1 -1
  77. package/lib/helper/scripts/highlightElement.js +1 -1
  78. package/lib/helper/scripts/isElementClickable.js +1 -1
  79. package/lib/helper/testcafe/testControllerHolder.js +1 -1
  80. package/lib/helper/testcafe/testcafe-utils.js +7 -6
  81. package/lib/helper.js +3 -1
  82. package/lib/history.js +5 -6
  83. package/lib/hooks.js +6 -6
  84. package/lib/html.js +7 -7
  85. package/lib/index.js +41 -25
  86. package/lib/interfaces/bdd.js +64 -47
  87. package/lib/interfaces/featureConfig.js +19 -19
  88. package/lib/interfaces/gherkin.js +118 -124
  89. package/lib/interfaces/scenarioConfig.js +29 -29
  90. package/lib/listener/artifacts.js +9 -9
  91. package/lib/listener/config.js +24 -24
  92. package/lib/listener/exit.js +12 -12
  93. package/lib/listener/helpers.js +42 -42
  94. package/lib/listener/mocha.js +11 -11
  95. package/lib/listener/retry.js +30 -32
  96. package/lib/listener/steps.js +53 -50
  97. package/lib/listener/timeout.js +54 -54
  98. package/lib/locator.js +10 -6
  99. package/lib/mochaFactory.js +15 -18
  100. package/lib/output.js +10 -6
  101. package/lib/parser.js +12 -15
  102. package/lib/pause.js +33 -40
  103. package/lib/plugin/allure.js +15 -15
  104. package/lib/plugin/autoDelay.js +37 -29
  105. package/lib/plugin/autoLogin.js +65 -70
  106. package/lib/plugin/commentStep.js +18 -18
  107. package/lib/plugin/coverage.js +67 -115
  108. package/lib/plugin/customLocator.js +20 -21
  109. package/lib/plugin/debugErrors.js +24 -24
  110. package/lib/plugin/eachElement.js +38 -38
  111. package/lib/plugin/fakerTransform.js +6 -6
  112. package/lib/plugin/heal.js +108 -67
  113. package/lib/plugin/pauseOnFail.js +11 -11
  114. package/lib/plugin/retryFailedStep.js +39 -32
  115. package/lib/plugin/retryTo.js +40 -46
  116. package/lib/plugin/screenshotOnFail.js +87 -109
  117. package/lib/plugin/selenoid.js +118 -131
  118. package/lib/plugin/standardActingHelpers.js +8 -2
  119. package/lib/plugin/stepByStepReport.js +91 -110
  120. package/lib/plugin/stepTimeout.js +23 -24
  121. package/lib/plugin/subtitles.js +35 -34
  122. package/lib/plugin/tryTo.js +30 -40
  123. package/lib/plugin/wdio.js +75 -78
  124. package/lib/recorder.js +17 -14
  125. package/lib/rerun.js +10 -11
  126. package/lib/scenario.js +23 -25
  127. package/lib/secret.js +2 -4
  128. package/lib/session.js +10 -10
  129. package/lib/step.js +9 -12
  130. package/lib/store.js +3 -2
  131. package/lib/transform.js +1 -1
  132. package/lib/translation.js +8 -7
  133. package/lib/ui.js +14 -12
  134. package/lib/utils.js +72 -70
  135. package/lib/within.js +10 -10
  136. package/lib/workerStorage.js +25 -27
  137. package/lib/workers.js +32 -29
  138. package/package.json +53 -51
  139. package/translations/de-DE.js +1 -1
  140. package/translations/fr-FR.js +1 -1
  141. package/translations/index.js +13 -9
  142. package/translations/it-IT.js +1 -1
  143. package/translations/ja-JP.js +1 -1
  144. package/translations/pl-PL.js +1 -1
  145. package/translations/pt-BR.js +1 -1
  146. package/translations/ru-RU.js +1 -1
  147. package/translations/zh-CN.js +1 -1
  148. package/translations/zh-TW.js +1 -1
  149. package/typings/index.d.ts +65 -415
@@ -1,17 +1,15 @@
1
- const colors = require('chalk')
2
- const crypto = require('crypto')
3
- const figures = require('figures')
4
- const fs = require('fs')
5
- const mkdirp = require('mkdirp')
6
- const path = require('path')
7
-
8
- const Container = require('../container')
9
- const recorder = require('../recorder')
10
- const event = require('../event')
11
- const output = require('../output')
12
- const { template, deleteDir } = require('../utils')
13
-
14
- const supportedHelpers = require('./standardActingHelpers')
1
+ import colors from 'chalk';
2
+ import crypto from 'crypto';
3
+ import figures from 'figures';
4
+ import fs from 'fs';
5
+ import mkdirp from 'mkdirp';
6
+ import path from 'path';
7
+ import Container from '../container.js';
8
+ import recorder from '../recorder.js';
9
+ import * as event from '../event.js';
10
+ import * as output from '../output.js';
11
+ import { template, deleteDir } from '../utils.js';
12
+ import supportedHelpers from './standardActingHelpers.js';
15
13
 
16
14
  const defaultConfig = {
17
15
  deleteSuccessful: true,
@@ -21,9 +19,9 @@ const defaultConfig = {
21
19
  output: global.output_dir,
22
20
  screenshotsForAllureReport: false,
23
21
  disableScreenshotOnFail: true,
24
- }
22
+ };
25
23
 
26
- const templates = {}
24
+ const templates = {};
27
25
 
28
26
  /**
29
27
  * ![step-by-step-report](https://codecept.io/img/codeceptjs-slideshow.gif)
@@ -62,152 +60,135 @@ const templates = {}
62
60
  * @param {*} config
63
61
  */
64
62
 
65
- module.exports = function (config) {
66
- const helpers = Container.helpers()
67
- let helper
63
+ export default function (config) {
64
+ const helpers = Container.helpers();
65
+ let helper;
68
66
 
69
- config = Object.assign(defaultConfig, config)
67
+ config = Object.assign(defaultConfig, config);
70
68
 
71
69
  for (const helperName of supportedHelpers) {
72
70
  if (Object.keys(helpers).indexOf(helperName) > -1) {
73
- helper = helpers[helperName]
71
+ helper = helpers[helperName];
74
72
  }
75
73
  }
76
74
 
77
- if (!helper) return // no helpers for screenshot
78
-
79
- let dir
80
- let stepNum
81
- let slides = {}
82
- let error
83
- let savedStep = null
84
- let currentTest = null
85
- let scenarioFailed = false
75
+ if (!helper) return; // no helpers for screenshot
86
76
 
87
- const recordedTests = {}
88
- const pad = '0000'
89
- const reportDir = config.output ? path.resolve(global.codecept_dir, config.output) : defaultConfig.output
77
+ let dir;
78
+ let stepNum;
79
+ let slides = {};
80
+ let error;
81
+ let savedStep = null;
82
+ let currentTest = null;
83
+ let scenarioFailed = false;
90
84
 
91
- event.dispatcher.on(event.suite.before, (suite) => {
92
- stepNum = -1
93
- })
85
+ const recordedTests = {};
86
+ const pad = '0000';
87
+ const reportDir = config.output ? path.resolve(global.codecept_dir, config.output) : defaultConfig.output;
94
88
 
95
89
  event.dispatcher.on(event.test.before, (test) => {
96
- const sha256hash = crypto
97
- .createHash('sha256')
98
- .update(test.file + test.title)
99
- .digest('hex')
100
- dir = path.join(reportDir, `record_${sha256hash}`)
101
- mkdirp.sync(dir)
102
- stepNum = 0
103
- error = null
104
- slides = {}
105
- savedStep = null
106
- currentTest = test
107
- })
90
+ const sha256hash = crypto.createHash('sha256').update(test.file + test.title).digest('hex');
91
+ dir = path.join(reportDir, `record_${sha256hash}`);
92
+ mkdirp.sync(dir);
93
+ stepNum = 0;
94
+ error = null;
95
+ slides = {};
96
+ savedStep = null;
97
+ currentTest = test;
98
+ });
108
99
 
109
100
  event.dispatcher.on(event.step.failed, (step) => {
110
- recorder.add('screenshot of failed test', async () => persistStep(step), true)
111
- })
101
+ recorder.add('screenshot of failed test', async () => persistStep(step), true);
102
+ });
112
103
 
113
- event.dispatcher.on(event.step.after, (step) => {
114
- recorder.add('screenshot of step of test', async () => persistStep(step), true)
115
- })
104
+ event.dispatcher.on(event.step.after, persistStep);
116
105
 
117
106
  event.dispatcher.on(event.test.passed, (test) => {
118
- if (!config.deleteSuccessful) return persist(test)
107
+ if (!config.deleteSuccessful) return persist(test);
119
108
  // cleanup
120
- deleteDir(dir)
121
- })
109
+ deleteDir(dir);
110
+ });
122
111
 
123
112
  event.dispatcher.on(event.test.failed, (test, err) => {
124
113
  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
- )
129
- return
114
+ output.output.plugin('stepByStepReport', 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.');
115
+ return;
130
116
  }
131
- persist(test, err)
132
- })
117
+ });
133
118
 
134
119
  event.dispatcher.on(event.all.result, () => {
135
- if (Object.keys(recordedTests).length === 0 || !Object.keys(slides).length) return
120
+ if (!Object.keys(slides).length) return;
136
121
 
137
- let links = ''
122
+ let links = '';
138
123
 
139
124
  for (const link in recordedTests) {
140
- links += `<li><a href="${recordedTests[link]}">${link}</a></li>\n`
125
+ links += `<li><a href="${recordedTests[link]}">${link}</a></li>\n`;
141
126
  }
142
127
 
143
128
  const indexHTML = template(templates.index, {
144
129
  time: Date().toString(),
145
130
  records: links,
146
- })
131
+ });
147
132
 
148
- fs.writeFileSync(path.join(reportDir, 'records.html'), indexHTML)
133
+ fs.writeFileSync(path.join(reportDir, 'records.html'), indexHTML);
149
134
 
150
- output.print(
151
- `${figures.circleFilled} Step-by-step preview: ${colors.white.bold(`file://${reportDir}/records.html`)}`,
152
- )
153
- })
135
+ output.print(`${figures.circleFilled} Step-by-step preview: ${colors.white.bold(`file://${reportDir}/records.html`)}`);
136
+ });
154
137
 
155
138
  async function persistStep(step) {
156
- if (stepNum === -1) return // Ignore steps from BeforeSuite function
157
- if (isStepIgnored(step)) return
158
- if (savedStep === step) return // already saved
139
+ if (isStepIgnored(step)) return;
140
+ if (savedStep === step) return; // already saved
159
141
  // Ignore steps from BeforeSuite function
160
- if (scenarioFailed && config.disableScreenshotOnFail) return
161
- if (step.metaStep && step.metaStep.name === 'BeforeSuite') return
162
- if (!step.test) return // Ignore steps from AfterSuite
142
+ if (scenarioFailed && config.disableScreenshotOnFail) return;
143
+ if (step.metaStep && step.metaStep.name === 'BeforeSuite') return;
163
144
 
164
- const fileName = `${pad.substring(0, pad.length - stepNum.toString().length) + stepNum.toString()}.png`
145
+ const fileName = `${pad.substring(0, pad.length - stepNum.toString().length) + stepNum.toString()}.png`;
165
146
  if (step.status === 'failed') {
166
- scenarioFailed = true
147
+ scenarioFailed = true;
167
148
  }
168
- stepNum++
169
- slides[fileName] = step
149
+ stepNum++;
150
+ slides[fileName] = step;
170
151
  try {
171
- await helper.saveScreenshot(path.join(dir, fileName), config.fullPageScreenshots)
152
+ await helper.saveScreenshot(path.relative(reportDir, path.join(dir, fileName)), config.fullPageScreenshots);
172
153
  } catch (err) {
173
- output.plugin(`Can't save step screenshot: ${err}`)
174
- error = err
175
- return
154
+ output.output.plugin(`Can't save step screenshot: ${err}`);
155
+ error = err;
156
+ return;
176
157
  } finally {
177
- savedStep = step
158
+ savedStep = step;
178
159
  }
179
160
 
180
- if (!currentTest.artifacts.screenshots) currentTest.artifacts.screenshots = []
161
+ if (!currentTest.artifacts.screenshots) currentTest.artifacts.screenshots = [];
181
162
  // added attachments to test
182
- currentTest.artifacts.screenshots.push(path.join(dir, fileName))
163
+ currentTest.artifacts.screenshots.push(path.join(dir, fileName));
183
164
 
184
- const allureReporter = Container.plugins('allure')
165
+ const allureReporter = Container.plugins('allure');
185
166
  if (allureReporter && config.screenshotsForAllureReport) {
186
- output.plugin('stepByStepReport', 'Adding screenshot to Allure')
187
- allureReporter.addAttachment(`Screenshot of step ${step}`, fs.readFileSync(path.join(dir, fileName)), 'image/png')
167
+ output.output.plugin('stepByStepReport', 'Adding screenshot to Allure');
168
+ allureReporter.addAttachment(`Screenshot of step ${step}`, fs.readFileSync(path.join(dir, fileName)), 'image/png');
188
169
  }
189
170
  }
190
171
 
191
172
  function persist(test) {
192
- if (error) return
173
+ if (error) return;
193
174
 
194
- let indicatorHtml = ''
195
- let slideHtml = ''
175
+ let indicatorHtml = '';
176
+ let slideHtml = '';
196
177
 
197
178
  for (const i in slides) {
198
- const step = slides[i]
199
- const stepNum = parseInt(i, 10)
179
+ const step = slides[i];
180
+ const stepNum = parseInt(i, 10);
200
181
  indicatorHtml += template(templates.indicator, {
201
182
  step: stepNum,
202
183
  isActive: stepNum ? '' : 'class="active"',
203
- })
184
+ });
204
185
 
205
186
  slideHtml += template(templates.slides, {
206
187
  image: i,
207
188
  caption: step.toString().replace(/\[\d{2}m/g, ''), // remove ANSI escape sequence
208
189
  isActive: stepNum ? '' : 'active',
209
190
  isError: step.status === 'failed' ? 'error' : '',
210
- })
191
+ });
211
192
  }
212
193
 
213
194
  const html = template(templates.global, {
@@ -216,19 +197,19 @@ module.exports = function (config) {
216
197
  feature: test.parent && test.parent.title,
217
198
  test: test.title,
218
199
  carousel_class: config.animateSlides ? ' slide' : '',
219
- })
200
+ });
220
201
 
221
- const index = path.join(dir, 'index.html')
222
- fs.writeFileSync(index, html)
223
- recordedTests[`${test.parent.title}: ${test.title}`] = path.relative(reportDir, index)
202
+ const index = path.join(dir, 'index.html');
203
+ fs.writeFileSync(index, html);
204
+ recordedTests[`${test.parent.title}: ${test.title}`] = path.relative(reportDir, index);
224
205
  }
225
206
 
226
207
  function isStepIgnored(step) {
227
- if (!config.ignoreSteps) return
208
+ if (!config.ignoreSteps) return;
228
209
  for (const pattern of config.ignoreSteps || []) {
229
- if (step.name.match(pattern)) return true
210
+ if (step.name.match(pattern)) return true;
230
211
  }
231
- return false
212
+ return false;
232
213
  }
233
214
  }
234
215
 
@@ -242,11 +223,11 @@ templates.slides = `
242
223
  <small>scroll up and down to see the full page</small>
243
224
  </div>
244
225
  </div>
245
- `
226
+ `;
246
227
 
247
228
  templates.indicator = `
248
229
  <li data-target="#steps" data-slide-to="{{step}}" {{isActive}}></li>
249
- `
230
+ `;
250
231
 
251
232
  templates.index = `
252
233
  <!DOCTYPE html>
@@ -275,7 +256,7 @@ templates.index = `
275
256
 
276
257
  </body>
277
258
  </html>
278
- `
259
+ `;
279
260
 
280
261
  templates.global = `
281
262
  <!DOCTYPE html>
@@ -385,4 +366,4 @@ templates.global = `
385
366
  </body>
386
367
 
387
368
  </html>
388
- `
369
+ `;
@@ -1,12 +1,15 @@
1
- const event = require('../event')
2
- const TIMEOUT_ORDER = require('../step').TIMEOUT_ORDER
1
+ import * as event from '../event.js';
2
+ import { Step } from '../step.js';
3
3
 
4
4
  const defaultConfig = {
5
5
  timeout: 150,
6
6
  overrideStepLimits: false,
7
- noTimeoutSteps: ['amOnPage', 'wait*'],
7
+ noTimeoutSteps: [
8
+ 'amOnPage',
9
+ 'wait*',
10
+ ],
8
11
  customTimeoutSteps: [],
9
- }
12
+ };
10
13
 
11
14
  /**
12
15
  * Set timeout for test steps globally.
@@ -61,32 +64,28 @@ const defaultConfig = {
61
64
  * ```
62
65
  *
63
66
  */
64
- module.exports = (config) => {
65
- config = Object.assign(defaultConfig, config)
67
+ export default (config) => {
68
+ config = Object.assign(defaultConfig, config);
66
69
  // below override rule makes sure customTimeoutSteps go first but then they override noTimeoutSteps in case of exact pattern match
67
- config.customTimeoutSteps = config.customTimeoutSteps.concat(config.noTimeoutSteps).concat(config.customTimeoutSteps)
70
+ config.customTimeoutSteps = config.customTimeoutSteps.concat(config.noTimeoutSteps).concat(config.customTimeoutSteps);
68
71
 
69
72
  event.dispatcher.on(event.step.before, (step) => {
70
- let stepTimeout
73
+ let stepTimeout;
71
74
  for (let stepRule of config.customTimeoutSteps) {
72
- let customTimeout = 0
75
+ let customTimeout = 0;
73
76
  if (Array.isArray(stepRule)) {
74
- if (stepRule.length > 1) customTimeout = stepRule[1]
75
- stepRule = stepRule[0]
77
+ if (stepRule.length > 1) customTimeout = stepRule[1];
78
+ stepRule = stepRule[0];
76
79
  }
77
- if (
78
- stepRule instanceof RegExp
79
- ? step.name.match(stepRule)
80
- : step.name === stepRule || (stepRule.indexOf('*') && step.name.startsWith(stepRule.slice(0, -1)))
80
+ if (stepRule instanceof RegExp
81
+ ? step.name.match(stepRule)
82
+ : (step.name === stepRule || stepRule.indexOf('*') && step.name.startsWith(stepRule.slice(0, -1)))
81
83
  ) {
82
- stepTimeout = customTimeout
83
- break
84
+ stepTimeout = customTimeout;
85
+ break;
84
86
  }
85
87
  }
86
- stepTimeout = stepTimeout === undefined ? config.timeout : stepTimeout
87
- step.setTimeout(
88
- stepTimeout * 1000,
89
- config.overrideStepLimits ? TIMEOUT_ORDER.stepTimeoutHard : TIMEOUT_ORDER.stepTimeoutSoft,
90
- )
91
- })
92
- }
88
+ stepTimeout = stepTimeout === undefined ? config.timeout : stepTimeout;
89
+ step.setTimeout(stepTimeout * 1000, config.overrideStepLimits ? Step.TIMEOUT_ORDER.stepTimeoutHard : Step.TIMEOUT_ORDER.stepTimeoutSoft);
90
+ });
91
+ };
@@ -1,21 +1,22 @@
1
- const { v4: uuidv4 } = require('uuid')
2
- const fsPromise = require('fs').promises
3
- const path = require('path')
4
- const event = require('../event')
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { promises as fsPromise } from 'fs';
3
+ import path from 'path';
4
+ import * as event from '../event.js';
5
5
 
6
6
  // This will convert a given timestamp in milliseconds to
7
7
  // an SRT recognized timestamp, ie HH:mm:ss,SSS
8
8
  function formatTimestamp(timestampInMs) {
9
- const date = new Date(0, 0, 0, 0, 0, 0, timestampInMs)
10
- const hours = date.getHours()
11
- const minutes = date.getMinutes()
12
- const seconds = date.getSeconds()
13
- const ms = timestampInMs - (hours * 3600000 + minutes * 60000 + seconds * 1000)
14
- return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')},${ms.toString().padStart(3, '0')}`
9
+ const date = new Date(0, 0, 0, 0, 0, 0, timestampInMs);
10
+ const hours = date.getHours();
11
+ const minutes = date.getMinutes();
12
+ const seconds = date.getSeconds();
13
+ const ms = timestampInMs - (hours * 3600000 + minutes * 60000 + seconds * 1000);
14
+ return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')},${ms.toString().padStart(3, '0')}`;
15
15
  }
16
16
 
17
- let steps = {}
18
- let testStartedAt
17
+ let steps = {};
18
+ let testStartedAt;
19
+
19
20
  /**
20
21
  * Automatically captures steps as subtitle, and saves it as an artifact when a video is found for a failed test
21
22
  *
@@ -28,42 +29,42 @@ let testStartedAt
28
29
  * }
29
30
  * ```
30
31
  */
31
- module.exports = function () {
32
+ export default function () {
32
33
  event.dispatcher.on(event.test.before, (_) => {
33
- testStartedAt = Date.now()
34
- steps = {}
35
- })
34
+ testStartedAt = Date.now();
35
+ steps = {};
36
+ });
36
37
 
37
38
  event.dispatcher.on(event.step.started, (step) => {
38
- const stepStartedAt = Date.now()
39
- step.id = uuidv4()
39
+ const stepStartedAt = Date.now();
40
+ step.id = uuidv4();
40
41
 
41
- let title = `${step.actor}.${step.name}(${step.args ? step.args.join(',') : ''})`
42
+ let title = `${step.actor}.${step.name}(${step.args ? step.args.join(',') : ''})`;
42
43
  if (title.length > 100) {
43
- title = `${title.substring(0, 100)}...`
44
+ title = `${title.substring(0, 100)}...`;
44
45
  }
45
46
 
46
47
  steps[step.id] = {
47
48
  start: formatTimestamp(stepStartedAt - testStartedAt),
48
49
  startedAt: stepStartedAt,
49
50
  title,
50
- }
51
- })
51
+ };
52
+ });
52
53
 
53
54
  event.dispatcher.on(event.step.finished, (step) => {
54
55
  if (step && step.id && steps[step.id]) {
55
- steps[step.id].end = formatTimestamp(Date.now() - testStartedAt)
56
+ steps[step.id].end = formatTimestamp(Date.now() - testStartedAt);
56
57
  }
57
- })
58
+ });
58
59
 
59
60
  event.dispatcher.on(event.test.after, async (test) => {
60
61
  if (test && test.artifacts && test.artifacts.video) {
61
- const stepsSortedByStartTime = Object.values(steps)
62
+ const stepsSortedByStartTime = Object.values(steps);
62
63
  stepsSortedByStartTime.sort((stepA, stepB) => {
63
- return stepA.startedAt - stepB.startedAt
64
- })
64
+ return stepA.startedAt - stepB.startedAt;
65
+ });
65
66
 
66
- let subtitle = ''
67
+ let subtitle = '';
67
68
 
68
69
  // For an SRT file, every subtitle has to be in the format as mentioned below:
69
70
  //
@@ -76,13 +77,13 @@ module.exports = function () {
76
77
  ${step.start} --> ${step.end}
77
78
  ${step.title}
78
79
 
79
- `
80
+ `;
80
81
  }
81
- })
82
+ });
82
83
 
83
- const { dir: artifactsDirectory, name: fileName } = path.parse(test.artifacts.video)
84
- await fsPromise.writeFile(`${artifactsDirectory}/${fileName}.srt`, subtitle)
85
- test.artifacts.subtitle = `${artifactsDirectory}/${fileName}.srt`
84
+ const { dir: artifactsDirectory, name: fileName } = path.parse(test.artifacts.video);
85
+ await fsPromise.writeFile(`${artifactsDirectory}/${fileName}.srt`, subtitle);
86
+ test.artifacts.subtitle = `${artifactsDirectory}/${fileName}.srt`;
86
87
  }
87
- })
88
+ });
88
89
  }
@@ -1,9 +1,9 @@
1
- const recorder = require('../recorder')
2
- const { debug } = require('../output')
1
+ import recorder from '../recorder.js';
2
+ import * as output from '../output.js';
3
3
 
4
4
  const defaultConfig = {
5
5
  registerGlobal: true,
6
- }
6
+ };
7
7
 
8
8
  /**
9
9
  *
@@ -70,46 +70,36 @@ const defaultConfig = {
70
70
  * ```
71
71
  *
72
72
  */
73
- module.exports = function (config) {
74
- config = Object.assign(defaultConfig, config)
73
+ export default function (config) {
74
+ config = Object.assign(defaultConfig, config);
75
75
 
76
76
  if (config.registerGlobal) {
77
- global.tryTo = tryTo
77
+ global.tryTo = tryTo;
78
78
  }
79
- return tryTo
79
+ return tryTo;
80
80
  }
81
81
 
82
- function tryTo(callback) {
83
- let result = false
84
- return recorder.add(
85
- 'tryTo',
86
- () => {
87
- recorder.session.start('tryTo')
88
- process.env.TRY_TO = 'true'
89
- callback()
90
- recorder.add(() => {
91
- result = true
92
- recorder.session.restore('tryTo')
93
- return result
94
- })
95
- recorder.session.catch((err) => {
96
- result = false
97
- const msg = err.inspect ? err.inspect() : err.toString()
98
- debug(`Unsuccessful try > ${msg}`)
99
- recorder.session.restore('tryTo')
100
- return result
101
- })
102
- return recorder.add(
103
- 'result',
104
- () => {
105
- process.env.TRY_TO = undefined
106
- return result
107
- },
108
- true,
109
- false,
110
- )
111
- },
112
- false,
113
- false,
114
- )
82
+ export function tryTo(callback) {
83
+ let result = false;
84
+ return recorder.add('tryTo', () => {
85
+ recorder.session.start('tryTo');
86
+ process.env.TRY_TO = 'true';
87
+ callback();
88
+ recorder.add(() => {
89
+ result = true;
90
+ recorder.session.restore('tryTo');
91
+ return result;
92
+ });
93
+ recorder.session.catch((err) => {
94
+ result = false;
95
+ const msg = err.inspect ? err.inspect() : err.toString();
96
+ output.output.debug(`Unsuccessful try > ${msg}`);
97
+ recorder.session.restore('tryTo');
98
+ return result;
99
+ });
100
+ return recorder.add('result', () => {
101
+ process.env.TRY_TO = undefined;
102
+ return result;
103
+ }, true, false);
104
+ }, false, false);
115
105
  }