codeceptjs 4.0.0-beta.5 → 4.0.0-beta.7.esm-aria

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +0 -45
  2. package/bin/codecept.js +46 -57
  3. package/lib/actor.js +15 -11
  4. package/lib/ai.js +6 -5
  5. package/lib/assert/empty.js +9 -8
  6. package/lib/assert/equal.js +15 -17
  7. package/lib/assert/error.js +2 -2
  8. package/lib/assert/include.js +9 -11
  9. package/lib/assert/throws.js +1 -1
  10. package/lib/assert/truth.js +8 -5
  11. package/lib/assert.js +18 -18
  12. package/lib/codecept.js +66 -107
  13. package/lib/colorUtils.js +48 -50
  14. package/lib/command/check.js +32 -27
  15. package/lib/command/configMigrate.js +11 -10
  16. package/lib/command/definitions.js +16 -10
  17. package/lib/command/dryRun.js +16 -16
  18. package/lib/command/generate.js +29 -26
  19. package/lib/command/gherkin/init.js +36 -38
  20. package/lib/command/gherkin/snippets.js +14 -14
  21. package/lib/command/gherkin/steps.js +21 -18
  22. package/lib/command/info.js +8 -8
  23. package/lib/command/init.js +34 -31
  24. package/lib/command/interactive.js +11 -10
  25. package/lib/command/list.js +10 -9
  26. package/lib/command/run-multiple/chunk.js +5 -5
  27. package/lib/command/run-multiple/collection.js +5 -5
  28. package/lib/command/run-multiple/run.js +3 -3
  29. package/lib/command/run-multiple.js +16 -13
  30. package/lib/command/run-rerun.js +6 -7
  31. package/lib/command/run-workers.js +10 -24
  32. package/lib/command/run.js +8 -8
  33. package/lib/command/utils.js +20 -18
  34. package/lib/command/workers/runTests.js +117 -269
  35. package/lib/config.js +111 -49
  36. package/lib/container.js +299 -102
  37. package/lib/data/context.js +6 -5
  38. package/lib/data/dataScenarioConfig.js +1 -1
  39. package/lib/data/dataTableArgument.js +1 -1
  40. package/lib/data/table.js +1 -1
  41. package/lib/effects.js +94 -10
  42. package/lib/els.js +11 -9
  43. package/lib/event.js +11 -10
  44. package/lib/globals.js +141 -0
  45. package/lib/heal.js +12 -12
  46. package/lib/helper/AI.js +1 -1
  47. package/lib/helper/ApiDataFactory.js +16 -13
  48. package/lib/helper/FileSystem.js +32 -12
  49. package/lib/helper/GraphQL.js +1 -1
  50. package/lib/helper/GraphQLDataFactory.js +1 -1
  51. package/lib/helper/JSONResponse.js +19 -30
  52. package/lib/helper/Mochawesome.js +9 -28
  53. package/lib/helper/Playwright.js +668 -265
  54. package/lib/helper/Puppeteer.js +284 -169
  55. package/lib/helper/REST.js +29 -12
  56. package/lib/helper/WebDriver.js +192 -71
  57. package/lib/helper/errors/ConnectionRefused.js +6 -6
  58. package/lib/helper/errors/ElementAssertion.js +11 -16
  59. package/lib/helper/errors/ElementNotFound.js +5 -9
  60. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  61. package/lib/helper/extras/Console.js +11 -11
  62. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  63. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  64. package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
  65. package/lib/helper/extras/Popup.js +1 -1
  66. package/lib/helper/extras/React.js +29 -30
  67. package/lib/helper/network/actions.js +33 -48
  68. package/lib/helper/network/utils.js +76 -83
  69. package/lib/helper/scripts/blurElement.js +6 -6
  70. package/lib/helper/scripts/focusElement.js +6 -6
  71. package/lib/helper/scripts/highlightElement.js +9 -9
  72. package/lib/helper/scripts/isElementClickable.js +34 -34
  73. package/lib/helper.js +2 -1
  74. package/lib/history.js +23 -20
  75. package/lib/hooks.js +10 -10
  76. package/lib/html.js +90 -100
  77. package/lib/index.js +48 -21
  78. package/lib/listener/config.js +8 -9
  79. package/lib/listener/emptyRun.js +6 -7
  80. package/lib/listener/exit.js +4 -3
  81. package/lib/listener/globalRetry.js +5 -5
  82. package/lib/listener/globalTimeout.js +11 -10
  83. package/lib/listener/helpers.js +33 -14
  84. package/lib/listener/mocha.js +3 -4
  85. package/lib/listener/result.js +4 -5
  86. package/lib/listener/steps.js +7 -18
  87. package/lib/listener/store.js +3 -3
  88. package/lib/locator.js +213 -192
  89. package/lib/mocha/asyncWrapper.js +108 -75
  90. package/lib/mocha/bdd.js +99 -13
  91. package/lib/mocha/cli.js +60 -27
  92. package/lib/mocha/factory.js +75 -19
  93. package/lib/mocha/featureConfig.js +1 -1
  94. package/lib/mocha/gherkin.js +57 -25
  95. package/lib/mocha/hooks.js +12 -3
  96. package/lib/mocha/index.js +13 -4
  97. package/lib/mocha/inject.js +22 -5
  98. package/lib/mocha/scenarioConfig.js +2 -2
  99. package/lib/mocha/suite.js +9 -2
  100. package/lib/mocha/test.js +10 -13
  101. package/lib/mocha/ui.js +28 -31
  102. package/lib/output.js +11 -9
  103. package/lib/parser.js +44 -44
  104. package/lib/pause.js +15 -16
  105. package/lib/plugin/analyze.js +19 -12
  106. package/lib/plugin/auth.js +20 -21
  107. package/lib/plugin/autoDelay.js +12 -8
  108. package/lib/plugin/coverage.js +12 -8
  109. package/lib/plugin/customLocator.js +3 -3
  110. package/lib/plugin/customReporter.js +3 -2
  111. package/lib/plugin/heal.js +14 -9
  112. package/lib/plugin/pageInfo.js +10 -10
  113. package/lib/plugin/pauseOnFail.js +4 -3
  114. package/lib/plugin/retryFailedStep.js +47 -5
  115. package/lib/plugin/screenshotOnFail.js +75 -37
  116. package/lib/plugin/stepByStepReport.js +14 -14
  117. package/lib/plugin/stepTimeout.js +4 -3
  118. package/lib/plugin/subtitles.js +6 -5
  119. package/lib/recorder.js +33 -23
  120. package/lib/rerun.js +69 -26
  121. package/lib/result.js +4 -4
  122. package/lib/secret.js +18 -17
  123. package/lib/session.js +95 -89
  124. package/lib/step/base.js +6 -6
  125. package/lib/step/config.js +1 -1
  126. package/lib/step/func.js +3 -3
  127. package/lib/step/helper.js +3 -3
  128. package/lib/step/meta.js +4 -4
  129. package/lib/step/record.js +11 -11
  130. package/lib/step/retry.js +3 -3
  131. package/lib/step/section.js +3 -3
  132. package/lib/step.js +7 -10
  133. package/lib/steps.js +9 -5
  134. package/lib/store.js +1 -1
  135. package/lib/timeout.js +1 -7
  136. package/lib/transform.js +8 -8
  137. package/lib/translation.js +32 -18
  138. package/lib/utils.js +68 -97
  139. package/lib/workerStorage.js +16 -17
  140. package/lib/workers.js +145 -171
  141. package/package.json +58 -55
  142. package/translations/de-DE.js +2 -2
  143. package/translations/fr-FR.js +2 -2
  144. package/translations/index.js +23 -10
  145. package/translations/it-IT.js +2 -2
  146. package/translations/ja-JP.js +2 -2
  147. package/translations/nl-NL.js +2 -2
  148. package/translations/pl-PL.js +2 -2
  149. package/translations/pt-BR.js +2 -2
  150. package/translations/ru-RU.js +2 -2
  151. package/translations/utils.js +4 -3
  152. package/translations/zh-CN.js +2 -2
  153. package/translations/zh-TW.js +2 -2
  154. package/typings/index.d.ts +7 -18
  155. package/typings/promiseBasedTypes.d.ts +3769 -5450
  156. package/typings/types.d.ts +3953 -5778
  157. package/bin/test-server.js +0 -53
  158. package/lib/element/WebElement.js +0 -327
  159. package/lib/helper/Nightmare.js +0 -1486
  160. package/lib/helper/Protractor.js +0 -1840
  161. package/lib/helper/TestCafe.js +0 -1391
  162. package/lib/helper/clientscripts/nightmare.js +0 -213
  163. package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
  164. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  165. package/lib/helper/testcafe/testcafe-utils.js +0 -61
  166. package/lib/listener/retryEnhancer.js +0 -85
  167. package/lib/plugin/allure.js +0 -15
  168. package/lib/plugin/autoLogin.js +0 -5
  169. package/lib/plugin/commentStep.js +0 -141
  170. package/lib/plugin/eachElement.js +0 -127
  171. package/lib/plugin/fakerTransform.js +0 -49
  172. package/lib/plugin/htmlReporter.js +0 -1947
  173. package/lib/plugin/retryTo.js +0 -16
  174. package/lib/plugin/selenoid.js +0 -364
  175. package/lib/plugin/standardActingHelpers.js +0 -6
  176. package/lib/plugin/tryTo.js +0 -16
  177. package/lib/plugin/wdio.js +0 -247
  178. package/lib/test-server.js +0 -323
  179. package/lib/within.js +0 -90
