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,12 +1,15 @@
1
- const merge = require('lodash.merge');
2
- const path = require('path');
1
+ import merge from 'lodash.merge';
2
+ import path from 'path';
3
+
4
+ import importSync from 'import-sync';
5
+ import * as translations from '../translations/index.js';
3
6
 
4
7
  const defaultVocabulary = {
5
8
  I: 'I',
6
9
  actions: {},
7
10
  };
8
11
 
9
- class Translation {
12
+ export default class Translation {
10
13
  constructor(vocabulary, loaded) {
11
14
  this.vocabulary = vocabulary;
12
15
  this.loaded = loaded !== false;
@@ -17,7 +20,7 @@ class Translation {
17
20
  const filePath = path.join(global.codecept_dir, vocabularyFile);
18
21
 
19
22
  try {
20
- const vocabulary = require(filePath);
23
+ const vocabulary = importSync(filePath);
21
24
  this.vocabulary = merge(this.vocabulary, vocabulary);
22
25
  } catch (err) {
23
26
  throw new Error(`Can't load vocabulary from ${filePath}; ${err}`);
@@ -40,7 +43,7 @@ class Translation {
40
43
  }
41
44
 
42
45
  static get langs() {
43
- return require('../translations');
46
+ return translations;
44
47
  }
45
48
 
46
49
  static createDefault() {
@@ -51,5 +54,3 @@ class Translation {
51
54
  return new Translation(defaultVocabulary, false);
52
55
  }
53
56
  }
54
-
55
- module.exports = Translation;
package/lib/ui.js CHANGED
@@ -1,12 +1,12 @@
1
- const escapeRe = require('escape-string-regexp');
2
- const Suite = require('mocha/lib/suite');
3
- const Test = require('mocha/lib/test');
4
-
5
- const scenario = require('./scenario');
6
- const ScenarioConfig = require('./interfaces/scenarioConfig');
7
- const FeatureConfig = require('./interfaces/featureConfig');
8
- const addDataContext = require('./data/context');
9
- const container = require('./container');
1
+ import escapeRe from 'escape-string-regexp';
2
+ import Suite from 'mocha/lib/suite.js';
3
+ import Test from 'mocha/lib/test.js';
4
+ import mocha0 from 'mocha/lib/interfaces/common.js';
5
+ import * as scenario from './scenario.js';
6
+ import ScenarioConfig from './interfaces/scenarioConfig.js';
7
+ import FeatureConfig from './interfaces/featureConfig.js';
8
+ import addDataContext from './data/context.js';
9
+ import container from './container.js';
10
10
 
11
11
  const setContextTranslation = (context) => {
12
12
  const contexts = container.translation().value('contexts');
@@ -34,7 +34,7 @@ const setContextTranslation = (context) => {
34
34
  * @param {Mocha.Suite} suite Root suite.
35
35
  * @ignore
36
36
  */
37
- module.exports = function (suite) {
37
+ export function suite(suite) {
38
38
  const suites = [suite];
39
39
  suite.timeout(0);
40
40
  let afterAllHooks;
@@ -43,7 +43,7 @@ module.exports = function (suite) {
43
43
  let afterEachHooksAreLoaded;
44
44
 
45
45
  suite.on('pre-require', (context, file, mocha) => {
46
- const common = require('mocha/lib/interfaces/common')(suites, context, mocha);
46
+ const common = mocha0(suites, context, mocha);
47
47
 
48
48
  const addScenario = function (title, opts = {}, fn) {
49
49
  const suite = suites[0];
@@ -233,4 +233,6 @@ module.exports = function (suite) {
233
233
  afterAllHooksAreLoaded = true;
234
234
  }
235
235
  });
236
- };
236
+ }
237
+
238
+ export default suite;
package/lib/utils.js CHANGED
@@ -1,42 +1,45 @@
1
- const fs = require('fs');
2
- const os = require('os');
3
- const path = require('path');
4
- const getFunctionArguments = require('fn-args');
5
- const deepClone = require('lodash.clonedeep');
6
- const { convertColorToRGBA, isColorProperty } = require('./colorUtils');
7
-
8
- function deepMerge(target, source) {
9
- const merge = require('lodash.merge');
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import getFunctionArguments from 'fn-args';
5
+ import deepClone from 'lodash.clonedeep';
6
+ import merge from 'lodash.merge';
7
+ import { createHash } from 'crypto';
8
+ import format from 'js-beautify';
9
+ import importSync from 'import-sync';
10
+ import { convertColorToRGBA, isColorProperty } from './colorUtils.js';
11
+
12
+ const __dirname = path.resolve();
13
+
14
+ export function deepMerge(target, source) {
10
15
  return merge(target, source);
11
16
  }
12
17
 
13
- module.exports.genTestId = (test) => {
14
- return require('crypto').createHash('sha256').update(test.fullTitle()).digest('base64')
18
+ export const genTestId = (test) => {
19
+ return createHash('sha256').update(test.fullTitle()).digest('base64')
15
20
  .slice(0, -2);
16
21
  };
17
22
 
18
- module.exports.deepMerge = deepMerge;
23
+ export { deepClone };
19
24
 
20
- module.exports.deepClone = deepClone;
21
-
22
- module.exports.isGenerator = function (fn) {
25
+ export const isGenerator = function (fn) {
23
26
  return fn.constructor.name === 'GeneratorFunction';
24
27
  };
25
28
 
26
- const isFunction = module.exports.isFunction = function (fn) {
29
+ export const isFunction = function (fn) {
27
30
  return typeof fn === 'function';
28
31
  };
29
32
 
30
- const isAsyncFunction = module.exports.isAsyncFunction = function (fn) {
33
+ export function isAsyncFunction(fn) {
31
34
  if (!fn) return false;
32
35
  return fn[Symbol.toStringTag] === 'AsyncFunction';
33
- };
36
+ }
34
37
 
35
- module.exports.fileExists = function (filePath) {
38
+ export const fileExists = function (filePath) {
36
39
  return fs.existsSync(filePath);
37
40
  };
38
41
 
39
- module.exports.isFile = function (filePath) {
42
+ export const isFile = function (filePath) {
40
43
  let filestat;
41
44
  try {
42
45
  filestat = fs.statSync(filePath);
@@ -47,16 +50,16 @@ module.exports.isFile = function (filePath) {
47
50
  return filestat.isFile();
48
51
  };
49
52
 
50
- module.exports.getParamNames = function (fn) {
53
+ export const getParamNames = function (fn) {
51
54
  if (fn.isSinonProxy) return [];
52
55
  return getFunctionArguments(fn);
53
56
  };
54
57
 
55
- module.exports.installedLocally = function () {
58
+ export const installedLocally = function () {
56
59
  return path.resolve(`${__dirname}/../`).indexOf(process.cwd()) === 0;
57
60
  };
58
61
 
59
- module.exports.methodsOfObject = function (obj, className) {
62
+ export const methodsOfObject = function (obj, className) {
60
63
  const methods = [];
61
64
 
62
65
  const standard = [
@@ -92,7 +95,7 @@ module.exports.methodsOfObject = function (obj, className) {
92
95
  return methods;
93
96
  };
94
97
 
95
- module.exports.template = function (template, data) {
98
+ export const template = function (template, data) {
96
99
  return template.replace(/{{([^{}]*)}}/g, (a, b) => {
97
100
  const r = data[b];
98
101
  if (r === undefined) return '';
@@ -105,7 +108,7 @@ module.exports.template = function (template, data) {
105
108
  * @param {string} str
106
109
  * @returns {string}
107
110
  */
108
- module.exports.ucfirst = function (str) {
111
+ export const ucfirst = function (str) {
109
112
  return str.charAt(0).toUpperCase() + str.substr(1);
110
113
  };
111
114
 
@@ -114,11 +117,11 @@ module.exports.ucfirst = function (str) {
114
117
  * @param {string} str
115
118
  * @returns {string}
116
119
  */
117
- module.exports.lcfirst = function (str) {
120
+ export const lcfirst = function (str) {
118
121
  return str.charAt(0).toLowerCase() + str.substr(1);
119
122
  };
120
123
 
121
- module.exports.chunkArray = function (arr, chunk) {
124
+ export const chunkArray = function (arr, chunk) {
122
125
  let i;
123
126
  let j;
124
127
  const tmp = [];
@@ -128,7 +131,7 @@ module.exports.chunkArray = function (arr, chunk) {
128
131
  return tmp;
129
132
  };
130
133
 
131
- module.exports.clearString = function (str) {
134
+ export const clearString = function (str) {
132
135
  if (!str) return '';
133
136
  /* Replace forbidden symbols in string
134
137
  */
@@ -149,13 +152,13 @@ module.exports.clearString = function (str) {
149
152
  .replace(/'/g, '');
150
153
  };
151
154
 
152
- module.exports.decodeUrl = function (url) {
155
+ export const decodeUrl = function (url) {
153
156
  /* Replace forbidden symbols in string
154
157
  */
155
158
  return decodeURIComponent(decodeURIComponent(decodeURIComponent(url)));
156
159
  };
157
160
 
158
- module.exports.xpathLocator = {
161
+ export const xpathLocator = {
159
162
  /**
160
163
  * @param {string} string
161
164
  * @returns {string}
@@ -176,25 +179,7 @@ module.exports.xpathLocator = {
176
179
  combine: locators => locators.join(' | '),
177
180
  };
178
181
 
179
- module.exports.test = {
180
-
181
- grepLines(array, startString, endString) {
182
- let startIndex = 0;
183
- let endIndex;
184
- array.every((elem, index) => {
185
- if (elem === startString) {
186
- startIndex = index;
187
- return true;
188
- }
189
- if (elem === endString) {
190
- endIndex = index;
191
- return false;
192
- }
193
- return true;
194
- });
195
- return array.slice(startIndex + 1, endIndex);
196
- },
197
-
182
+ export default {
198
183
  submittedData(dataFile) {
199
184
  return function (key) {
200
185
  if (!fs.existsSync(dataFile)) {
@@ -214,6 +199,23 @@ module.exports.test = {
214
199
 
215
200
  };
216
201
 
202
+ export function grepLines(array, startString, endString) {
203
+ let startIndex = 0;
204
+ let endIndex;
205
+ array.every((elem, index) => {
206
+ if (elem === startString) {
207
+ startIndex = index;
208
+ return true;
209
+ }
210
+ if (elem === endString) {
211
+ endIndex = index;
212
+ return false;
213
+ }
214
+ return true;
215
+ });
216
+ return array.slice(startIndex + 1, endIndex);
217
+ }
218
+
217
219
  function toCamelCase(name) {
218
220
  if (typeof name !== 'string') {
219
221
  return name;
@@ -222,7 +224,7 @@ function toCamelCase(name) {
222
224
  return letter.toUpperCase();
223
225
  });
224
226
  }
225
- module.exports.toCamelCase = toCamelCase;
227
+ export { toCamelCase };
226
228
 
227
229
  function convertFontWeightToNumber(name) {
228
230
  const fontWeightPatterns = [
@@ -253,7 +255,7 @@ function isFontWeightProperty(prop) {
253
255
  return prop === 'fontWeight';
254
256
  }
255
257
 
256
- module.exports.convertCssPropertiesToCamelCase = function (props) {
258
+ export const convertCssPropertiesToCamelCase = function (props) {
257
259
  const output = {};
258
260
  Object.keys(props).forEach((key) => {
259
261
  const keyCamel = toCamelCase(key);
@@ -269,7 +271,7 @@ module.exports.convertCssPropertiesToCamelCase = function (props) {
269
271
  return output;
270
272
  };
271
273
 
272
- module.exports.deleteDir = function (dir_path) {
274
+ export const deleteDir = function (dir_path) {
273
275
  if (fs.existsSync(dir_path)) {
274
276
  fs.readdirSync(dir_path).forEach(function (entry) {
275
277
  const entry_path = path.join(dir_path, entry);
@@ -287,7 +289,7 @@ module.exports.deleteDir = function (dir_path) {
287
289
  * Returns absolute filename to save screenshot.
288
290
  * @param fileName {string} - filename.
289
291
  */
290
- module.exports.screenshotOutputFolder = function (fileName) {
292
+ export const screenshotOutputFolder = function (fileName) {
291
293
  const fileSep = path.sep;
292
294
 
293
295
  if (!fileName.includes(fileSep) || fileName.includes('record_')) {
@@ -296,8 +298,7 @@ module.exports.screenshotOutputFolder = function (fileName) {
296
298
  return path.resolve(global.codecept_dir, fileName);
297
299
  };
298
300
 
299
- module.exports.beautify = function (code) {
300
- const format = require('js-beautify').js;
301
+ export const beautify = function (code) {
301
302
  return format(code, { indent_size: 2, space_in_empty_paren: true });
302
303
  };
303
304
 
@@ -317,7 +318,7 @@ function joinUrl(baseUrl, url) {
317
318
  return shouldAppendBaseUrl(url) ? `${baseUrl}/${trimUrl(url)}` : url;
318
319
  }
319
320
 
320
- module.exports.appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
321
+ export const appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
321
322
  if (typeof baseUrl !== 'string') {
322
323
  throw new Error(`Invalid value for baseUrl: ${baseUrl}`);
323
324
  }
@@ -343,7 +344,7 @@ module.exports.appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
343
344
  * @param {string} key key to search
344
345
  * @param {*} value value to set for key
345
346
  */
346
- module.exports.replaceValueDeep = function replaceValueDeep(obj, key, value) {
347
+ export const replaceValueDeep = function replaceValueDeep(obj, key, value) {
347
348
  if (!obj) return;
348
349
 
349
350
  if (obj instanceof Array) {
@@ -365,7 +366,7 @@ module.exports.replaceValueDeep = function replaceValueDeep(obj, key, value) {
365
366
  return obj;
366
367
  };
367
368
 
368
- module.exports.ansiRegExp = function ({ onlyFirst = false } = {}) {
369
+ export const ansiRegExp = function ({ onlyFirst = false } = {}) {
369
370
  const pattern = [
370
371
  '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
371
372
  '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))',
@@ -374,7 +375,7 @@ module.exports.ansiRegExp = function ({ onlyFirst = false } = {}) {
374
375
  return new RegExp(pattern, onlyFirst ? undefined : 'g');
375
376
  };
376
377
 
377
- module.exports.tryOrDefault = function (fn, defaultValue) {
378
+ export const tryOrDefault = function (fn, defaultValue) {
378
379
  try {
379
380
  return fn();
380
381
  } catch (_) {
@@ -401,7 +402,7 @@ function normalizeKeyReplacer(match, prefix, key, suffix, offset, string) {
401
402
  * @param {string} key
402
403
  * @returns {string}
403
404
  */
404
- module.exports.getNormalizedKeyAttributeValue = function (key) {
405
+ export const getNormalizedKeyAttributeValue = function (key) {
405
406
  // Use operation modifier key based on operating system
406
407
  key = key.replace(/(Ctrl|Control|Cmd|Command)[ _]?Or[ _]?(Ctrl|Control|Cmd|Command)/i, os.platform() === 'darwin' ? 'Meta' : 'Control');
407
408
  // Selection of keys (https://www.w3.org/TR/uievents-key/#named-key-attribute-values)
@@ -425,15 +426,16 @@ const modifierKeys = [
425
426
  'Shift', 'ShiftLeft', 'ShiftRight',
426
427
  ];
427
428
 
428
- module.exports.modifierKeys = modifierKeys;
429
- module.exports.isModifierKey = function (key) {
429
+ export { modifierKeys };
430
+
431
+ export const isModifierKey = function (key) {
430
432
  return modifierKeys.includes(key);
431
433
  };
432
434
 
433
- module.exports.requireWithFallback = function (...packages) {
435
+ export const requireWithFallback = function (...packages) {
434
436
  const exists = function (pkg) {
435
437
  try {
436
- require.resolve(pkg);
438
+ importSync(pkg);
437
439
  } catch (e) {
438
440
  return false;
439
441
  }
@@ -443,24 +445,24 @@ module.exports.requireWithFallback = function (...packages) {
443
445
 
444
446
  for (const pkg of packages) {
445
447
  if (exists(pkg)) {
446
- return require(pkg);
448
+ return importSync(pkg);
447
449
  }
448
450
  }
449
451
 
450
452
  throw new Error(`Cannot find modules ${packages.join(',')}`);
451
453
  };
452
454
 
453
- module.exports.isNotSet = function (obj) {
455
+ export const isNotSet = function (obj) {
454
456
  if (obj === null) return true;
455
457
  if (obj === undefined) return true;
456
458
  return false;
457
459
  };
458
460
 
459
- module.exports.emptyFolder = async (directoryPath) => {
460
- require('child_process').execSync(`rm -rf ${directoryPath}/*`);
461
+ export const emptyFolder = async (directoryPath) => {
462
+ importSync('child_process').execSync(`rm -rf ${directoryPath}/*`);
461
463
  };
462
464
 
463
- module.exports.printObjectProperties = (obj) => {
465
+ export const printObjectProperties = (obj) => {
464
466
  if (typeof obj !== 'object' || obj === null) {
465
467
  return obj;
466
468
  }
@@ -473,6 +475,6 @@ module.exports.printObjectProperties = (obj) => {
473
475
  return `{${result}}`;
474
476
  };
475
477
 
476
- module.exports.normalizeSpacesInString = (string) => {
478
+ export const normalizeSpacesInString = (string) => {
477
479
  return string.replace(/\s+/g, ' ');
478
480
  };
package/lib/within.js CHANGED
@@ -1,10 +1,10 @@
1
- const output = require('./output');
2
- const store = require('./store');
3
- const recorder = require('./recorder');
4
- const container = require('./container');
5
- const event = require('./event');
6
- const Step = require('./step');
7
- const { isAsyncFunction } = require('./utils');
1
+ import * as output from './output.js';
2
+ import { store } from './store.js';
3
+ import recorder from './recorder.js';
4
+ import container from './container.js';
5
+ import * as event from './event.js';
6
+ import { Step } from './step.js';
7
+ import { isAsyncFunction } from './utils.js';
8
8
 
9
9
  /**
10
10
  * @param {CodeceptJS.LocatorOrString} context
@@ -29,7 +29,7 @@ function within(context, fn) {
29
29
  const finalize = () => {
30
30
  event.dispatcher.removeListener(event.step.before, defineMetaStep);
31
31
  recorder.add('Finalize session within session', () => {
32
- output.stepShift = 1;
32
+ output.output.stepShift = 1;
33
33
  recorder.session.restore('within');
34
34
  });
35
35
  };
@@ -58,7 +58,7 @@ function within(context, fn) {
58
58
  } finally {
59
59
  finishHelpers();
60
60
  recorder.catch((err) => {
61
- output.stepShift = 1;
61
+ output.output.stepShift = 1;
62
62
  throw err;
63
63
  });
64
64
  }
@@ -67,4 +67,4 @@ function within(context, fn) {
67
67
  }, false, false);
68
68
  }
69
69
 
70
- module.exports = within;
70
+ export default within;
@@ -1,9 +1,9 @@
1
- const { isMainThread, parentPort } = require('worker_threads');
1
+ import { isMainThread, parentPort } from 'worker_threads';
2
2
 
3
3
  const workerObjects = {};
4
4
  const shareEvent = 'share';
5
5
 
6
- const invokeWorkerListeners = (workerObj) => {
6
+ export const invokeWorkerListeners = (workerObj) => {
7
7
  const { threadId } = workerObj;
8
8
  workerObj.on('message', (messageData) => {
9
9
  if (messageData.event === shareEvent) {
@@ -15,32 +15,30 @@ const invokeWorkerListeners = (workerObj) => {
15
15
  });
16
16
  };
17
17
 
18
- class WorkerStorage {
19
- /**
20
- * Add worker object
21
- *
22
- * @api
23
- * @param {Worker} workerObj
24
- */
25
- static addWorker(workerObj) {
26
- workerObjects[workerObj.threadId] = workerObj;
27
- invokeWorkerListeners(workerObj);
28
- }
18
+ /**
19
+ * Add worker object
20
+ *
21
+ * @api
22
+ * @param {Worker} workerObj
23
+ */
24
+ export function addWorker(workerObj) {
25
+ // @ts-ignore
26
+ workerObjects[workerObj.threadId] = workerObj;
27
+ invokeWorkerListeners(workerObj);
28
+ }
29
29
 
30
- /**
31
- * Share data across workers
32
- *
33
- * @param {*} data
34
- */
35
- static share(data) {
36
- if (isMainThread) {
37
- for (const workerObj of Object.values(workerObjects)) {
38
- workerObj.postMessage({ data });
39
- }
40
- } else {
41
- parentPort.postMessage({ data, event: shareEvent });
30
+ /**
31
+ * Share data across workers
32
+ *
33
+ * @param {*} data
34
+ */
35
+ export function share(data) {
36
+ if (isMainThread) {
37
+ for (const workerObj of Object.values(workerObjects)) {
38
+ workerObj.postMessage({ data });
42
39
  }
40
+ } else {
41
+ // @ts-ignore
42
+ parentPort.postMessage({ data, event: shareEvent });
43
43
  }
44
44
  }
45
-
46
- module.exports = WorkerStorage;
package/lib/workers.js CHANGED
@@ -1,24 +1,27 @@
1
1
  /* eslint-disable max-classes-per-file */
2
- const path = require('path');
3
- const mkdirp = require('mkdirp');
4
- const { Worker } = require('worker_threads');
5
- const { Suite, Test, reporters: { Base } } = require('mocha');
6
- const { EventEmitter } = require('events');
7
- const ms = require('ms');
8
- const Codecept = require('./codecept');
9
- const MochaFactory = require('./mochaFactory');
10
- const Container = require('./container');
11
- const { getTestRoot } = require('./command/utils');
12
- const { isFunction, fileExists } = require('./utils');
13
- const { replaceValueDeep, deepClone } = require('./utils');
14
- const mainConfig = require('./config');
15
- const output = require('./output');
16
- const event = require('./event');
17
- const recorder = require('./recorder');
18
- const runHook = require('./hooks');
19
- const WorkerStorage = require('./workerStorage');
20
- const collection = require('./command/run-multiple/collection');
21
-
2
+ import path from 'path';
3
+ import mkdirp from 'mkdirp';
4
+ import { Worker } from 'worker_threads';
5
+
6
+ import { Suite, Test } from 'mocha';
7
+ import { EventEmitter } from 'events';
8
+ import ms from 'ms';
9
+ import Codecept from './codecept.js';
10
+ import { MochaFactory } from './mochaFactory.js';
11
+ import Container from './container.js';
12
+ import { getTestRoot } from './command/utils.js';
13
+ import {
14
+ deepClone, fileExists, isFunction, replaceValueDeep,
15
+ } from './utils.js';
16
+ import mainConfig from './config.js';
17
+ import * as output from './output.js';
18
+ import * as event from './event.js';
19
+ import recorder from './recorder.js';
20
+ import runHook from './hooks.js';
21
+ import * as WorkerStorage from './workerStorage.js';
22
+ import collection from './command/run-multiple/collection.js';
23
+
24
+ const __dirname = path.resolve('.', 'lib');
22
25
  const pathToWorker = path.join(__dirname, 'command', 'workers', 'runTests.js');
23
26
 
24
27
  const initializeCodecept = (configPath, options = {}) => {
@@ -40,14 +43,14 @@ const createOutputDir = (configPath) => {
40
43
  }
41
44
  };
42
45
 
43
- const populateGroups = (numberOfWorkers) => {
46
+ export function populateGroups(numberOfWorkers) {
44
47
  const groups = [];
45
48
  for (let i = 0; i < numberOfWorkers; i++) {
46
49
  groups[i] = [];
47
50
  }
48
51
 
49
52
  return groups;
50
- };
53
+ }
51
54
 
52
55
  const createWorker = (workerObject) => {
53
56
  const worker = new Worker(pathToWorker, {
@@ -58,8 +61,9 @@ const createWorker = (workerObject) => {
58
61
  workerIndex: workerObject.workerIndex + 1,
59
62
  },
60
63
  });
61
- worker.on('error', err => output.error(`Worker Error: ${err.stack}`));
64
+ worker.on('error', err => output.output.error(`Worker Error: ${err.stack}`));
62
65
 
66
+ // @ts-ignore
63
67
  WorkerStorage.addWorker(worker);
64
68
  return worker;
65
69
  };
@@ -224,7 +228,7 @@ class WorkerObject {
224
228
  }
225
229
  }
226
230
 
227
- class Workers extends EventEmitter {
231
+ export class Workers extends EventEmitter {
228
232
  /**
229
233
  * @param {Number} numberOfWorkers
230
234
  * @param {Object} config
@@ -388,7 +392,7 @@ class Workers extends EventEmitter {
388
392
 
389
393
  _listenWorkerEvents(worker) {
390
394
  worker.on('message', (message) => {
391
- output.process(message.workerIndex);
395
+ output.output.process(message.workerIndex);
392
396
 
393
397
  // deal with events that are not test cycle related
394
398
  if (!message.event) {
@@ -463,7 +467,7 @@ class Workers extends EventEmitter {
463
467
  process.exitCode = 0;
464
468
  }
465
469
  // removed this.finishedTests because in all /lib only first argument (!this.isFailed()) is used)
466
- this.emit(event.all.result, !this.isFailed());
470
+ this.emit(event.all.result, { status: !this.isFailed(), stats: this.stats });
467
471
  this.emit('end'); // internal event
468
472
  }
469
473
 
@@ -480,7 +484,7 @@ class Workers extends EventEmitter {
480
484
  this.stats.duration = this.stats.end - this.stats.start;
481
485
 
482
486
  // Reset process for logs in main thread
483
- output.process(null);
487
+ output.output.process(null);
484
488
  output.print();
485
489
 
486
490
  this.failuresLog = this.failuresLog
@@ -495,8 +499,7 @@ class Workers extends EventEmitter {
495
499
  }
496
500
 
497
501
  output.result(this.stats.passes, this.stats.failures, this.stats.pending, ms(this.stats.duration), this.stats.failedHooks);
502
+ output.result(cts.passes, this.stats.failures, this.stats.pending, ms(this.stats.duration));
498
503
  process.env.RUNS_WITH_WORKERS = 'false';
499
504
  }
500
505
  }
501
-
502
- module.exports = Workers;