codeceptjs 4.0.0-beta.2 → 4.0.0-beta.20
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 +133 -120
- package/bin/codecept.js +107 -96
- package/bin/test-server.js +64 -0
- package/docs/webapi/clearCookie.mustache +1 -1
- package/docs/webapi/click.mustache +5 -1
- package/lib/actor.js +71 -103
- package/lib/ai.js +159 -188
- package/lib/assert/empty.js +22 -24
- package/lib/assert/equal.js +30 -37
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +43 -48
- package/lib/assert/throws.js +11 -11
- package/lib/assert/truth.js +22 -22
- package/lib/assert.js +20 -18
- package/lib/codecept.js +262 -162
- package/lib/colorUtils.js +50 -52
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +56 -51
- package/lib/command/definitions.js +96 -109
- package/lib/command/dryRun.js +77 -79
- package/lib/command/generate.js +234 -194
- package/lib/command/gherkin/init.js +42 -33
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +20 -17
- package/lib/command/info.js +74 -38
- package/lib/command/init.js +301 -290
- package/lib/command/interactive.js +41 -32
- package/lib/command/list.js +28 -27
- package/lib/command/run-multiple/chunk.js +51 -48
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +5 -1
- package/lib/command/run-multiple.js +97 -97
- package/lib/command/run-rerun.js +19 -25
- package/lib/command/run-workers.js +68 -92
- package/lib/command/run.js +39 -27
- package/lib/command/utils.js +80 -64
- package/lib/command/workers/runTests.js +388 -226
- package/lib/config.js +109 -50
- package/lib/container.js +641 -261
- package/lib/data/context.js +60 -61
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +32 -32
- package/lib/data/table.js +22 -22
- package/lib/effects.js +307 -0
- package/lib/element/WebElement.js +327 -0
- package/lib/els.js +160 -0
- package/lib/event.js +173 -163
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -85
- package/lib/helper/AI.js +131 -41
- package/lib/helper/ApiDataFactory.js +107 -75
- package/lib/helper/Appium.js +542 -404
- package/lib/helper/FileSystem.js +100 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +52 -52
- package/lib/helper/JSONResponse.js +126 -88
- package/lib/helper/Mochawesome.js +54 -29
- package/lib/helper/Playwright.js +2547 -1316
- package/lib/helper/Puppeteer.js +1578 -1181
- package/lib/helper/REST.js +209 -68
- package/lib/helper/WebDriver.js +1482 -1342
- 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 +17 -8
- package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +27 -28
- package/lib/helper/network/actions.js +36 -42
- package/lib/helper/network/utils.js +78 -84
- package/lib/helper/scripts/blurElement.js +5 -5
- package/lib/helper/scripts/focusElement.js +5 -5
- package/lib/helper/scripts/highlightElement.js +8 -8
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -3
- package/lib/history.js +23 -19
- package/lib/hooks.js +8 -8
- package/lib/html.js +94 -104
- package/lib/index.js +38 -27
- package/lib/listener/config.js +30 -23
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/enhancedGlobalRetry.js +110 -0
- package/lib/listener/exit.js +16 -18
- package/lib/listener/globalRetry.js +70 -0
- package/lib/listener/globalTimeout.js +181 -0
- package/lib/listener/helpers.js +76 -51
- package/lib/listener/mocha.js +10 -11
- package/lib/listener/result.js +11 -0
- package/lib/listener/retryEnhancer.js +85 -0
- package/lib/listener/steps.js +71 -59
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +214 -197
- package/lib/mocha/asyncWrapper.js +274 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +163 -0
- package/lib/mocha/featureConfig.js +89 -0
- package/lib/mocha/gherkin.js +231 -0
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +184 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +242 -0
- package/lib/output.js +141 -71
- package/lib/parser.js +47 -44
- package/lib/pause.js +173 -145
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +178 -79
- package/lib/plugin/autoDelay.js +36 -40
- package/lib/plugin/coverage.js +131 -78
- package/lib/plugin/customLocator.js +22 -21
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/enhancedRetryFailedStep.js +99 -0
- package/lib/plugin/heal.js +101 -110
- package/lib/plugin/htmlReporter.js +3648 -0
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +12 -11
- package/lib/plugin/retryFailedStep.js +82 -47
- package/lib/plugin/screenshotOnFail.js +111 -92
- package/lib/plugin/stepByStepReport.js +159 -101
- package/lib/plugin/stepTimeout.js +20 -25
- package/lib/plugin/subtitles.js +38 -38
- package/lib/recorder.js +193 -130
- package/lib/rerun.js +94 -49
- package/lib/result.js +238 -0
- package/lib/retryCoordinator.js +207 -0
- package/lib/secret.js +20 -18
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -329
- package/lib/steps.js +54 -0
- package/lib/store.js +38 -7
- package/lib/template/heal.js +3 -12
- 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 +334 -0
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +34 -21
- package/lib/utils/loaderCheck.js +124 -0
- package/lib/utils/mask_data.js +47 -0
- package/lib/utils/typescript.js +237 -0
- package/lib/utils.js +411 -228
- package/lib/workerStorage.js +37 -34
- package/lib/workers.js +532 -296
- package/package.json +124 -95
- package/translations/de-DE.js +5 -3
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +22 -12
- package/translations/it-IT.js +4 -3
- package/translations/ja-JP.js +4 -3
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +4 -3
- package/translations/pt-BR.js +4 -3
- package/translations/ru-RU.js +4 -3
- package/translations/utils.js +10 -0
- package/translations/zh-CN.js +4 -3
- package/translations/zh-TW.js +4 -3
- package/typings/index.d.ts +546 -185
- package/typings/promiseBasedTypes.d.ts +150 -875
- package/typings/types.d.ts +547 -992
- package/lib/cli.js +0 -249
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
- package/lib/helper/ExpectHelper.js +0 -399
- package/lib/helper/MockServer.js +0 -223
- package/lib/helper/Nightmare.js +0 -1411
- package/lib/helper/Protractor.js +0 -1835
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1410
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -63
- package/lib/interfaces/bdd.js +0 -98
- package/lib/interfaces/featureConfig.js +0 -69
- package/lib/interfaces/gherkin.js +0 -195
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/retry.js +0 -68
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -110
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -121
- package/lib/plugin/selenoid.js +0 -371
- package/lib/plugin/standardActingHelpers.js +0 -9
- package/lib/plugin/tryTo.js +0 -105
- package/lib/plugin/wdio.js +0 -246
- package/lib/scenario.js +0 -222
- package/lib/ui.js +0 -238
- package/lib/within.js +0 -70
|
@@ -1,132 +1,134 @@
|
|
|
1
|
-
import escapeStringRegexp from 'escape-string-regexp'
|
|
2
|
-
import fs from 'fs'
|
|
3
|
-
import Gherkin from '@cucumber/gherkin'
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import fsPath from 'path'
|
|
7
|
-
import { getConfig, getTestRoot } from '../utils.js';
|
|
8
|
-
import Codecept from '../../codecept.js';
|
|
9
|
-
import * as output from '../../output.js';
|
|
10
|
-
import { matchStep } from '../../interfaces/bdd.js';
|
|
1
|
+
import escapeStringRegexp from 'escape-string-regexp'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import Gherkin from '@cucumber/gherkin'
|
|
4
|
+
import { IdGenerator } from '@cucumber/messages'
|
|
5
|
+
import { globSync } from 'glob'
|
|
6
|
+
import fsPath from 'path'
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
parser.stopAtFirstError = false;
|
|
8
|
+
import { getConfig, getTestRoot } from '../utils.js'
|
|
9
|
+
import Codecept from '../../codecept.js'
|
|
10
|
+
import output from '../../output.js'
|
|
11
|
+
import { matchStep } from '../../mocha/bdd.js'
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
const uuidFn = IdGenerator.uuid()
|
|
14
|
+
const builder = new Gherkin.AstBuilder(uuidFn)
|
|
15
|
+
const matcher = new Gherkin.GherkinClassicTokenMatcher()
|
|
16
|
+
const parser = new Gherkin.Parser(builder, matcher)
|
|
17
|
+
parser.stopAtFirstError = false
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
export default async function (genPath, options) {
|
|
20
|
+
const configFile = options.config || genPath
|
|
21
|
+
const testsPath = getTestRoot(configFile)
|
|
22
|
+
const config = await getConfig(configFile)
|
|
23
|
+
if (!config) return
|
|
24
|
+
|
|
25
|
+
const codecept = new Codecept(config, {})
|
|
26
|
+
await codecept.init(testsPath)
|
|
26
27
|
|
|
27
28
|
if (!config.gherkin) {
|
|
28
|
-
output.
|
|
29
|
-
process.exit(1)
|
|
29
|
+
output.error('Gherkin is not enabled in config. Run `codecept gherkin:init` to enable it')
|
|
30
|
+
process.exit(1)
|
|
30
31
|
}
|
|
31
32
|
if (!config.gherkin.steps || !config.gherkin.steps[0]) {
|
|
32
|
-
output.
|
|
33
|
-
process.exit(1)
|
|
33
|
+
output.error('No gherkin steps defined in config. Exiting')
|
|
34
|
+
process.exit(1)
|
|
34
35
|
}
|
|
35
36
|
if (!options.feature && !config.gherkin.features) {
|
|
36
|
-
output.
|
|
37
|
-
process.exit(1)
|
|
37
|
+
output.error('No gherkin features defined in config. Exiting')
|
|
38
|
+
process.exit(1)
|
|
38
39
|
}
|
|
39
40
|
if (options.path && !config.gherkin.steps.includes(options.path)) {
|
|
40
|
-
output.
|
|
41
|
-
process.exit(1)
|
|
41
|
+
output.error(`You must include ${options.path} to the gherkin steps in your config file`)
|
|
42
|
+
process.exit(1)
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const files = []
|
|
45
|
-
|
|
45
|
+
const files = []
|
|
46
|
+
globSync(options.feature || config.gherkin.features, { cwd: options.feature ? '.' : global.codecept_dir }).forEach(file => {
|
|
46
47
|
if (!fsPath.isAbsolute(file)) {
|
|
47
|
-
file = fsPath.join(global.codecept_dir, file)
|
|
48
|
+
file = fsPath.join(global.codecept_dir, file)
|
|
48
49
|
}
|
|
49
|
-
files.push(fsPath.resolve(file))
|
|
50
|
-
})
|
|
51
|
-
output.print(`Loaded ${files.length} files`)
|
|
50
|
+
files.push(fsPath.resolve(file))
|
|
51
|
+
})
|
|
52
|
+
output.print(`Loaded ${files.length} files`)
|
|
52
53
|
|
|
53
|
-
const newSteps = new Map()
|
|
54
|
+
const newSteps = new Map()
|
|
54
55
|
|
|
55
|
-
const parseSteps =
|
|
56
|
-
const newSteps = []
|
|
57
|
-
let currentKeyword = ''
|
|
56
|
+
const parseSteps = steps => {
|
|
57
|
+
const newSteps = []
|
|
58
|
+
let currentKeyword = ''
|
|
58
59
|
for (const step of steps) {
|
|
59
60
|
if (step.keyword.trim() === 'And') {
|
|
60
|
-
if (!currentKeyword) throw new Error(`There is no active keyword for step '${step.text}'`)
|
|
61
|
-
step.keyword = currentKeyword
|
|
61
|
+
if (!currentKeyword) throw new Error(`There is no active keyword for step '${step.text}'`)
|
|
62
|
+
step.keyword = currentKeyword
|
|
62
63
|
}
|
|
63
|
-
currentKeyword = step.keyword
|
|
64
|
+
currentKeyword = step.keyword
|
|
64
65
|
try {
|
|
65
|
-
matchStep(step.text)
|
|
66
|
+
matchStep(step.text)
|
|
66
67
|
} catch (err) {
|
|
67
|
-
let stepLine
|
|
68
|
+
let stepLine
|
|
68
69
|
if (/[{}()/]/.test(step.text)) {
|
|
69
70
|
stepLine = escapeStringRegexp(step.text)
|
|
70
71
|
.replace(/\//g, '\\/')
|
|
71
72
|
.replace(/\"(.*?)\"/g, '"(.*?)"')
|
|
72
73
|
.replace(/(\d+\\\.\d+)/, '(\\d+\\.\\d+)')
|
|
73
|
-
.replace(/ (\d+) /, ' (\\d+) ')
|
|
74
|
-
stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: true })
|
|
74
|
+
.replace(/ (\d+) /, ' (\\d+) ')
|
|
75
|
+
stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: true })
|
|
75
76
|
} else {
|
|
76
77
|
stepLine = step.text
|
|
77
78
|
.replace(/\"(.*?)\"/g, '{string}')
|
|
78
79
|
.replace(/(\d+\.\d+)/, '{float}')
|
|
79
|
-
.replace(/ (\d+) /, ' {int} ')
|
|
80
|
-
stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: false })
|
|
80
|
+
.replace(/ (\d+) /, ' {int} ')
|
|
81
|
+
stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: false })
|
|
81
82
|
}
|
|
82
|
-
newSteps.push(stepLine)
|
|
83
|
+
newSteps.push(stepLine)
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
|
-
return newSteps
|
|
86
|
-
}
|
|
86
|
+
return newSteps
|
|
87
|
+
}
|
|
87
88
|
|
|
88
|
-
const parseFile =
|
|
89
|
-
|
|
90
|
-
const ast = parser.parse(fs.readFileSync(file).toString());
|
|
89
|
+
const parseFile = file => {
|
|
90
|
+
const ast = parser.parse(fs.readFileSync(file).toString())
|
|
91
91
|
for (const child of ast.feature.children) {
|
|
92
|
-
if (child.scenario.keyword === 'Scenario Outline') continue
|
|
93
|
-
parseSteps(child.scenario.steps)
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
if (child.scenario.keyword === 'Scenario Outline') continue // skip scenario outline
|
|
93
|
+
parseSteps(child.scenario.steps)
|
|
94
|
+
.map(step => {
|
|
95
|
+
return Object.assign(step, { file: file.replace(global.codecept_dir, '').slice(1) })
|
|
96
|
+
})
|
|
97
|
+
.map(step => newSteps.set(`${step.type}(${step})`, step))
|
|
96
98
|
}
|
|
97
|
-
}
|
|
99
|
+
}
|
|
98
100
|
|
|
99
|
-
files.forEach(file => parseFile(file))
|
|
101
|
+
files.forEach(file => parseFile(file))
|
|
100
102
|
|
|
101
|
-
let stepFile = options.path || config.gherkin.steps[0]
|
|
103
|
+
let stepFile = options.path || config.gherkin.steps[0]
|
|
102
104
|
if (!fs.existsSync(stepFile)) {
|
|
103
|
-
output.
|
|
104
|
-
process.exit(1)
|
|
105
|
+
output.error(`Please enter a valid step file path ${stepFile}`)
|
|
106
|
+
process.exit(1)
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
if (!fsPath.isAbsolute(stepFile)) {
|
|
108
|
-
stepFile = fsPath.join(global.codecept_dir, stepFile)
|
|
110
|
+
stepFile = fsPath.join(global.codecept_dir, stepFile)
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
const snippets = [...newSteps.values()]
|
|
112
114
|
.filter((value, index, self) => self.indexOf(value) === index)
|
|
113
|
-
.map(
|
|
115
|
+
.map(step => {
|
|
114
116
|
return `
|
|
115
117
|
${step.type}(${step.regexp ? '/^' : "'"}${step}${step.regexp ? '$/' : "'"}, () => {
|
|
116
118
|
// From "${step.file}" ${JSON.stringify(step.location)}
|
|
117
119
|
throw new Error('Not implemented yet');
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
+
});`
|
|
121
|
+
})
|
|
120
122
|
|
|
121
123
|
if (!snippets.length) {
|
|
122
|
-
output.print('No new snippets found')
|
|
123
|
-
return
|
|
124
|
+
output.print('No new snippets found')
|
|
125
|
+
return
|
|
124
126
|
}
|
|
125
|
-
output.
|
|
126
|
-
output.print(snippets.join('\n'))
|
|
127
|
+
output.success(`Snippets generated: ${snippets.length}`)
|
|
128
|
+
output.print(snippets.join('\n'))
|
|
127
129
|
|
|
128
130
|
if (!options.dryRun) {
|
|
129
|
-
output.
|
|
130
|
-
fs.writeFileSync(stepFile, fs.readFileSync(stepFile).toString() + snippets.join('\n') + '\n')
|
|
131
|
+
output.success(`Snippets added to ${output.colors.bold(stepFile)}`)
|
|
132
|
+
fs.writeFileSync(stepFile, fs.readFileSync(stepFile).toString() + snippets.join('\n') + '\n')
|
|
131
133
|
}
|
|
132
134
|
}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import { getConfig, getTestRoot } from '../utils.js'
|
|
2
|
-
import Codecept from '../../codecept.js'
|
|
3
|
-
import
|
|
4
|
-
import { getSteps } from '../../
|
|
1
|
+
import { getConfig, getTestRoot } from '../utils.js'
|
|
2
|
+
import Codecept from '../../codecept.js'
|
|
3
|
+
import output from '../../output.js'
|
|
4
|
+
import { getSteps, clearSteps } from '../../mocha/bdd.js'
|
|
5
5
|
|
|
6
|
-
export default function (genPath, options) {
|
|
7
|
-
const configFile = options.config || genPath
|
|
8
|
-
const testsPath = getTestRoot(configFile)
|
|
9
|
-
const config = getConfig(configFile)
|
|
10
|
-
if (!config) return
|
|
6
|
+
export default async function (genPath, options) {
|
|
7
|
+
const configFile = options.config || genPath
|
|
8
|
+
const testsPath = getTestRoot(configFile)
|
|
9
|
+
const config = await getConfig(configFile)
|
|
10
|
+
if (!config) return
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
// Clear any previously loaded steps
|
|
13
|
+
clearSteps()
|
|
14
|
+
|
|
15
|
+
const codecept = new Codecept(config, {})
|
|
16
|
+
await codecept.init(testsPath)
|
|
14
17
|
|
|
15
|
-
output.print('Gherkin Step Definitions:')
|
|
16
|
-
output.print()
|
|
17
|
-
const steps = getSteps()
|
|
18
|
+
output.print('Gherkin Step Definitions:')
|
|
19
|
+
output.print()
|
|
20
|
+
const steps = getSteps()
|
|
18
21
|
for (const step of Object.keys(steps)) {
|
|
19
|
-
output.print(` ${output.
|
|
22
|
+
output.print(` ${output.colors.bold(step)} ${output.colors.green(steps[step].line || '')}`)
|
|
20
23
|
}
|
|
21
|
-
output.print()
|
|
24
|
+
output.print()
|
|
22
25
|
if (!Object.keys(steps).length) {
|
|
23
|
-
output.
|
|
26
|
+
output.error('No Gherkin steps defined')
|
|
24
27
|
}
|
|
25
28
|
}
|
package/lib/command/info.js
CHANGED
|
@@ -1,44 +1,79 @@
|
|
|
1
|
-
import envinfo from 'envinfo'
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import envinfo from 'envinfo'
|
|
2
|
+
|
|
3
|
+
import { getConfig, getTestRoot } from './utils.js'
|
|
4
|
+
import Codecept from '../codecept.js'
|
|
5
|
+
import output from '../output.js'
|
|
6
|
+
import { execSync } from 'child_process'
|
|
7
|
+
|
|
8
|
+
async function getPlaywrightBrowsers() {
|
|
9
|
+
try {
|
|
10
|
+
const regex = /(chromium|firefox|webkit)\s+version\s+([\d.]+)/gi
|
|
11
|
+
let versions = []
|
|
12
|
+
|
|
13
|
+
const info = execSync('npx playwright install --dry-run').toString().trim()
|
|
14
|
+
|
|
15
|
+
const matches = [...info.matchAll(regex)]
|
|
16
|
+
|
|
17
|
+
matches.forEach(match => {
|
|
18
|
+
const browser = match[1]
|
|
19
|
+
const version = match[2]
|
|
20
|
+
versions.push(`${browser}: ${version}`)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
return versions.join(', ')
|
|
24
|
+
} catch (err) {
|
|
25
|
+
return 'Playwright not installed'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function getOsBrowsers() {
|
|
30
|
+
const chromeInfo = await envinfo.helpers.getChromeInfo()
|
|
31
|
+
const edgeInfo = await envinfo.helpers.getEdgeInfo()
|
|
32
|
+
const firefoxInfo = await envinfo.helpers.getFirefoxInfo()
|
|
33
|
+
const safariInfo = await envinfo.helpers.getSafariInfo()
|
|
34
|
+
|
|
35
|
+
return [
|
|
36
|
+
`chrome: ${chromeInfo ? chromeInfo[1] : 'not installed'}`,
|
|
37
|
+
`edge: ${edgeInfo ? edgeInfo[1] : 'not installed'}`,
|
|
38
|
+
`firefox: ${firefoxInfo ? firefoxInfo[1] : 'not installed'}`,
|
|
39
|
+
`safari: ${safariInfo ? safariInfo[1] : 'not installed'}`,
|
|
40
|
+
].join(', ')
|
|
41
|
+
}
|
|
6
42
|
|
|
7
43
|
export default async function (path) {
|
|
8
|
-
const testsPath = getTestRoot(path)
|
|
9
|
-
const config = getConfig(testsPath)
|
|
10
|
-
const codecept = new Codecept(config, {})
|
|
11
|
-
codecept.init(testsPath)
|
|
12
|
-
|
|
13
|
-
output.print('\n Environment information
|
|
14
|
-
const info = {}
|
|
15
|
-
info.codeceptVersion =
|
|
16
|
-
info.nodeInfo = await envinfo.helpers.getNodeInfo()
|
|
17
|
-
info.osInfo = await envinfo.helpers.getOSInfo()
|
|
18
|
-
info.cpuInfo = await envinfo.helpers.getCPUInfo()
|
|
19
|
-
info.
|
|
20
|
-
info.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
info.
|
|
25
|
-
info.plugins = plugins || "You don't have any enabled plugins";
|
|
44
|
+
const testsPath = getTestRoot(path)
|
|
45
|
+
const config = await getConfig(testsPath)
|
|
46
|
+
const codecept = new Codecept(config, {})
|
|
47
|
+
codecept.init(testsPath)
|
|
48
|
+
|
|
49
|
+
output.print('\n Environment information: \n')
|
|
50
|
+
const info = {}
|
|
51
|
+
info.codeceptVersion = Codecept.version()
|
|
52
|
+
info.nodeInfo = await envinfo.helpers.getNodeInfo()
|
|
53
|
+
info.osInfo = await envinfo.helpers.getOSInfo()
|
|
54
|
+
info.cpuInfo = await envinfo.helpers.getCPUInfo()
|
|
55
|
+
info.osBrowsers = await getOsBrowsers()
|
|
56
|
+
info.playwrightBrowsers = await getPlaywrightBrowsers()
|
|
57
|
+
|
|
58
|
+
const { helpers, plugins } = config
|
|
59
|
+
info.helpers = helpers || "You don't use any helpers"
|
|
60
|
+
info.plugins = plugins || "You don't have any enabled plugins"
|
|
26
61
|
|
|
27
62
|
for (const [key, value] of Object.entries(info)) {
|
|
28
63
|
if (Array.isArray(value)) {
|
|
29
|
-
output.print(`${key}: ${value[1]}`)
|
|
64
|
+
output.print(`${key}: ${value[1]}`)
|
|
30
65
|
} else {
|
|
31
|
-
output.print(`${key}: ${JSON.stringify(value, null, ' ')}`)
|
|
66
|
+
output.print(`${key}: ${JSON.stringify(value, null, ' ')}`)
|
|
32
67
|
}
|
|
33
68
|
}
|
|
34
|
-
output.print('***************************************')
|
|
35
|
-
output.print('If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs')
|
|
36
|
-
output.print('Or ask them on our discussion board: https://codecept.discourse.group/')
|
|
37
|
-
output.print('Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues')
|
|
38
|
-
output.print('***************************************')
|
|
69
|
+
output.print('***************************************')
|
|
70
|
+
output.print('If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs')
|
|
71
|
+
output.print('Or ask them on our discussion board: https://codecept.discourse.group/')
|
|
72
|
+
output.print('Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues')
|
|
73
|
+
output.print('***************************************')
|
|
39
74
|
}
|
|
40
75
|
|
|
41
|
-
export async
|
|
76
|
+
export const getMachineInfo = async () => {
|
|
42
77
|
const info = {
|
|
43
78
|
nodeInfo: await envinfo.helpers.getNodeInfo(),
|
|
44
79
|
osInfo: await envinfo.helpers.getOSInfo(),
|
|
@@ -47,17 +82,18 @@ export async function getMachineInfo() {
|
|
|
47
82
|
edgeInfo: await envinfo.helpers.getEdgeInfo(),
|
|
48
83
|
firefoxInfo: await envinfo.helpers.getFirefoxInfo(),
|
|
49
84
|
safariInfo: await envinfo.helpers.getSafariInfo(),
|
|
50
|
-
|
|
85
|
+
playwrightBrowsers: await getPlaywrightBrowsers(),
|
|
86
|
+
}
|
|
51
87
|
|
|
52
|
-
output.print('***************************************')
|
|
88
|
+
output.print('***************************************')
|
|
53
89
|
for (const [key, value] of Object.entries(info)) {
|
|
54
90
|
if (Array.isArray(value)) {
|
|
55
|
-
output.print(`${key}: ${value[1]}`)
|
|
91
|
+
output.print(`${key}: ${value[1]}`)
|
|
56
92
|
} else {
|
|
57
|
-
output.print(`${key}: ${JSON.stringify(value, null, ' ')}`)
|
|
93
|
+
output.print(`${key}: ${JSON.stringify(value, null, ' ')}`)
|
|
58
94
|
}
|
|
59
95
|
}
|
|
60
|
-
output.print('If you need more detailed info, just run this: npx codeceptjs info')
|
|
61
|
-
output.print('***************************************')
|
|
62
|
-
return info
|
|
96
|
+
output.print('If you need more detailed info, just run this: npx codeceptjs info')
|
|
97
|
+
output.print('***************************************')
|
|
98
|
+
return info
|
|
63
99
|
}
|