package/lib/step/retry.js CHANGED
@@ -1,5 +1,5 @@
1
- const recorder = require('../recorder')
2
- const event = require('../event')
1
+ import recorder from '../recorder.js'
2
+ import event from '../event.js'
3
3
 
4
4
  function retryStep(opts) {
5
5
  if (opts === undefined) opts = 1
@@ -8,4 +8,4 @@ function retryStep(opts) {
8
8
  recorder.add(() => event.dispatcher.once(event.step.finished, () => recorder.retries.pop()))
9
9
  }
10
10
 
11
- module.exports = retryStep
11
+ export default retryStep
@@ -1,5 +1,5 @@
1
- const MetaStep = require('./meta')
2
- const event = require('../event')
1
+ import MetaStep from './meta.js'
2
+ import event from '../event.js'
3
3
 
4
4
  let currentSection
5
5
 
@@ -52,4 +52,4 @@ function getRootMetaStep(step) {
52
52
  return step
53
53
  }
54
54
 
55
- module.exports = Section
55
+ export default Section
package/lib/step.js CHANGED
@@ -3,24 +3,21 @@
3
3
  * Step is wrapper around a helper method.
4
4
  * It is used to create a new step that is a combination of other steps.
5
5
  */
6
- const BaseStep = require('./step/base')
7
- const StepConfig = require('./step/config')
8
- const Step = require('./step/helper')
6
+ import BaseStep from './step/base.js'
7
+ import StepConfig from './step/config.js'
8
+ import Step from './step/helper.js'
9
9
 
10
10
  /**
11
11
  * MetaStep is a step that is used to wrap other steps.
12
12
  * It is used to create a new step that is a combination of other steps.
13
13
  * It is used to create a new step that is a combination of other steps.
14
14
  */
15
- const MetaStep = require('./step/meta')
15
+ import MetaStep from './step/meta.js'
16
16
 
17
17
  /**
18
18
  * Step used to execute a single function
19
19
  */
20
- const FuncStep = require('./step/func')
20
+ import FuncStep from './step/func.js'
21
21
 
22
- module.exports = Step
23
- module.exports.MetaStep = MetaStep
24
- module.exports.BaseStep = BaseStep
25
- module.exports.StepConfig = StepConfig
26
- module.exports.FuncStep = FuncStep
22
+ export default Step
23
+ export { MetaStep, BaseStep, StepConfig, FuncStep }
package/lib/steps.js CHANGED
@@ -1,5 +1,5 @@
1
- const StepConfig = require('./step/config')
2
- const Section = require('./step/section')
1
+ import StepConfig from './step/config.js'
2
+ import SectionClass from './step/section.js'
3
3
  function stepOpts(opts = {}) {
4
4
  return new StepConfig(opts)
5
5
  }
@@ -14,11 +14,11 @@ function stepRetry(retry) {
14
14
 
15
15
  function section(name) {
16
16
  if (!name) return endSection()
17
- return new Section(name).start()
17
+ return new SectionClass(name).start()
18
18
  }
19
19
 
20
20
  function endSection() {
21
- return Section.current().end()
21
+ return SectionClass.current().end()
22
22
  }
23
23
 
24
24
  // Section function to be added here
@@ -47,4 +47,8 @@ const step = {
47
47
  Then: () => section('Then'),
48
48
  }
49
49
 
50
- module.exports = step
50
+ export default step
51
+
52
+ // Named exports for ESM compatibility
53
+ export const Section = step.Section
54
+ export const EndSection = step.EndSection
package/lib/store.js CHANGED
@@ -43,4 +43,4 @@ const store = {
43
43
  currentSuite: null,
44
44
  }
45
45
 
46
- module.exports = store
46
+ export default store
package/lib/timeout.js CHANGED
@@ -57,10 +57,4 @@ class StepTimeoutError extends TimeoutError {
57
57
  }
58
58
  }
59
59
 
60
- module.exports = {
61
- TIMEOUT_ORDER,
62
- getCurrentTimeout,
63
- TimeoutError,
64
- TestTimeoutError,
65
- StepTimeoutError,
66
- }
60
+ export { TIMEOUT_ORDER, getCurrentTimeout, TimeoutError, TestTimeoutError, StepTimeoutError }
package/lib/transform.js CHANGED
@@ -1,26 +1,26 @@
1
1
  const transformers = {
2
2
  'gherkin.examples': [],
3
- };
3
+ }
4
4
 
