codeceptjs 3.7.0-beta.1 → 3.7.0-beta.10

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 (73) hide show
  1. package/README.md +9 -10
  2. package/bin/codecept.js +7 -0
  3. package/lib/actor.js +46 -92
  4. package/lib/ai.js +130 -121
  5. package/lib/codecept.js +2 -2
  6. package/lib/command/check.js +186 -0
  7. package/lib/command/definitions.js +3 -1
  8. package/lib/command/interactive.js +1 -1
  9. package/lib/command/run-workers.js +2 -54
  10. package/lib/command/workers/runTests.js +64 -225
  11. package/lib/container.js +27 -0
  12. package/lib/effects.js +218 -0
  13. package/lib/els.js +87 -106
  14. package/lib/event.js +18 -17
  15. package/lib/heal.js +10 -0
  16. package/lib/helper/AI.js +2 -1
  17. package/lib/helper/Appium.js +31 -22
  18. package/lib/helper/Playwright.js +22 -1
  19. package/lib/helper/Puppeteer.js +5 -0
  20. package/lib/helper/WebDriver.js +29 -8
  21. package/lib/listener/emptyRun.js +2 -5
  22. package/lib/listener/exit.js +5 -8
  23. package/lib/listener/globalTimeout.js +66 -10
  24. package/lib/listener/result.js +12 -0
  25. package/lib/listener/steps.js +3 -6
  26. package/lib/listener/store.js +9 -1
  27. package/lib/mocha/asyncWrapper.js +15 -3
  28. package/lib/mocha/cli.js +79 -28
  29. package/lib/mocha/featureConfig.js +13 -0
  30. package/lib/mocha/hooks.js +32 -3
  31. package/lib/mocha/inject.js +5 -0
  32. package/lib/mocha/scenarioConfig.js +11 -0
  33. package/lib/mocha/suite.js +27 -1
  34. package/lib/mocha/test.js +102 -3
  35. package/lib/mocha/types.d.ts +11 -0
  36. package/lib/output.js +75 -73
  37. package/lib/pause.js +3 -10
  38. package/lib/plugin/analyze.js +349 -0
  39. package/lib/plugin/autoDelay.js +2 -2
  40. package/lib/plugin/commentStep.js +5 -0
  41. package/lib/plugin/customReporter.js +52 -0
  42. package/lib/plugin/heal.js +30 -0
  43. package/lib/plugin/pageInfo.js +140 -0
  44. package/lib/plugin/retryTo.js +18 -118
  45. package/lib/plugin/screenshotOnFail.js +12 -17
  46. package/lib/plugin/standardActingHelpers.js +4 -1
  47. package/lib/plugin/stepByStepReport.js +6 -5
  48. package/lib/plugin/stepTimeout.js +1 -1
  49. package/lib/plugin/tryTo.js +17 -107
  50. package/lib/recorder.js +5 -5
  51. package/lib/rerun.js +43 -42
  52. package/lib/result.js +161 -0
  53. package/lib/step/base.js +228 -0
  54. package/lib/step/config.js +50 -0
  55. package/lib/step/func.js +46 -0
  56. package/lib/step/helper.js +50 -0
  57. package/lib/step/meta.js +99 -0
  58. package/lib/step/record.js +74 -0
  59. package/lib/step/retry.js +11 -0
  60. package/lib/step/section.js +55 -0
  61. package/lib/step.js +20 -347
  62. package/lib/steps.js +50 -0
  63. package/lib/store.js +4 -0
  64. package/lib/timeout.js +66 -0
  65. package/lib/utils.js +93 -0
  66. package/lib/within.js +2 -2
  67. package/lib/workers.js +29 -49
  68. package/package.json +23 -20
  69. package/typings/index.d.ts +5 -4
  70. package/typings/promiseBasedTypes.d.ts +617 -7
  71. package/typings/types.d.ts +663 -34
  72. package/lib/listener/artifacts.js +0 -19
  73. package/lib/plugin/debugErrors.js +0 -67
