codeceptjs 3.7.6-beta.4 → 4.0.0-beta.10.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 +1 -3
- package/bin/codecept.js +51 -53
- package/bin/test-server.js +14 -3
- package/docs/webapi/click.mustache +5 -1
- package/lib/actor.js +15 -11
- package/lib/ai.js +72 -107
- 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 +102 -75
- 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 +62 -27
- 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 +36 -29
- 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 +24 -9
- package/lib/command/run.js +23 -8
- package/lib/command/utils.js +20 -18
- package/lib/command/workers/runTests.js +197 -114
- package/lib/config.js +124 -51
- package/lib/container.js +438 -87
- 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/element/WebElement.js +2 -2
- 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 +11 -11
- package/lib/helper/ApiDataFactory.js +50 -19
- package/lib/helper/Appium.js +19 -27
- package/lib/helper/FileSystem.js +32 -12
- package/lib/helper/GraphQL.js +3 -3
- package/lib/helper/GraphQLDataFactory.js +4 -4
- package/lib/helper/JSONResponse.js +25 -29
- package/lib/helper/Mochawesome.js +7 -4
- package/lib/helper/Playwright.js +902 -164
- package/lib/helper/Puppeteer.js +383 -76
- package/lib/helper/REST.js +29 -12
- package/lib/helper/WebDriver.js +268 -61
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- 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/PlaywrightReactVueLocator.js +18 -9
- package/lib/helper/extras/PlaywrightRestartOpts.js +34 -23
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +29 -44
- 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 +19 -12
- package/lib/listener/emptyRun.js +6 -7
- package/lib/listener/enhancedGlobalRetry.js +6 -6
- package/lib/listener/exit.js +4 -3
- package/lib/listener/globalRetry.js +5 -5
- package/lib/listener/globalTimeout.js +30 -14
- package/lib/listener/helpers.js +39 -14
- package/lib/listener/mocha.js +3 -4
- package/lib/listener/result.js +4 -5
- package/lib/listener/retryEnhancer.js +3 -3
- package/lib/listener/steps.js +8 -7
- package/lib/listener/store.js +3 -3
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +105 -62
- package/lib/mocha/bdd.js +99 -13
- package/lib/mocha/cli.js +59 -26
- package/lib/mocha/factory.js +78 -19
- package/lib/mocha/featureConfig.js +1 -1
- package/lib/mocha/gherkin.js +56 -24
- 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 -7
- package/lib/mocha/ui.js +28 -18
- package/lib/output.js +10 -8
- 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 +28 -11
- package/lib/plugin/customLocator.js +3 -3
- package/lib/plugin/customReporter.js +3 -2
- package/lib/plugin/enhancedRetryFailedStep.js +6 -6
- package/lib/plugin/heal.js +14 -9
- package/lib/plugin/htmlReporter.js +724 -99
- package/lib/plugin/pageInfo.js +10 -10
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +48 -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 -14
- package/lib/rerun.js +69 -26
- package/lib/result.js +4 -4
- package/lib/retryCoordinator.js +2 -2
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +7 -7
- package/lib/step/comment.js +2 -2
- 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 +5 -5
- 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/template/heal.js +1 -1
- package/lib/template/prompts/generatePageObject.js +31 -0
- package/lib/template/prompts/healStep.js +13 -0
- package/lib/template/prompts/writeStep.js +9 -0
- package/lib/test-server.js +17 -6
- package/lib/timeout.js +1 -7
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils/mask_data.js +4 -10
- package/lib/utils.js +66 -64
- package/lib/workerStorage.js +17 -17
- package/lib/workers.js +214 -84
- package/package.json +41 -37
- 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 +4 -3
- package/translations/zh-CN.js +2 -2
- package/translations/zh-TW.js +2 -2
- package/typings/index.d.ts +5 -3
- package/typings/promiseBasedTypes.d.ts +4 -0
- package/typings/types.d.ts +4 -0
- 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/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -61
- 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/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/within.js +0 -90
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/mask_data.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { maskSensitiveData } from 'invisi-data'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Mask sensitive data utility for CodeceptJS
|
|
@@ -8,7 +8,7 @@ const { maskSensitiveData } = require('invisi-data')
|
|
|
8
8
|
* @param {boolean|object} config - Masking configuration
|
|
9
9
|
* @returns {string} - Masked string
|
|
10
10
|
*/
|
|
11
|
-
function maskData(input, config) {
|
|
11
|
+
export function maskData(input, config) {
|
|
12
12
|
if (!config) {
|
|
13
13
|
return input
|
|
14
14
|
}
|
|
@@ -32,7 +32,7 @@ function maskData(input, config) {
|
|
|
32
32
|
*
|
|
33
33
|
* @returns {boolean|object} - Current masking configuration
|
|
34
34
|
*/
|
|
35
|
-
function getMaskConfig() {
|
|
35
|
+
export function getMaskConfig() {
|
|
36
36
|
return global.maskSensitiveData || false
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -41,13 +41,7 @@ function getMaskConfig() {
|
|
|
41
41
|
*
|
|
42
42
|
* @returns {boolean} - True if masking is enabled
|
|
43
43
|
*/
|
|
44
|
-
function shouldMaskData() {
|
|
44
|
+
export function shouldMaskData() {
|
|
45
45
|
const config = getMaskConfig()
|
|
46
46
|
return config === true || (typeof config === 'object' && config.enabled === true)
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
module.exports = {
|
|
50
|
-
maskData,
|
|
51
|
-
getMaskConfig,
|
|
52
|
-
shouldMaskData,
|
|
53
|
-
}
|
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 { createRequire } from 'module'
|
|
5
|
+
import chalk from 'chalk'
|
|
6
|
+
import getFunctionArguments from 'fn-args'
|
|
7
|
+
import deepClone from 'lodash.clonedeep'
|
|
8
|
+
import merge from 'lodash.merge'
|
|
9
|
+
import { convertColorToRGBA, isColorProperty } from './colorUtils.js'
|
|
10
|
+
import Fuse from 'fuse.js'
|
|
11
|
+
import crypto from 'crypto'
|
|
12
|
+
import jsBeautify from 'js-beautify'
|
|
13
|
+
import { spawnSync } from 'child_process'
|
|
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
|
|
@@ -238,7 +241,7 @@ module.exports.test = {
|
|
|
238
241
|
},
|
|
239
242
|
}
|
|
240
243
|
|
|
241
|
-
function
|
|
244
|
+
export const toCamelCase = function (name) {
|
|
242
245
|
if (typeof name !== 'string') {
|
|
243
246
|
return name
|
|
244
247
|
}
|
|
@@ -246,7 +249,6 @@ function toCamelCase(name) {
|
|
|
246
249
|
return letter.toUpperCase()
|
|
247
250
|
})
|
|
248
251
|
}
|
|
249
|
-
module.exports.toCamelCase = toCamelCase
|
|
250
252
|
|
|
251
253
|
function convertFontWeightToNumber(name) {
|
|
252
254
|
const fontWeightPatterns = [
|
|
@@ -277,7 +279,7 @@ function isFontWeightProperty(prop) {
|
|
|
277
279
|
return prop === 'fontWeight'
|
|
278
280
|
}
|
|
279
281
|
|
|
280
|
-
|
|
282
|
+
export const convertCssPropertiesToCamelCase = function (props) {
|
|
281
283
|
const output = {}
|
|
282
284
|
Object.keys(props).forEach(key => {
|
|
283
285
|
const keyCamel = toCamelCase(key)
|
|
@@ -293,12 +295,12 @@ module.exports.convertCssPropertiesToCamelCase = function (props) {
|
|
|
293
295
|
return output
|
|
294
296
|
}
|
|
295
297
|
|
|
296
|
-
|
|
298
|
+
export const deleteDir = function (dir_path) {
|
|
297
299
|
if (fs.existsSync(dir_path)) {
|
|
298
300
|
fs.readdirSync(dir_path).forEach(function (entry) {
|
|
299
301
|
const entry_path = path.join(dir_path, entry)
|
|
300
302
|
if (fs.lstatSync(entry_path).isDirectory()) {
|
|
301
|
-
|
|
303
|
+
deleteDir(entry_path)
|
|
302
304
|
} else {
|
|
303
305
|
fs.unlinkSync(entry_path)
|
|
304
306
|
}
|
|
@@ -311,7 +313,7 @@ module.exports.deleteDir = function (dir_path) {
|
|
|
311
313
|
* Returns absolute filename to save screenshot.
|
|
312
314
|
* @param fileName {string} - filename.
|
|
313
315
|
*/
|
|
314
|
-
|
|
316
|
+
export const screenshotOutputFolder = function (fileName) {
|
|
315
317
|
const fileSep = path.sep
|
|
316
318
|
|
|
317
319
|
if (!fileName.includes(fileSep) || fileName.includes('record_')) {
|
|
@@ -320,12 +322,12 @@ module.exports.screenshotOutputFolder = function (fileName) {
|
|
|
320
322
|
return path.resolve(global.codecept_dir, fileName)
|
|
321
323
|
}
|
|
322
324
|
|
|
323
|
-
|
|
325
|
+
export const relativeDir = function (fileName) {
|
|
324
326
|
return fileName.replace(global.codecept_dir, '').replace(/^\//, '')
|
|
325
327
|
}
|
|
326
328
|
|
|
327
|
-
|
|
328
|
-
const format =
|
|
329
|
+
export const beautify = function (code) {
|
|
330
|
+
const format = jsBeautify.js
|
|
329
331
|
return format(code, { indent_size: 2, space_in_empty_paren: true })
|
|
330
332
|
}
|
|
331
333
|
|
|
@@ -345,7 +347,7 @@ function joinUrl(baseUrl, url) {
|
|
|
345
347
|
return shouldAppendBaseUrl(url) ? `${baseUrl}/${trimUrl(url)}` : url
|
|
346
348
|
}
|
|
347
349
|
|
|
348
|
-
|
|
350
|
+
export const appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
|
|
349
351
|
if (typeof baseUrl !== 'string') {
|
|
350
352
|
throw new Error(`Invalid value for baseUrl: ${baseUrl}`)
|
|
351
353
|
}
|
|
@@ -371,7 +373,7 @@ module.exports.appendBaseUrl = function (baseUrl = '', oneOrMoreUrls) {
|
|
|
371
373
|
* @param {string} key key to search
|
|
372
374
|
* @param {*} value value to set for key
|
|
373
375
|
*/
|
|
374
|
-
|
|
376
|
+
export const replaceValueDeep = function replaceValueDeep(obj, key, value) {
|
|
375
377
|
if (!obj) return
|
|
376
378
|
|
|
377
379
|
if (obj instanceof Array) {
|
|
@@ -393,13 +395,13 @@ module.exports.replaceValueDeep = function replaceValueDeep(obj, key, value) {
|
|
|
393
395
|
return obj
|
|
394
396
|
}
|
|
395
397
|
|
|
396
|
-
|
|
398
|
+
export const ansiRegExp = function ({ onlyFirst = false } = {}) {
|
|
397
399
|
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
400
|
|
|
399
401
|
return new RegExp(pattern, onlyFirst ? undefined : 'g')
|
|
400
402
|
}
|
|
401
403
|
|
|
402
|
-
|
|
404
|
+
export const tryOrDefault = function (fn, defaultValue) {
|
|
403
405
|
try {
|
|
404
406
|
return fn()
|
|
405
407
|
} catch (_) {
|
|
@@ -426,7 +428,7 @@ function normalizeKeyReplacer(match, prefix, key, suffix, offset, string) {
|
|
|
426
428
|
* @param {string} key
|
|
427
429
|
* @returns {string}
|
|
428
430
|
*/
|
|
429
|
-
|
|
431
|
+
export const getNormalizedKeyAttributeValue = function (key) {
|
|
430
432
|
// Use operation modifier key based on operating system
|
|
431
433
|
key = key.replace(/(Ctrl|Control|Cmd|Command)[ _]?Or[ _]?(Ctrl|Control|Cmd|Command)/i, os.platform() === 'darwin' ? 'Meta' : 'Control')
|
|
432
434
|
// Selection of keys (https://www.w3.org/TR/uievents-key/#named-key-attribute-values)
|
|
@@ -443,14 +445,14 @@ module.exports.getNormalizedKeyAttributeValue = function (key) {
|
|
|
443
445
|
return key
|
|
444
446
|
}
|
|
445
447
|
|
|
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) {
|
|
448
|
+
export const modifierKeys = ['Alt', 'AltGraph', 'AltLeft', 'AltRight', 'Control', 'ControlLeft', 'ControlRight', 'Meta', 'MetaLeft', 'MetaRight', 'Shift', 'ShiftLeft', 'ShiftRight']
|
|
449
|
+
export const isModifierKey = function (key) {
|
|
450
450
|
return modifierKeys.includes(key)
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
|
|
453
|
+
export const requireWithFallback = function (...packages) {
|
|
454
|
+
const require = createRequire(import.meta.url)
|
|
455
|
+
|
|
454
456
|
const exists = function (pkg) {
|
|
455
457
|
try {
|
|
456
458
|
require.resolve(pkg)
|
|
@@ -470,13 +472,13 @@ module.exports.requireWithFallback = function (...packages) {
|
|
|
470
472
|
throw new Error(`Cannot find modules ${packages.join(',')}`)
|
|
471
473
|
}
|
|
472
474
|
|
|
473
|
-
|
|
475
|
+
export const isNotSet = function (obj) {
|
|
474
476
|
if (obj === null) return true
|
|
475
477
|
if (obj === undefined) return true
|
|
476
478
|
return false
|
|
477
479
|
}
|
|
478
480
|
|
|
479
|
-
|
|
481
|
+
export const emptyFolder = directoryPath => {
|
|
480
482
|
// Do not throw on non-existent directory, since it may be created later
|
|
481
483
|
if (!fs.existsSync(directoryPath)) return
|
|
482
484
|
for (const file of fs.readdirSync(directoryPath)) {
|
|
@@ -484,7 +486,7 @@ module.exports.emptyFolder = directoryPath => {
|
|
|
484
486
|
}
|
|
485
487
|
}
|
|
486
488
|
|
|
487
|
-
|
|
489
|
+
export const printObjectProperties = obj => {
|
|
488
490
|
if (typeof obj !== 'object' || obj === null) {
|
|
489
491
|
return obj
|
|
490
492
|
}
|
|
@@ -497,11 +499,11 @@ module.exports.printObjectProperties = obj => {
|
|
|
497
499
|
return `{${result}}`
|
|
498
500
|
}
|
|
499
501
|
|
|
500
|
-
|
|
502
|
+
export const normalizeSpacesInString = string => {
|
|
501
503
|
return string.replace(/\s+/g, ' ')
|
|
502
504
|
}
|
|
503
505
|
|
|
504
|
-
|
|
506
|
+
export const humanizeFunction = function (fn) {
|
|
505
507
|
const fnStr = fn.toString().trim()
|
|
506
508
|
// Remove arrow function syntax, async, and parentheses
|
|
507
509
|
let simplified = fnStr
|
|
@@ -563,20 +565,20 @@ module.exports.humanizeFunction = function (fn) {
|
|
|
563
565
|
* const results = searchWithFusejs(data, 'lock', options);
|
|
564
566
|
* console.log(results);
|
|
565
567
|
*/
|
|
566
|
-
|
|
568
|
+
export const searchWithFusejs = function (source, searchString, opts) {
|
|
567
569
|
const fuse = new Fuse(source, opts)
|
|
568
570
|
|
|
569
571
|
return fuse.search(searchString)
|
|
570
572
|
}
|
|
571
573
|
|
|
572
|
-
|
|
574
|
+
export const humanizeString = function (string) {
|
|
573
575
|
// split strings by words, then make them all lowercase
|
|
574
576
|
const _result = string
|
|
575
577
|
.replace(/([a-z](?=[A-Z]))/g, '$1 ')
|
|
576
578
|
.split(' ')
|
|
577
579
|
.map(word => word.toLowerCase())
|
|
578
580
|
|
|
579
|
-
_result[0] = _result[0] === 'i' ?
|
|
581
|
+
_result[0] = _result[0] === 'i' ? ucfirst(_result[0]) : _result[0]
|
|
580
582
|
return _result.join(' ').trim()
|
|
581
583
|
}
|
|
582
584
|
|
|
@@ -617,7 +619,7 @@ function createCircularSafeReplacer(keysToSkip = []) {
|
|
|
617
619
|
* @param {number} space - Number of spaces for indentation (default: 0)
|
|
618
620
|
* @returns {string} JSON string representation
|
|
619
621
|
*/
|
|
620
|
-
|
|
622
|
+
export const safeStringify = function (obj, keysToSkip = [], space = 0) {
|
|
621
623
|
try {
|
|
622
624
|
return JSON.stringify(obj, createCircularSafeReplacer(keysToSkip), space)
|
|
623
625
|
} catch (error) {
|
|
@@ -626,7 +628,7 @@ module.exports.safeStringify = function (obj, keysToSkip = [], space = 0) {
|
|
|
626
628
|
}
|
|
627
629
|
}
|
|
628
630
|
|
|
629
|
-
|
|
631
|
+
export const serializeError = function (error) {
|
|
630
632
|
if (error) {
|
|
631
633
|
const { stack, uncaught, message, actual, expected } = error
|
|
632
634
|
return { stack, uncaught, message, actual, expected }
|
|
@@ -634,11 +636,11 @@ module.exports.serializeError = function (error) {
|
|
|
634
636
|
return null
|
|
635
637
|
}
|
|
636
638
|
|
|
637
|
-
|
|
639
|
+
export const base64EncodeFile = function (filePath) {
|
|
638
640
|
return Buffer.from(fs.readFileSync(filePath)).toString('base64')
|
|
639
641
|
}
|
|
640
642
|
|
|
641
|
-
|
|
643
|
+
export const markdownToAnsi = function (markdown) {
|
|
642
644
|
return (
|
|
643
645
|
markdown
|
|
644
646
|
// Headers (# Text) - make blue and bold
|
package/lib/workerStorage.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import { isMainThread, parentPort } from 'worker_threads'
|
|
2
|
+
import Container from './container.js'
|
|
2
3
|
|
|
3
|
-
const workerObjects = {}
|
|
4
|
-
const shareEvent = 'share'
|
|
4
|
+
const workerObjects = {}
|
|
5
|
+
const shareEvent = 'share'
|
|
5
6
|
|
|
6
|
-
const invokeWorkerListeners =
|
|
7
|
-
const { threadId } = workerObj
|
|
8
|
-
workerObj.on('message',
|
|
7
|
+
const invokeWorkerListeners = workerObj => {
|
|
8
|
+
const { threadId } = workerObj
|
|
9
|
+
workerObj.on('message', messageData => {
|
|
9
10
|
if (messageData.event === shareEvent) {
|
|
10
|
-
|
|
11
|
-
Container.share(messageData.data);
|
|
11
|
+
Container.share(messageData.data)
|
|
12
12
|
}
|
|
13
|
-
})
|
|
13
|
+
})
|
|
14
14
|
workerObj.on('exit', () => {
|
|
15
|
-
delete workerObjects[threadId]
|
|
16
|
-
})
|
|
17
|
-
}
|
|
15
|
+
delete workerObjects[threadId]
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
18
|
|
|
19
19
|
class WorkerStorage {
|
|
20
20
|
/**
|
|
@@ -24,8 +24,8 @@ class WorkerStorage {
|
|
|
24
24
|
* @param {Worker} workerObj
|
|
25
25
|
*/
|
|
26
26
|
static addWorker(workerObj) {
|
|
27
|
-
workerObjects[workerObj.threadId] = workerObj
|
|
28
|
-
invokeWorkerListeners(workerObj)
|
|
27
|
+
workerObjects[workerObj.threadId] = workerObj
|
|
28
|
+
invokeWorkerListeners(workerObj)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -36,12 +36,12 @@ class WorkerStorage {
|
|
|
36
36
|
static share(data) {
|
|
37
37
|
if (isMainThread) {
|
|
38
38
|
for (const workerObj of Object.values(workerObjects)) {
|
|
39
|
-
workerObj.postMessage({ data })
|
|
39
|
+
workerObj.postMessage({ data })
|
|
40
40
|
}
|
|
41
41
|
} else {
|
|
42
|
-
parentPort.postMessage({ data, event: shareEvent })
|
|
42
|
+
parentPort.postMessage({ data, event: shareEvent })
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
export default WorkerStorage
|