5
5
  function transform(target, value) {
6
6
  if (target in transformers) {
7
7
  for (const transform of transformers[target]) {
8
- value = transform(value);
8
+ value = transform(value)
9
9
  }
10
10
  }
11
- return value;
11
+ return value
12
12
  }
13
13
 
14
14
  transform.addTransformer = function (target, transformer) {
15
15
  if (target in transformers) {
16
- transformers[target].push(transformer);
16
+ transformers[target].push(transformer)
17
17
  }
18
- };
18
+ }
19
19
 
20
20
  transform.addTransformerBeforeAll = function (target, transformer) {
21
21
  if (target in transformers) {
22
- transformers[target].unshift(transformer);
22
+ transformers[target].unshift(transformer)
23
23
  }
24
- };
24
+ }
25
25
 
26
- module.exports = transform;
26
+ export default transform
@@ -1,55 +1,69 @@
1
- const merge = require('lodash.merge');
2
- const path = require('path');
1
+ import merge from 'lodash.merge'
2
+ import path from 'path'
3
+ import { createRequire } from 'module'
3
4
 
4
5
  const defaultVocabulary = {
5
6
  I: 'I',
6
7
  actions: {},
7
- };
8
+ }
8
9
 
9
10
  class Translation {
10
11
  constructor(vocabulary, loaded) {
11
- this.vocabulary = vocabulary;
12
- this.loaded = loaded !== false;
12
+ this.vocabulary = vocabulary
13
+ this.loaded = loaded !== false
13
14
  }
14
15
 
15
16
  loadVocabulary(vocabularyFile) {
16
- if (!vocabularyFile) return;
17
- const filePath = path.join(global.codecept_dir, vocabularyFile);
17
+ if (!vocabularyFile) return
18
+ const filePath = path.join(global.codecept_dir, vocabularyFile)
18
19
 
19
20
  try {
20
- const vocabulary = require(filePath);
21
- this.vocabulary = merge(this.vocabulary, vocabulary);
21
+ const require = createRequire(import.meta.url)
22
+ const vocabulary = require(filePath)
23
+ this.vocabulary = merge(this.vocabulary, vocabulary)
22
24
  } catch (err) {
23
- throw new Error(`Can't load vocabulary from ${filePath}; ${err}`);
25
+ throw new Error(`Can't load vocabulary from ${filePath}; ${err}`)
24
26
  }
25
27
  }
26
28
 
27
29
  value(val) {
28
- return this.vocabulary[val];
30
+ return this.vocabulary[val]
29
31
  }
30
32
 
31
33
  actionAliasFor(actualActionName) {
32
34
  if (this.vocabulary.actions && this.vocabulary.actions[actualActionName]) {
33
- return this.vocabulary.actions[actualActionName];
35
+ return this.vocabulary.actions[actualActionName]
34
36
  }
35
- return actualActionName;
37
+ return actualActionName
36
38
  }
37
39
 
38
40
  get I() {
39
- return this.vocabulary.I;
41
+ return this.vocabulary.I
42
+ }
43
+
44
+ static async getLangs() {
45
+ const translations = await import('../translations/index.js')
46
+ return translations.default
40
47
  }
41
48
 
42
49
  static get langs() {
43
- return require('../translations');
50
+ // Synchronous fallback - may be empty initially
51
+ if (!this._cachedLangs) {
52
+ this.getLangs().then(langs => {
53
+ this._cachedLangs = langs
54
+ })
55
+ return {}
56
+ }
57
+ return this._cachedLangs
44
58
  }
45
59
 
46
60
  static createDefault() {
47
- return new Translation(defaultVocabulary, true);
61
+ return new Translation(defaultVocabulary, true)
48
62
  }
49
63
 
50
64
  static createEmpty() {
51
- return new Translation(defaultVocabulary, false);
65
+ return new Translation(defaultVocabulary, false)
52
66
  }
53
67
  }