package/lib/codecept.js CHANGED
@@ -105,8 +105,8 @@ class Codecept {
105
105
  // default hooks
106
106
  runHook(require('./listener/store'))
107
107
  runHook(require('./listener/steps'))
108
- runHook(require('./listener/artifacts'))
109
108
  runHook(require('./listener/config'))
109
+ runHook(require('./listener/result'))
110
110
  runHook(require('./listener/helpers'))
111
111
  runHook(require('./listener/globalTimeout'))
112
112
  runHook(require('./listener/globalRetry'))
@@ -199,7 +199,7 @@ class Codecept {
199
199
  mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test)
200
200
  }
201
201
  const done = () => {
202
- event.emit(event.all.result, this)
202
+ event.emit(event.all.result, container.result())
203
203
  event.emit(event.all.after, this)
204
204
  resolve()
205
205
  }
@@ -0,0 +1,186 @@
1
+ const { getConfig, getTestRoot } = require('./utils')
2
+ const Codecept = require('../codecept')
3
+ const output = require('../output')
4
+ const store = require('../store')
5
+ const container = require('../container')
6
+ const figures = require('figures')
7
+ const chalk = require('chalk')
8
+ const { createTest } = require('../mocha/test')
9
+ const { getMachineInfo } = require('./info')
10
+ const definitions = require('./definitions')
11
+
12
+ module.exports = async function (options) {
13
+ const configFile = options.config
14
+
15
+ setTimeout(() => {
16
+ output.error("Something went wrong. Checks didn't pass and timed out. Please check your config and helpers.")
17
+ process.exit(1)
18
+ }, options.timeout || 50000)
19
+
20
+ const checks = {
21
+ config: false,
22
+ container: false,
23
+ pageObjects: false,
24
+ plugins: false,
25
+ ai: true, // we don't need to check AI
26
+ helpers: false,
27
+ setup: false,
28
+ tests: false,
29
+ def: false,
30
+ }
31
+
32
+ const testRoot = getTestRoot(configFile)
33
+ let config = getConfig(configFile)
34
+
35
+ try {
36
+ config = getConfig(configFile)
37
+ checks['config'] = true
38
+ } catch (err) {
39
+ checks['config'] = err
40
+ }
41
+
42
+ printCheck('config', checks['config'], config.name)
43
+
44
+ let codecept
45
+ try {
46
+ codecept = new Codecept(config, options)
47
+ codecept.init(testRoot)
48
+ await container.started()
49
+ checks.container = true
50
+ } catch (err) {
51
+ checks.container = err
52
+ }
53
+
54
+ const standardActingHelpers = container.STANDARD_ACTING_HELPERS
55
+
56
+ printCheck('container', checks['container'])
57
+
58
+ if (codecept) {
59
+ try {
60
+ if (options.bootstrap) await codecept.bootstrap()
61
+ checks.bootstrap = true
62
+ } catch (err) {
63
+ checks.bootstrap = err
64
+ }
65
+ printCheck('bootstrap', checks['bootstrap'], options.bootstrap ? 'Bootstrap was executed' : 'No bootstrap command')
66
+ }
67
+
68
+ let numTests = 0
69
+ if (codecept) {
70
+ try {
71
+ codecept.loadTests()
72
+ const mocha = container.mocha()
73
+ mocha.files = codecept.testFiles
74
+ mocha.loadFiles()
75
+ mocha.suite.suites.forEach(suite => {
76
+ numTests += suite.tests.length
77
+ })
78
+ if (numTests > 0) {
79
+ checks.tests = true
80
+ } else {
81
+ throw new Error('No tests found')
82
+ }
83
+ } catch (err) {
84
+ checks.tests = err
85
+ }
86
+ }
87
+
88
+ if (config?.ai?.request) {
89
+ checks.ai = true
90
+ printCheck('ai', checks['ai'], 'AI configuration is enabled, request function is set')
91
+ } else {
92
+ printCheck('ai', checks['ai'], 'AI is disabled')
93
+ }
94
+
95
+ printCheck('tests', checks['tests'], `Total: ${numTests} tests`)
96
+
97
+ store.dryRun = true
98
+
99
+ const helpers = container.helpers()
100
+
101
+ try {
102
+ if (!Object.keys(helpers).length) throw new Error('No helpers found')
103
+ // load helpers
104
+ for (const helper of Object.values(helpers)) {
105
+ if (helper._init) helper._init()
106
+ }
107
+ checks.helpers = true
108
+ } catch (err) {
109
+ checks.helpers = err
110
+ }
111
+
112
+ printCheck('helpers', checks['helpers'], `${Object.keys(helpers).join(', ')}`)
113
+
114
+ const pageObjects = container.support()
115
+
116
+ try {
117
+ if (Object.keys(pageObjects).length) {
118
+ for (const pageObject of Object.values(pageObjects)) {
119
+ pageObject.name
120
+ }
121
+ }
122
+ checks.pageObjects = true
123
+ } catch (err) {
124
+ checks.pageObjects = err
125
+ }
126
+ printCheck('page objects', checks['pageObjects'], `Total: ${Object.keys(pageObjects).length} support objects`)
127
+
128
+ checks.plugins = true // how to check plugins?
129
+ printCheck('plugins', checks['plugins'], Object.keys(container.plugins()).join(', '))
130
+
131
+ if (Object.keys(helpers).length) {
132
+ const suite = container.mocha().suite
133
+ const test = createTest('test', () => {})
134
+ try {
135
+ for (const helper of Object.values(helpers)) {
136
+ if (helper._beforeSuite) await helper._beforeSuite(suite)
137
+ if (helper._before) await helper._before(test)
138
+ if (helper._passed) await helper._passed(test)
139
+ if (helper._after) await helper._after(test)
140
+ if (helper._finishTest) await helper._finishTest(suite)
141
+ if (helper._afterSuite) await helper._afterSuite(suite)
142
+ }
143
+ checks.setup = true
144
+ } catch (err) {
145
+ checks.setup = err
146
+ }
147
+ }
148
+
149
+ printCheck('Helpers Before/After', checks['setup'], standardActingHelpers.some(h => Object.keys(helpers).includes(h)) ? 'Initializing and closing browser' : '')
150
+
151
+ try {
152
+ definitions(configFile, { dryRun: true })
153
+ checks.def = true
154
+ } catch (err) {
155
+ checks.def = err
156
+ }
157
+
158
+ printCheck('TypeScript Definitions', checks['def'])
159
+
160
+ output.print('')
161
+
162
+ if (!Object.values(checks).every(check => check === true)) {
163
+ output.error("Something went wrong. Checks didn't pass.")
164
+ output.print()
165
+ await getMachineInfo()
166
+ process.exit(1)
167
+ }
168
+
169
+ output.print(output.styles.success('All checks passed'.toUpperCase()), 'Ready to run your tests 🚀')
170
+ process.exit(0)
171
+ }
172
+
173
+ function printCheck(name, value, comment = '') {
174
+ let status = ''
175
+ if (value == true) {
176
+ status += chalk.bold.green(figures.tick)
177
+ } else {
178
+ status += chalk.bold.red(figures.cross)
179
+ }
180
+
181
+ if (value instanceof Error) {
182
+ comment = `${comment} ${chalk.red(value.message)}`.trim()
183
+ }
184
+
185
+ output.print(status, name.toUpperCase(), chalk.dim(comment))
186
+ }
@@ -5,7 +5,7 @@ const { getConfig, getTestRoot } = require('./utils')
5
5
  const Codecept = require('../codecept')
