codeceptjs 4.0.0-beta.5 → 4.0.0-beta.6.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.
- package/README.md +0 -45
- package/bin/codecept.js +46 -57
- package/lib/actor.js +15 -11
- package/lib/ai.js +6 -5
- package/lib/assert/empty.js +9 -8
- package/lib/assert/equal.js +15 -17
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +9 -11
- package/lib/assert/throws.js +1 -1
- package/lib/assert/truth.js +8 -5
- package/lib/assert.js +18 -18
- package/lib/codecept.js +66 -107
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +32 -27
- package/lib/command/configMigrate.js +11 -10
- package/lib/command/definitions.js +16 -10
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +29 -26
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +14 -14
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +8 -8
- package/lib/command/init.js +34 -31
- package/lib/command/interactive.js +11 -10
- package/lib/command/list.js +10 -9
- package/lib/command/run-multiple/chunk.js +5 -5
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +16 -13
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +10 -24
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +20 -18
- package/lib/command/workers/runTests.js +117 -269
- package/lib/config.js +111 -49
- package/lib/container.js +299 -102
- package/lib/data/context.js +6 -5
- package/lib/data/dataScenarioConfig.js +1 -1
- package/lib/data/dataTableArgument.js +1 -1
- package/lib/data/table.js +1 -1
- package/lib/effects.js +94 -10
- package/lib/els.js +11 -9
- package/lib/event.js +11 -10
- package/lib/globals.js +141 -0
- package/lib/heal.js +12 -12
- package/lib/helper/AI.js +1 -1
- package/lib/helper/ApiDataFactory.js +16 -13
- package/lib/helper/FileSystem.js +32 -12
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +1 -1
- package/lib/helper/JSONResponse.js +19 -30
- package/lib/helper/Mochawesome.js +9 -28
- package/lib/helper/Playwright.js +668 -265
- package/lib/helper/Puppeteer.js +284 -169
- package/lib/helper/REST.js +29 -12
- package/lib/helper/WebDriver.js +191 -71
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +33 -48
- package/lib/helper/network/utils.js +76 -83
- package/lib/helper/scripts/blurElement.js +6 -6
- package/lib/helper/scripts/focusElement.js +6 -6
- package/lib/helper/scripts/highlightElement.js +9 -9
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -1
- package/lib/history.js +23 -20
- package/lib/hooks.js +10 -10
- package/lib/html.js +90 -100
- package/lib/index.js +48 -21
- package/lib/listener/config.js +8 -9
- package/lib/listener/emptyRun.js +6 -7
- package/lib/listener/exit.js +4 -3
- package/lib/listener/globalRetry.js +5 -5
- package/lib/listener/globalTimeout.js +11 -10
- package/lib/listener/helpers.js +33 -14
- package/lib/listener/mocha.js +3 -4
- package/lib/listener/result.js +4 -5
- package/lib/listener/steps.js +7 -18
- package/lib/listener/store.js +3 -3
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +108 -75
- package/lib/mocha/bdd.js +99 -13
- package/lib/mocha/cli.js +60 -27
- package/lib/mocha/factory.js +75 -19
- package/lib/mocha/featureConfig.js +1 -1
- package/lib/mocha/gherkin.js +57 -25
- package/lib/mocha/hooks.js +12 -3
- package/lib/mocha/index.js +13 -4
- package/lib/mocha/inject.js +22 -5
- package/lib/mocha/scenarioConfig.js +2 -2
- package/lib/mocha/suite.js +9 -2
- package/lib/mocha/test.js +10 -13
- package/lib/mocha/ui.js +28 -31
- package/lib/output.js +11 -9
- package/lib/parser.js +44 -44
- package/lib/pause.js +15 -16
- package/lib/plugin/analyze.js +19 -12
- package/lib/plugin/auth.js +20 -21
- package/lib/plugin/autoDelay.js +12 -8
- package/lib/plugin/coverage.js +12 -8
- package/lib/plugin/customLocator.js +3 -3
- package/lib/plugin/customReporter.js +3 -2
- package/lib/plugin/heal.js +14 -9
- package/lib/plugin/pageInfo.js +10 -10
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +47 -5
- package/lib/plugin/screenshotOnFail.js +75 -37
- package/lib/plugin/stepByStepReport.js +14 -14
- package/lib/plugin/stepTimeout.js +4 -3
- package/lib/plugin/subtitles.js +6 -5
- package/lib/recorder.js +33 -23
- package/lib/rerun.js +69 -26
- package/lib/result.js +4 -4
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +6 -6
- package/lib/step/config.js +1 -1
- package/lib/step/func.js +3 -3
- package/lib/step/helper.js +3 -3
- package/lib/step/meta.js +4 -4
- package/lib/step/record.js +11 -11
- package/lib/step/retry.js +3 -3
- package/lib/step/section.js +3 -3
- package/lib/step.js +7 -10
- package/lib/steps.js +9 -5
- package/lib/store.js +1 -1
- package/lib/timeout.js +1 -7
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +68 -97
- package/lib/workerStorage.js +16 -17
- package/lib/workers.js +145 -171
- package/package.json +63 -57
- package/translations/de-DE.js +2 -2
- package/translations/fr-FR.js +2 -2
- package/translations/index.js +23 -10
- package/translations/it-IT.js +2 -2
- package/translations/ja-JP.js +2 -2
- package/translations/nl-NL.js +2 -2
- package/translations/pl-PL.js +2 -2
- package/translations/pt-BR.js +2 -2
- package/translations/ru-RU.js +2 -2
- package/translations/utils.js +11 -2
- package/translations/zh-CN.js +2 -2
- package/translations/zh-TW.js +2 -2
- package/typings/index.d.ts +7 -18
- package/typings/promiseBasedTypes.d.ts +3769 -5450
- package/typings/types.d.ts +3953 -5778
- package/bin/test-server.js +0 -53
- package/lib/element/WebElement.js +0 -327
- package/lib/helper/Nightmare.js +0 -1486
- package/lib/helper/Protractor.js +0 -1840
- package/lib/helper/TestCafe.js +0 -1391
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -61
- package/lib/listener/retryEnhancer.js +0 -85
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/autoLogin.js +0 -5
- package/lib/plugin/commentStep.js +0 -141
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/htmlReporter.js +0 -1947
- package/lib/plugin/retryTo.js +0 -16
- package/lib/plugin/selenoid.js +0 -364
- package/lib/plugin/standardActingHelpers.js +0 -6
- package/lib/plugin/tryTo.js +0 -16
- package/lib/plugin/wdio.js +0 -247
- package/lib/test-server.js +0 -323
- package/lib/within.js +0 -90
package/lib/step/retry.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
11
|
+
export default retryStep
|
package/lib/step/section.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
15
|
+
import MetaStep from './step/meta.js'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Step used to execute a single function
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
import FuncStep from './step/func.js'
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
2
|
-
|
|
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
|
|
17
|
+
return new SectionClass(name).start()
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function endSection() {
|
|
21
|
-
return
|
|
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
|
-
|
|
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
package/lib/timeout.js
CHANGED
|
@@ -57,10 +57,4 @@ class StepTimeoutError extends TimeoutError {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
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
|
-
|
|
26
|
+
export default transform
|
package/lib/translation.js
CHANGED
|
@@ -1,55 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
69
|
+
export default Translation
|
package/lib/utils.js
CHANGED
|
@@ -1,44 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
17
|
-
return
|
|
19
|
+
export const genTestId = test => {
|
|
20
|
+
return clearString(crypto.createHash('sha256').update(test.fullTitle()).digest('base64').slice(0, -2))
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
export { deepMerge }
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
export { deepClone }
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
export const isGenerator = function (fn) {
|
|
25
28
|
return fn.constructor.name === 'GeneratorFunction'
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
const isFunction =
|
|
31
|
+
export const isFunction = function (fn) {
|
|
29
32
|
return typeof fn === 'function'
|
|
30
|
-
}
|
|
33
|
+
}
|
|
31
34
|
|
|
32
|
-
const isAsyncFunction =
|
|
35
|
+
export const isAsyncFunction = function (fn) {
|
|
33
36
|
if (!fn) return false
|
|
34
37
|
return fn[Symbol.toStringTag] === 'AsyncFunction'
|
|
35
|
-
}
|
|
38
|
+
}
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
export const fileExists = function (filePath) {
|
|
38
41
|
return fs.existsSync(filePath)
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
|
|
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
|
-
|
|
55
|
+
export const getParamNames = function (fn) {
|
|
53
56
|
if (fn.isSinonProxy) return []
|
|
54
57
|
return getFunctionArguments(fn)
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
return path.resolve(`${
|
|
60
|
+
export const installedLocally = function () {
|
|
61
|
+
return path.resolve(`${new URL(import.meta.url).pathname}/../../`).indexOf(process.cwd()) === 0
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
112
|
+
export const lcfirst = function (str) {
|
|
110
113
|
if (str) return str.charAt(0).toLowerCase() + str.substr(1)
|
|
111
114
|
}
|
|
112
115
|
|
|
113
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
196
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
294
|
+
export const relativeDir = function (fileName) {
|
|
324
295
|
return fileName.replace(global.codecept_dir, '').replace(/^\//, '')
|
|
325
296
|
}
|
|
326
297
|
|
|
327
|
-
|
|
328
|
-
const format =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
480
|
-
|
|
450
|
+
export const emptyFolder = async directoryPath => {
|
|
451
|
+
childProcess.execSync(`rm -rf ${directoryPath}/*`)
|
|
481
452
|
}
|
|
482
453
|
|
|
483
|
-
|
|
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
|
-
|
|
467
|
+
export const normalizeSpacesInString = string => {
|
|
497
468
|
return string.replace(/\s+/g, ' ')
|
|
498
469
|
}
|
|
499
470
|
|
|
500
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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' ?
|
|
546
|
+
_result[0] = _result[0] === 'i' ? ucfirst(_result[0]) : _result[0]
|
|
576
547
|
return _result.join(' ').trim()
|
|
577
548
|
}
|
|
578
549
|
|
|
579
|
-
|
|
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
|
-
|
|
558
|
+
export const base64EncodeFile = function (filePath) {
|
|
588
559
|
return Buffer.from(fs.readFileSync(filePath)).toString('base64')
|
|
589
560
|
}
|
|
590
561
|
|
|
591
|
-
|
|
562
|
+
export const markdownToAnsi = function (markdown) {
|
|
592
563
|
return (
|
|
593
564
|
markdown
|
|
594
565
|
// Headers (# Text) - make blue and bold
|