54
68
 
55
- module.exports = Translation;
69
+ export default Translation
package/lib/utils.js CHANGED
@@ -1,44 +1,47 @@
1
- const fs = require('fs')
2
- const os = require('os')
3
- const path = require('path')
4
- const chalk = require('chalk')
5
- const getFunctionArguments = require('fn-args')
6
- const deepClone = require('lodash.clonedeep')
7
- const { convertColorToRGBA, isColorProperty } = require('./colorUtils')
8
- const Fuse = require('fuse.js')
9
- const { spawnSync } = require('child_process')
1
+ import fs from 'fs'
2
+ import os from 'os'
3
+ import path from 'path'
4
+ import chalk from 'chalk'
5
+ import getFunctionArguments from 'fn-args'
6
+ import deepClone from 'lodash.clonedeep'
7
+ import merge from 'lodash.merge'
8
+ import { convertColorToRGBA, isColorProperty } from './colorUtils.js'
9
+ import Fuse from 'fuse.js'
10
+ import crypto from 'crypto'
11
+ import jsBeautify from 'js-beautify'
12
+ import childProcess from 'child_process'
13
+ import { createRequire } from 'module'
10
14
 
11
15
  function deepMerge(target, source) {
12
- const merge = require('lodash.merge')
13
16
  return merge(target, source)
14
17
  }