6
6
  const container = require('../container')
7
7
  const output = require('../output')
8
- const actingHelpers = [...require('../plugin/standardActingHelpers'), 'REST']
8
+ const actingHelpers = [...container.STANDARD_ACTING_HELPERS, 'REST']
9
9
 
10
10
  /**
11
11
  * Prepare data and generate content of definitions file
@@ -185,6 +185,8 @@ module.exports = function (genPath, options) {
185
185
  definitionsFileContent += `\n${translationAliases.join('\n')}`
186
186
  }
187
187
 
188
+ if (options.dryRun) return
189
+
188
190
  fs.writeFileSync(path.join(targetFolderPath, 'steps.d.ts'), definitionsFileContent)
189
191
  output.print('TypeScript Definitions provide autocompletion in Visual Studio Code and other IDEs')
190
192
  output.print('Definitions were generated in steps.d.ts')
@@ -4,7 +4,7 @@ const Codecept = require('../codecept')
4
4
  const Container = require('../container')
5
5
  const event = require('../event')
6
6
  const output = require('../output')
7
- const webHelpers = require('../plugin/standardActingHelpers')
7
+ const webHelpers = Container.STANDARD_ACTING_HELPERS
8
8
 
9
9
  module.exports = async function (path, options) {
10
10
  // Backward compatibility for --profile
@@ -8,12 +8,6 @@ const Workers = require('../workers')
8
8
  module.exports = async function (workerCount, selectedRuns, options) {
9
9
  process.env.profile = options.profile
10
10
 
11
- const suiteArr = []
12
- const passedTestArr = []
13
- const failedTestArr = []
14
- const skippedTestArr = []
15
- const stepArr = []
16
-
17
11
  const { config: testConfig, override = '' } = options
18
12
  const overrideConfigs = tryOrDefault(() => JSON.parse(override), {})
19
13
  const by = options.suites ? 'suite' : 'test'
@@ -30,69 +24,24 @@ module.exports = async function (workerCount, selectedRuns, options) {
30
24
  output.print(`CodeceptJS v${require('../codecept').version()} ${output.standWithUkraine()}`)
31
25
  output.print(`Running tests in ${output.styles.bold(numberOfWorkers)} workers...`)
32
26
  output.print()
27
+ store.hasWorkers = true
33
28
 
34
29
  const workers = new Workers(numberOfWorkers, config)
35
30
  workers.overrideConfig(overrideConfigs)
36
31
 
37
- workers.on(event.suite.before, suite => {
38
- suiteArr.push(suite)
39
- })
40
-
41
- workers.on(event.step.passed, step => {
42
- stepArr.push(step)
43
- })
44
-
45
- workers.on(event.step.failed, step => {
46
- stepArr.push(step)
47
- })
48
-
49
32
  workers.on(event.test.failed, test => {
50
- failedTestArr.push(test)
51
33
  output.test.failed(test)
52
34
  })
53
35
 
54
36
  workers.on(event.test.passed, test => {
55
- passedTestArr.push(test)
56
37
  output.test.passed(test)
57
38
  })
58
39
 
59
40
  workers.on(event.test.skipped, test => {
60
- skippedTestArr.push(test)
61
41
  output.test.skipped(test)
62
42
  })
63
43
 
64
- workers.on(event.all.result, () => {
65
- // expose test stats after all workers finished their execution
66
- function addStepsToTest(test, stepArr) {
67
- stepArr.test.steps.forEach(step => {
68
- if (test.steps.length === 0) {
69
- test.steps.push(step)
70
- }
71
- })
72
- }
73
-
74
- stepArr.forEach(step => {
75
- passedTestArr.forEach(test => {
76
- if (step.test.title === test.title) {
77
- addStepsToTest(test, step)
78
- }
79
- })
80
-
81
- failedTestArr.forEach(test => {
82
- if (step.test.title === test.title) {
83
- addStepsToTest(test, step)
84
- }
85
- })
86
- })
87
-
88
- event.dispatcher.emit(event.workers.result, {
89
- suites: suiteArr,
90
- tests: {
91
- passed: passedTestArr,
92
- failed: failedTestArr,
93
- skipped: skippedTestArr,
94
- },
95
- })
44
+ workers.on(event.all.result, result => {
96
45
  workers.printResults()
97
46
  })
98
47
 
@@ -100,7 +49,6 @@ module.exports = async function (workerCount, selectedRuns, options) {
100
49
  if (options.verbose || options.debug) store.debugMode = true
101
50
 
102
51
  if (options.verbose) {
103
- global.debugMode = true
104
52
  const { getMachineInfo } = require('./info')
105
53
  await getMachineInfo()
106
54
  }
@@ -1,288 +1,127 @@
1
- const tty = require('tty');
1
+ const tty = require('tty')
2
2
 
3
3
  if (!tty.getWindowSize) {
4
4
  // this is really old method, long removed from Node, but Mocha
5
5
  // reporters fall back on it if they cannot use `process.stdout.getWindowSize`
6
6
  // we need to polyfill it.
7
- tty.getWindowSize = () => [40, 80];
7
+ tty.getWindowSize = () => [40, 80]
8
8
  }
9
9
 
10
- const { parentPort, workerData } = require('worker_threads');
11
- const event = require('../../event');
12
- const container = require('../../container');
13
- const { getConfig } = require('../utils');
14
- const { tryOrDefault, deepMerge } = require('../../utils');
10
+ const { parentPort, workerData } = require('worker_threads')
11
+ const event = require('../../event')
12
+ const container = require('../../container')
13
+ const { getConfig } = require('../utils')
14
+ const { tryOrDefault, deepMerge } = require('../../utils')
15
15
 
16
- let stdout = '';
16
+ let stdout = ''
17
17
 
18
- const stderr = '';
18
+ const stderr = ''
19
19
 
20
20
  // Requiring of Codecept need to be after tty.getWindowSize is available.
21
- const Codecept = require(process.env.CODECEPT_CLASS_PATH || '../../codecept');
21
+ const Codecept = require(process.env.CODECEPT_CLASS_PATH || '../../codecept')
22
22
 
23
- const { options, tests, testRoot, workerIndex } = workerData;
23
+ const { options, tests, testRoot, workerIndex } = workerData
24
24
 
25
25
  // hide worker output
26
26
  if (!options.debug && !options.verbose)
27
27
  process.stdout.write = string => {
28
- stdout += string;
29
- return true;
30
- };
28
+ stdout += string
29
+ return true
30
+ }
31
31
 
32
- const overrideConfigs = tryOrDefault(() => JSON.parse(options.override), {});
32
+ const overrideConfigs = tryOrDefault(() => JSON.parse(options.override), {})
33
33
 
34
34
  // important deep merge so dynamic things e.g. functions on config are not overridden
35
- const config = deepMerge(getConfig(options.config || testRoot), overrideConfigs);
35
+ const config = deepMerge(getConfig(options.config || testRoot), overrideConfigs)
36
36
 
37
37
  // Load test and run
38
- const codecept = new Codecept(config, options);
39
- codecept.init(testRoot);
40
- codecept.loadTests();
41
- const mocha = container.mocha();
42
- filterTests();
38
+ const codecept = new Codecept(config, options)
39
+ codecept.init(testRoot)
40
+ codecept.loadTests()
41
+ const mocha = container.mocha()
42
+ filterTests()
43
43
 
44
44
  // run tests
45
- (async function () {
45
+ ;(async function () {
46
46
  if (mocha.suite.total()) {
47
- await runTests();
47
+ await runTests()
48
48
  }
49
- })();
49
+ })()
50
50
 
51
51
  async function runTests() {
52
52
  try {
53
- await codecept.bootstrap();
53
+ await codecept.bootstrap()
54
54
  } catch (err) {
55
- throw new Error(`Error while running bootstrap file :${err}`);
55
+ throw new Error(`Error while running bootstrap file :${err}`)
56
56
  }
57
- listenToParentThread();
58
- initializeListeners();
59
- disablePause();
57
+ listenToParentThread()
58
+ initializeListeners()
59
+ disablePause()
60
60
  try {
61
- await codecept.run();
61
+ await codecept.run()
62
62
  } finally {
63
- await codecept.teardown();
63
+ await codecept.teardown()
64
64
  }
65
65
  }
66
66
 
67
67
  function filterTests() {
68
- const files = codecept.testFiles;
69
- mocha.files = files;
70
- mocha.loadFiles();
68
+ const files = codecept.testFiles
69
+ mocha.files = files
70
+ mocha.loadFiles()
71
71
 
72
72
  for (const suite of mocha.suite.suites) {
73
- suite.tests = suite.tests.filter(test => tests.indexOf(test.uid) >= 0);
73
+ suite.tests = suite.tests.filter(test => tests.indexOf(test.uid) >= 0)
74
74
  }
75
75
  }
76
76
 
77
77
  function initializeListeners() {
78
- function simplifyError(error) {
79
- if (error) {
80
- const { stack, uncaught, message, actual, expected } = error;
81
-
82
- return {
83
- stack,
84
- uncaught,
85
- message,
86
- actual,
87
- expected,
88
- };
89
- }
90
-
91
- return null;
92
- }
93
- function simplifyTest(test, err = null) {
94
- test = { ...test };
95
-
96
- if (test.start && !test.duration) {
97
- const end = new Date();
98
- test.duration = end - test.start;
99
- }
100
-
101
- if (test.err) {
102
- err = simplifyError(test.err);
103
- test.status = 'failed';
104
- } else if (err) {
105
- err = simplifyError(err);
106
- test.status = 'failed';
107
- }
108
- const parent = {};
109
- if (test.parent) {
110
- parent.title = test.parent.title;
111
- }
112
-
113
- if (test.opts) {
114
- Object.keys(test.opts).forEach(k => {
115
- if (typeof test.opts[k] === 'object') delete test.opts[k];
116
- if (typeof test.opts[k] === 'function') delete test.opts[k];
117
- });
118
- }
119
-
120
- return {
121
- opts: test.opts || {},
122
- tags: test.tags || [],
123
- uid: test.uid,
124
- workerIndex,
125
- retries: test._retries,
126
- title: test.title,
127
- status: test.status,
128
- duration: test.duration || 0,
129
- err,
130
- parent,
131
- steps: test.steps && test.steps.length > 0 ? simplifyStepsInTestObject(test.steps, err) : [],
132
- };
133
- }
134
-
135
- function simplifyStepsInTestObject(steps, err) {
136
- steps = [...steps];
137
- const _steps = [];
138
-
139
- for (step of steps) {
140
- const _args = [];
141
-
142
- if (step.args) {
143
- for (const arg of step.args) {
144
- // check if arg is a JOI object
145
- if (arg && arg.$_root) {
146
- _args.push(JSON.stringify(arg).slice(0, 300));
147
- // check if arg is a function
148
- } else if (arg && typeof arg === 'function') {
149
- _args.push(arg.name);
150
- } else {
151
- _args.push(arg);
152
- }
153
- }
154
- }
155
-
156
- _steps.push({
157
- actor: step.actor,
158
- name: step.name,
159
- status: step.status,
160
- args: JSON.stringify(_args),
161
- startedAt: step.startedAt,
162
- startTime: step.startTime,
163
- endTime: step.endTime,
164
- finishedAt: step.finishedAt,
165
- duration: step.duration,
166
- err,
167
- });
168
- }
169
-
170
- return _steps;
171
- }
172
-
173
- function simplifyStep(step, err = null) {
174
- step = { ...step };
175
-
176
- if (step.startTime && !step.duration) {
177
- const end = new Date();
178
- step.duration = end - step.startTime;
179
- }
180
-
181
- if (step.err) {
182
- err = simplifyError(step.err);
183
- step.status = 'failed';
184
- } else if (err) {
185
- err = simplifyError(err);
186
- step.status = 'failed';
187
- }
188
-
189
- const parent = {};
190
- if (step.metaStep) {
191
- parent.title = step.metaStep.actor;
192
- }
193
-
194
- if (step.opts) {
195
- Object.keys(step.opts).forEach(k => {
196
- if (typeof step.opts[k] === 'object') delete step.opts[k];
197
- if (typeof step.opts[k] === 'function') delete step.opts[k];
198
- });
199
- }
200
-
201
- return {
202
- opts: step.opts || {},
203
- workerIndex,
204
- title: step.name,
205
- status: step.status,
206
- duration: step.duration || 0,
207
- err,
208
- parent,
209
- test: simplifyTest(step.test),
210
- };
211
- }
212
-
213
- collectStats();
214
78
  // suite
215
- event.dispatcher.on(event.suite.before, suite => sendToParentThread({ event: event.suite.before, workerIndex, data: simplifyTest(suite) }));
216
- event.dispatcher.on(event.suite.after, suite => sendToParentThread({ event: event.suite.after, workerIndex, data: simplifyTest(suite) }));
79
+ event.dispatcher.on(event.suite.before, suite => sendToParentThread({ event: event.suite.before, workerIndex, data: suite.simplify() }))
80
+ event.dispatcher.on(event.suite.after, suite => sendToParentThread({ event: event.suite.after, workerIndex, data: suite.simplify() }))
217
81
 
218
82
  // calculate duration
219
- event.dispatcher.on(event.test.started, test => (test.start = new Date()));
83
+ event.dispatcher.on(event.test.started, test => (test.start = new Date()))
220
84
 
221
85
  // tests
222
- event.dispatcher.on(event.test.before, test => sendToParentThread({ event: event.test.before, workerIndex, data: simplifyTest(test) }));
223
- event.dispatcher.on(event.test.after, test => sendToParentThread({ event: event.test.after, workerIndex, data: simplifyTest(test) }));
86
+ event.dispatcher.on(event.test.before, test => sendToParentThread({ event: event.test.before, workerIndex, data: test.simplify() }))
87
+ event.dispatcher.on(event.test.after, test => sendToParentThread({ event: event.test.after, workerIndex, data: test.simplify() }))
224
88
  // we should force-send correct errors to prevent race condition
225
- event.dispatcher.on(event.test.finished, (test, err) => sendToParentThread({ event: event.test.finished, workerIndex, data: simplifyTest(test, err) }));
226
- event.dispatcher.on(event.test.failed, (test, err) => sendToParentThread({ event: event.test.failed, workerIndex, data: simplifyTest(test, err) }));
227
- event.dispatcher.on(event.test.passed, (test, err) => sendToParentThread({ event: event.test.passed, workerIndex, data: simplifyTest(test, err) }));
228
- event.dispatcher.on(event.test.started, test => sendToParentThread({ event: event.test.started, workerIndex, data: simplifyTest(test) }));
229
- event.dispatcher.on(event.test.skipped, test => sendToParentThread({ event: event.test.skipped, workerIndex, data: simplifyTest(test) }));
89
+ event.dispatcher.on(event.test.finished, (test, err) => sendToParentThread({ event: event.test.finished, workerIndex, data: { ...test.simplify(), err } }))
90
+ event.dispatcher.on(event.test.failed, (test, err) => sendToParentThread({ event: event.test.failed, workerIndex, data: { ...test.simplify(), err } }))
91
+ event.dispatcher.on(event.test.passed, (test, err) => sendToParentThread({ event: event.test.passed, workerIndex, data: { ...test.simplify(), err } }))
92
+ event.dispatcher.on(event.test.started, test => sendToParentThread({ event: event.test.started, workerIndex, data: test.simplify() }))
93
+ event.dispatcher.on(event.test.skipped, test => sendToParentThread({ event: event.test.skipped, workerIndex, data: test.simplify() }))
230
94
 
231
95
  // steps
232
- event.dispatcher.on(event.step.finished, step => sendToParentThread({ event: event.step.finished, workerIndex, data: simplifyStep(step) }));
233
- event.dispatcher.on(event.step.started, step => sendToParentThread({ event: event.step.started, workerIndex, data: simplifyStep(step) }));
234
- event.dispatcher.on(event.step.passed, step => sendToParentThread({ event: event.step.passed, workerIndex, data: simplifyStep(step) }));
235
- event.dispatcher.on(event.step.failed, step => sendToParentThread({ event: event.step.failed, workerIndex, data: simplifyStep(step) }));
96
+ event.dispatcher.on(event.step.finished, step => sendToParentThread({ event: event.step.finished, workerIndex, data: step.simplify() }))
97
+ event.dispatcher.on(event.step.started, step => sendToParentThread({ event: event.step.started, workerIndex, data: step.simplify() }))
98
+ event.dispatcher.on(event.step.passed, step => sendToParentThread({ event: event.step.passed, workerIndex, data: step.simplify() }))
99
+ event.dispatcher.on(event.step.failed, step => sendToParentThread({ event: event.step.failed, workerIndex, data: step.simplify() }))
236
100
 
237
- event.dispatcher.on(event.hook.failed, (test, err) => sendToParentThread({ event: event.hook.failed, workerIndex, data: simplifyTest(test, err) }));
238
- event.dispatcher.on(event.hook.passed, (test, err) => sendToParentThread({ event: event.hook.passed, workerIndex, data: simplifyTest(test, err) }));
239
- event.dispatcher.on(event.all.failures, data => sendToParentThread({ event: event.all.failures, workerIndex, data }));
101
+ event.dispatcher.on(event.hook.failed, (hook, err) => sendToParentThread({ event: event.hook.failed, workerIndex, data: { ...hook.simplify(), err } }))
102
+ event.dispatcher.on(event.hook.passed, hook => sendToParentThread({ event: event.hook.passed, workerIndex, data: hook.simplify() }))
103
+ event.dispatcher.on(event.hook.finished, hook => sendToParentThread({ event: event.hook.finished, workerIndex, data: hook.simplify() }))
240
104
 
105
+ event.dispatcher.once(event.all.after, () => {
106
+ sendToParentThread({ event: event.all.after, workerIndex, data: container.result().simplify() })
107
+ })
241
108
  // all
242
- event.dispatcher.once(event.all.result, () => parentPort.close());
109
+ event.dispatcher.once(event.all.result, () => {
110
+ sendToParentThread({ event: event.all.result, workerIndex, data: container.result().simplify() })
111
+ parentPort?.close()
112
+ })
243
113
  }
244
114
 
245
115
  function disablePause() {
246
- global.pause = () => {};
247
- }
248
-
249
- function collectStats() {
250
- const stats = {
251
- passes: 0,
252
- failures: 0,
253
- skipped: 0,
254
- tests: 0,
255
- pending: 0,
256
- };
257
- event.dispatcher.on(event.test.skipped, () => {
258
- stats.skipped++;
259
- });
260
- event.dispatcher.on(event.test.passed, () => {
261
- stats.passes++;
262
- });
263
- event.dispatcher.on(event.test.failed, test => {
264
- if (test.ctx._runnable.title.includes('hook: AfterSuite')) {
265
- stats.failedHooks += 1;
266
- }
267
- stats.failures++;
268
- });
269
- event.dispatcher.on(event.test.skipped, () => {
270
- stats.pending++;
271
- });
272
- event.dispatcher.on(event.test.finished, () => {
273
- stats.tests++;
274
- });
275
- event.dispatcher.once(event.all.after, () => {
276
- sendToParentThread({ event: event.all.after, data: stats });
277
- });
116
+ global.pause = () => {}
278
117
  }
279
118
 
280
119
  function sendToParentThread(data) {
281
- parentPort.postMessage(data);
120
+ parentPort?.postMessage(data)
282
121
  }
283
122
 
284
123
  function listenToParentThread() {
285
- parentPort.on('message', eventData => {
286
- container.append({ support: eventData.data });
287
- });
124
+ parentPort?.on('message', eventData => {
125
+ container.append({ support: eventData.data })
126
+ })
288
127
  }