15
18
 
16
- module.exports.genTestId = test => {
17
- return this.clearString(require('crypto').createHash('sha256').update(test.fullTitle()).digest('base64').slice(0, -2))
19
+ export const genTestId = test => {
20
+ return clearString(crypto.createHash('sha256').update(test.fullTitle()).digest('base64').slice(0, -2))
18
21
  }
19
22
 
20
- module.exports.deepMerge = deepMerge
23
+ export { deepMerge }
21
24
 
22
- module.exports.deepClone = deepClone
25
+ export { deepClone }
23
26
 
24
- module.exports.isGenerator = function (fn) {
27
+ export const isGenerator = function (fn) {
25
28
  return fn.constructor.name === 'GeneratorFunction'
26
29
  }
27
30
 
28
- const isFunction = (module.exports.isFunction = function (fn) {
31
+ export const isFunction = function (fn) {
29
32
  return typeof fn === 'function'
30
- })
33
+ }
31
34
 
32
- const isAsyncFunction = (module.exports.isAsyncFunction = function (fn) {
35
+ export const isAsyncFunction = function (fn) {
33
36
  if (!fn) return false
34
37
  return fn[Symbol.toStringTag] === 'AsyncFunction'
35
- })
38
+ }
36
39
 
37
- module.exports.fileExists = function (filePath) {
40
+ export const fileExists = function (filePath) {
38
41
  return fs.existsSync(filePath)
39
42
  }
40
43
 
41
- module.exports.isFile = function (filePath) {
44
+ export const isFile = function (filePath) {
42
45
  let filestat
43
46
  try {
44
47
  filestat = fs.statSync(filePath)
@@ -49,16 +52,16 @@ module.exports.isFile = function (filePath) {
49
52
  return filestat.isFile()
50
53
  }
51
54
 
52
- module.exports.getParamNames = function (fn) {
55
+ export const getParamNames = function (fn) {
53
56
  if (fn.isSinonProxy) return []
54
57
  return getFunctionArguments(fn)
55
58
  }
56
59
 
57
- module.exports.installedLocally = function () {
58
- return path.resolve(`${__dirname}/../`).indexOf(process.cwd()) === 0
60
+ export const installedLocally = function () {
61
+ return path.resolve(`${new URL(import.meta.url).pathname}/../../`).indexOf(process.cwd()) === 0
59
62
  }
60
63
 
61
- module.exports.methodsOfObject = function (obj, className) {
64
+ export const methodsOfObject = function (obj, className) {
62
65
  const methods = []
63
66
 
64
67
  const standard = ['constructor', 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'bind', 'apply', 'call', 'isPrototypeOf', 'propertyIsEnumerable']
@@ -84,7 +87,7 @@ module.exports.methodsOfObject = function (obj, className) {
84
87
  return methods
85
88
  }
86
89
 
87
- module.exports.template = function (template, data) {
90
+ export const template = function (template, data) {
88
91
  return template.replace(/{{([^{}]*)}}/g, (a, b) => {
89
92
  const r = data[b]
90
93
  if (r === undefined) return ''
@@ -97,7 +100,7 @@ module.exports.template = function (template, data) {
97
100
  * @param {string} str
98
101
  * @returns {string | undefined}
99
102
  */
100
- module.exports.ucfirst = function (str) {
103
+ export const ucfirst = function (str) {
101
104
  if (str) return str.charAt(0).toUpperCase() + str.substr(1)
102
105
  }
103
106
 
@@ -106,11 +109,11 @@ module.exports.ucfirst = function (str) {
106
109
  * @param {string} str
107
110
  * @returns {string | undefined}
108
111
  */
109
- module.exports.lcfirst = function (str) {
112
+ export const lcfirst = function (str) {
110
113
  if (str) return str.charAt(0).toLowerCase() + str.substr(1)
111
114
  }
112
115
 
113
- module.exports.chunkArray = function (arr, chunk) {
116
+ export const chunkArray = function (arr, chunk) {
114
117
  let i
115
118
  let j
116
119
  const tmp = []
@@ -120,7 +123,7 @@ module.exports.chunkArray = function (arr, chunk) {
120
123
  return tmp
121
124
  }
122
125
 
123
- module.exports.clearString = function (str) {
126
+ export const clearString = function (str) {
124
127
  if (!str) return ''
125
128
  /* Replace forbidden symbols in string
126
129
  */
@@ -141,13 +144,13 @@ module.exports.clearString = function (str) {
141
144
  .replace(/'/g, '')
142
145
  }
143
146
 
144
- module.exports.decodeUrl = function (url) {
147
+ export const decodeUrl = function (url) {
145
148
  /* Replace forbidden symbols in string
146
149
  */
147
150
  return decodeURIComponent(decodeURIComponent(decodeURIComponent(url)))
148
151
  }
149
152
 
150
- module.exports.xpathLocator = {
153
+ export const xpathLocator = {
151
154
  /**
152
155
  * @param {string} string
153
156
  * @returns {string}
@@ -171,7 +174,7 @@ module.exports.xpathLocator = {
171
174
  combine: locators => locators.join(' | '),
172
175
  }
173
176
 
174
- module.exports.test = {
177
+ export const test = {
175
178
  grepLines(array, startString, endString) {
176
179
  let startIndex = 0
177
180
  let endIndex
@@ -192,39 +195,8 @@ module.exports.test = {
192
195
  submittedData(dataFile) {
193
196
  return function (key) {
194
197
  if (!fs.existsSync(dataFile)) {
195
- // Extended timeout for CI environments to handle slower processing
196
- const waitTime = process.env.CI ? 60 * 1000 : 2 * 1000 // 60 seconds in CI, 2 seconds otherwise
197
- let pollInterval = 100 // Start with 100ms polling interval
198
- const maxPollInterval = 2000 // Max 2 second intervals
199
- const startTime = new Date().getTime()
200
-
201
- // Synchronous polling with exponential backoff to reduce CPU usage
202
- while (new Date().getTime() - startTime < waitTime) {
203
- if (fs.existsSync(dataFile)) {
204
- break
205
- }
206
-
207
- // Use Node.js child_process.spawnSync with platform-specific sleep commands
208
- // This avoids busy waiting and allows other processes to run
209
- try {
210
- if (os.platform() === 'win32') {
211
- // Windows: use ping with precise timing (ping waits exactly the specified ms)
212
- spawnSync('ping', ['-n', '1', '-w', pollInterval.toString(), '127.0.0.1'], { stdio: 'ignore' })
213
- } else {
214
- // Unix/Linux/macOS: use sleep with fractional seconds
215
- spawnSync('sleep', [(pollInterval / 1000).toString()], { stdio: 'ignore' })
216
- }
217
- } catch (err) {
218
- // If system commands fail, use a simple busy wait with minimal CPU usage
219
- const end = new Date().getTime() + pollInterval
220
- while (new Date().getTime() < end) {
221
- // No-op loop - much lighter than previous approaches
222
- }
223
- }
224
-
225
- // Exponential backoff: gradually increase polling interval to reduce resource usage
226
- pollInterval = Math.min(pollInterval * 1.2, maxPollInterval)
227
- }
198
+ const waitTill = new Date(new Date().getTime() + 1 * 1000) // wait for one sec for file to be created
199
+ while (waitTill > new Date()) {}
228
200
  }
229
201
  if (!fs.existsSync(dataFile)) {
230
202
  throw new Error('Data file was not created in time')
@@ -238,7 +210,7 @@ module.exports.test = {
238
210
  },
239
211
  }
240
212
 
241
- function toCamelCase(name) {
213
+ export const toCamelCase = function (name) {
242
214
  if (typeof name !== 'string') {
243
215
  return name
244
216
  }
@@ -246,7 +218,6 @@ function toCamelCase(name) {
246
218
  return letter.toUpperCase()
247
219
  })
248
220
  }
249
- module.exports.toCamelCase = toCamelCase
250
221
 
251
222
  function convertFontWeightToNumber(name) {
252
223
  const fontWeightPatterns = [
@@ -277,7 +248,7 @@ function isFontWeightProperty(prop) {
277
248
  return prop === 'fontWeight'
278
249
  }
279
250
 
280
- module.exports.convertCssPropertiesToCamelCase = function (props) {
251
+ export const convertCssPropertiesToCamelCase = function (props) {
281
252
  const output = {}
282
253
  Object.keys(props).forEach(key => {
283
254
  const keyCamel = toCamelCase(key)
@@ -293,12 +264,12 @@ module.exports.convertCssPropertiesToCamelCase = function (props) {
293
264
  return output
294
265
  }
295
266
 
296
- module.exports.deleteDir = function (dir_path) {
267
+ export const deleteDir = function (dir_path) {
297
268
  if (fs.existsSync(dir_path)) {
298
269
  fs.readdirSync(dir_path).forEach(function (entry) {
299
270
  const entry_path = path.join(dir_path, entry)
300
271
  if (fs.lstatSync(entry_path).isDirectory()) {
301
- this.deleteDir(entry_path)
272
+ deleteDir(entry_path)
302
273
  } else {
303
274
  fs.unlinkSync(entry_path)
304
275
  }
@@ -311,7 +282,7 @@ module.exports.deleteDir = function (dir_path) {
311
282
  * Returns absolute filename to save screenshot.
312
283
  * @param fileName {string} - filename.
313
284
  */
314
- module.exports.screenshotOutputFolder = function (fileName) {
285
+ export const screenshotOutputFolder = function (fileName) {
315
286
  const fileSep = path.sep
316
287
 
317
288
  if (!fileName.includes(fileSep) || fileName.includes('record_')) {
@@ -320,12 +291,12 @@ module.exports.screenshotOutputFolder = function (fileName) {
320
291
  return path.resolve(global.codecept_dir, fileName)
321
292
  }
322
293
 
323
- module.exports.relativeDir = function (fileName) {
294
+ export const relativeDir = function (fileName) {
324
295
  return fileName.replace(global.codecept_dir, '').replace(/^\//, '')
325
296
  }
326
297
 
327
- module.exports.beautify = function (code) {
328
- const format = require('js-beautify').js
298
+ export const beautify = function (code) {
299
+ const format = jsBeautify.js
329
300
  return format(code, { indent_size: 2, space_in_empty_paren: true })
330
301
  }
331
302
 
@@ -345,7 +316,7 @@ function joinUrl(baseUrl, url) {
345
316
  return shouldAppendBaseUrl(url) ? `${baseUrl}/${trimUrl(url)}` : url
346
317
  }
347
318
 
348
- module.exports.appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
319
+ export const appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
349
320
  if (typeof baseUrl !== 'string') {
350
321
  throw new Error(`Invalid value for baseUrl: ${baseUrl}`)
351
322
  }
@@ -371,7 +342,7 @@ module.exports.appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
371
342
  * @param {string} key key to search
372
343
  * @param {*} value value to set for key
373
344
  */
374
- module.exports.replaceValueDeep = function replaceValueDeep(obj, key, value) {
345
+ export const replaceValueDeep = function replaceValueDeep(obj, key, value) {
375
346
  if (!obj) return
376
347
 
377
348
  if (obj instanceof Array) {
@@ -393,13 +364,13 @@ module.exports.replaceValueDeep = function replaceValueDeep(obj, key, value) {
393
364
  return obj
394
365
  }
395
366
 
396
- module.exports.ansiRegExp = function ({ onlyFirst = false } = {}) {
367
+ export const ansiRegExp = function ({ onlyFirst = false } = {}) {
397
368
  const pattern = ['[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'].join('|')
398
369
 
399
370
  return new RegExp(pattern, onlyFirst ? undefined : 'g')
400
371
  }
401
372
 
402
- module.exports.tryOrDefault = function (fn, defaultValue) {
373
+ export const tryOrDefault = function (fn, defaultValue) {
403
374
  try {
404
375
  return fn()
405
376
  } catch (_) {
@@ -426,7 +397,7 @@ function normalizeKeyReplacer(match, prefix, key, suffix, offset, string) {
426
397
  * @param {string} key
427
398
  * @returns {string}
428
399
  */
429
- module.exports.getNormalizedKeyAttributeValue = function (key) {
400
+ export const getNormalizedKeyAttributeValue = function (key) {
430
401
  // Use operation modifier key based on operating system
431
402
  key = key.replace(/(Ctrl|Control|Cmd|Command)[ _]?Or[ _]?(Ctrl|Control|Cmd|Command)/i, os.platform() === 'darwin' ? 'Meta' : 'Control')
432
403
  // Selection of keys (https://www.w3.org/TR/uievents-key/#named-key-attribute-values)
@@ -443,14 +414,14 @@ module.exports.getNormalizedKeyAttributeValue = function (key) {
443
414
  return key
444
415
  }
445
416
 
446
- const modifierKeys = ['Alt', 'AltGraph', 'AltLeft', 'AltRight', 'Control', 'ControlLeft', 'ControlRight', 'Meta', 'MetaLeft', 'MetaRight', 'Shift', 'ShiftLeft', 'ShiftRight']
447
-
448
- module.exports.modifierKeys = modifierKeys
449
- module.exports.isModifierKey = function (key) {
417
+ export const modifierKeys = ['Alt', 'AltGraph', 'AltLeft', 'AltRight', 'Control', 'ControlLeft', 'ControlRight', 'Meta', 'MetaLeft', 'MetaRight', 'Shift', 'ShiftLeft', 'ShiftRight']
418
+ export const isModifierKey = function (key) {
450
419
  return modifierKeys.includes(key)
451
420
  }
452
421
 
453
- module.exports.requireWithFallback = function (...packages) {
422
+ export const requireWithFallback = function (...packages) {
423
+ const require = createRequire(import.meta.url)
424
+
454
425
  const exists = function (pkg) {
455
426
  try {
456
427
  require.resolve(pkg)
@@ -470,17 +441,17 @@ module.exports.requireWithFallback = function (...packages) {
470
441
  throw new Error(`Cannot find modules ${packages.join(',')}`)
471
442
  }
472
443
 
473
- module.exports.isNotSet = function (obj) {
444
+ export const isNotSet = function (obj) {
474
445
  if (obj === null) return true
475
446
  if (obj === undefined) return true
476
447
  return false
477
448
  }
478
449
 
479
- module.exports.emptyFolder = async directoryPath => {
480
- require('child_process').execSync(`rm -rf ${directoryPath}/*`)
450
+ export const emptyFolder = async directoryPath => {
451
+ childProcess.execSync(`rm -rf ${directoryPath}/*`)
481
452
  }
482
453
 
483
- module.exports.printObjectProperties = obj => {
454
+ export const printObjectProperties = obj => {
484
455
  if (typeof obj !== 'object' || obj === null) {
485
456
  return obj
486
457
  }
@@ -493,11 +464,11 @@ module.exports.printObjectProperties = obj => {
493
464
  return `{${result}}`
494
465
  }
495
466
 
496
- module.exports.normalizeSpacesInString = string => {
467
+ export const normalizeSpacesInString = string => {
497
468
  return string.replace(/\s+/g, ' ')
498
469
  }
499
470
 
500
- module.exports.humanizeFunction = function (fn) {
471
+ export const humanizeFunction = function (fn) {
501
472
  const fnStr = fn.toString().trim()
502
473
  // Remove arrow function syntax, async, and parentheses
503
474
  let simplified = fnStr
@@ -559,24 +530,24 @@ module.exports.humanizeFunction = function (fn) {
559
530
  * const results = searchWithFusejs(data, 'lock', options);
560
531
  * console.log(results);
561
532
  */
562
- module.exports.searchWithFusejs = function (source, searchString, opts) {
533
+ export const searchWithFusejs = function (source, searchString, opts) {
563
534
  const fuse = new Fuse(source, opts)
564
535
 
565
536
  return fuse.search(searchString)
566
537
  }
567
538
 
568
- module.exports.humanizeString = function (string) {
539
+ export const humanizeString = function (string) {
569
540
  // split strings by words, then make them all lowercase
570
541
  const _result = string
571
542
  .replace(/([a-z](?=[A-Z]))/g, '$1 ')
572
543
  .split(' ')
573
544
  .map(word => word.toLowerCase())
574
545
 
575
- _result[0] = _result[0] === 'i' ? this.ucfirst(_result[0]) : _result[0]
546
+ _result[0] = _result[0] === 'i' ? ucfirst(_result[0]) : _result[0]
576
547
  return _result.join(' ').trim()
577
548
  }
578
549
 
579
- module.exports.serializeError = function (error) {
550
+ export const serializeError = function (error) {
580
551
  if (error) {
581
552
  const { stack, uncaught, message, actual, expected } = error
582
553
  return { stack, uncaught, message, actual, expected }
@@ -584,11 +555,11 @@ module.exports.serializeError = function (error) {
584
555
  return null
585
556
  }
586
557
 
587
- module.exports.base64EncodeFile = function (filePath) {
558
+ export const base64EncodeFile = function (filePath) {
588
559
  return Buffer.from(fs.readFileSync(filePath)).toString('base64')
589
560
  }
590
561
 
591
- module.exports.markdownToAnsi = function (markdown) {
562
+ export const markdownToAnsi = function (markdown) {
592
563
  return (
593
564
  markdown
594
565
  // Headers (# Text) - make blue and bold