codeceptjs 3.6.4 → 3.6.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/codecept.js +84 -63
- package/lib/assert/empty.js +19 -19
- package/lib/assert/equal.js +32 -30
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +42 -42
- package/lib/assert/throws.js +13 -11
- package/lib/assert/truth.js +17 -18
- package/lib/command/configMigrate.js +57 -52
- package/lib/command/definitions.js +88 -88
- package/lib/command/dryRun.js +65 -63
- package/lib/command/generate.js +191 -181
- package/lib/command/info.js +39 -37
- package/lib/command/init.js +289 -286
- package/lib/command/interactive.js +32 -32
- package/lib/command/list.js +26 -26
- package/lib/command/run-multiple.js +113 -93
- package/lib/command/run-rerun.js +22 -22
- package/lib/command/run-workers.js +63 -63
- package/lib/command/run.js +24 -26
- package/lib/command/utils.js +64 -63
- package/lib/data/context.js +60 -60
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +29 -29
- package/lib/data/table.js +26 -20
- package/lib/helper/AI.js +67 -65
- package/lib/helper/ApiDataFactory.js +72 -69
- package/lib/helper/Appium.js +409 -379
- package/lib/helper/ExpectHelper.js +214 -248
- package/lib/helper/FileSystem.js +77 -78
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +49 -50
- package/lib/helper/JSONResponse.js +64 -62
- package/lib/helper/Mochawesome.js +28 -28
- package/lib/helper/MockServer.js +12 -12
- package/lib/helper/Nightmare.js +664 -572
- package/lib/helper/Playwright.js +1320 -1211
- package/lib/helper/Protractor.js +663 -629
- package/lib/helper/Puppeteer.js +1232 -1124
- package/lib/helper/REST.js +87 -72
- package/lib/helper/TestCafe.js +490 -491
- package/lib/helper/WebDriver.js +1294 -1156
- package/lib/interfaces/bdd.js +38 -51
- package/lib/interfaces/featureConfig.js +19 -19
- package/lib/interfaces/gherkin.js +122 -111
- package/lib/interfaces/scenarioConfig.js +29 -29
- package/lib/listener/artifacts.js +9 -9
- package/lib/listener/config.js +24 -23
- package/lib/listener/exit.js +12 -12
- package/lib/listener/helpers.js +42 -42
- package/lib/listener/mocha.js +11 -11
- package/lib/listener/retry.js +32 -30
- package/lib/listener/steps.js +50 -51
- package/lib/listener/timeout.js +53 -53
- package/lib/plugin/allure.js +14 -14
- package/lib/plugin/autoDelay.js +29 -36
- package/lib/plugin/autoLogin.js +70 -66
- package/lib/plugin/commentStep.js +18 -18
- package/lib/plugin/coverage.js +92 -77
- package/lib/plugin/customLocator.js +20 -19
- package/lib/plugin/debugErrors.js +24 -24
- package/lib/plugin/eachElement.js +37 -37
- package/lib/plugin/fakerTransform.js +6 -6
- package/lib/plugin/heal.js +66 -63
- package/lib/plugin/pauseOnFail.js +10 -10
- package/lib/plugin/retryFailedStep.js +31 -38
- package/lib/plugin/retryTo.js +28 -28
- package/lib/plugin/screenshotOnFail.js +107 -86
- package/lib/plugin/selenoid.js +131 -117
- package/lib/plugin/standardActingHelpers.js +2 -8
- package/lib/plugin/stepByStepReport.js +102 -92
- package/lib/plugin/stepTimeout.js +23 -22
- package/lib/plugin/subtitles.js +34 -34
- package/lib/plugin/tryTo.js +39 -29
- package/lib/plugin/wdio.js +77 -72
- package/lib/template/heal.js +11 -14
- package/package.json +4 -2
- package/translations/de-DE.js +1 -1
- package/translations/fr-FR.js +1 -1
- package/translations/index.js +9 -9
- package/translations/it-IT.js +1 -1
- package/translations/ja-JP.js +1 -1
- package/translations/pl-PL.js +1 -1
- package/translations/pt-BR.js +1 -1
- package/translations/ru-RU.js +1 -1
- package/translations/zh-CN.js +1 -1
- package/translations/zh-TW.js +1 -1
- package/typings/promiseBasedTypes.d.ts +238 -0
- package/typings/types.d.ts +32 -0
package/lib/command/dryRun.js
CHANGED
|
@@ -1,120 +1,122 @@
|
|
|
1
|
-
const { getConfig, getTestRoot } = require('./utils')
|
|
2
|
-
const Config = require('../config')
|
|
3
|
-
const Codecept = require('../codecept')
|
|
4
|
-
const output = require('../output')
|
|
5
|
-
const event = require('../event')
|
|
6
|
-
const store = require('../store')
|
|
7
|
-
const Container = require('../container')
|
|
1
|
+
const { getConfig, getTestRoot } = require('./utils')
|
|
2
|
+
const Config = require('../config')
|
|
3
|
+
const Codecept = require('../codecept')
|
|
4
|
+
const output = require('../output')
|
|
5
|
+
const event = require('../event')
|
|
6
|
+
const store = require('../store')
|
|
7
|
+
const Container = require('../container')
|
|
8
8
|
|
|
9
9
|
module.exports = async function (test, options) {
|
|
10
|
-
if (options.grep) process.env.grep = options.grep.toLowerCase()
|
|
11
|
-
const configFile = options.config
|
|
12
|
-
let codecept
|
|
10
|
+
if (options.grep) process.env.grep = options.grep.toLowerCase()
|
|
11
|
+
const configFile = options.config
|
|
12
|
+
let codecept
|
|
13
13
|
|
|
14
|
-
const testRoot = getTestRoot(configFile)
|
|
15
|
-
let config = getConfig(configFile)
|
|
14
|
+
const testRoot = getTestRoot(configFile)
|
|
15
|
+
let config = getConfig(configFile)
|
|
16
16
|
if (options.override) {
|
|
17
|
-
config = Config.append(JSON.parse(options.override))
|
|
17
|
+
config = Config.append(JSON.parse(options.override))
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
if (config.plugins) {
|
|
21
21
|
// disable all plugins by default, they can be enabled with -p option
|
|
22
22
|
for (const plugin in config.plugins) {
|
|
23
23
|
// if `-p all` is passed, then enabling all plugins, otherwise plugins could be enabled by `-p customLocator,commentStep,tryTo`
|
|
24
|
-
config.plugins[plugin].enabled = options.plugins === 'all'
|
|
24
|
+
config.plugins[plugin].enabled = options.plugins === 'all'
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
|
-
codecept = new Codecept(config, options)
|
|
30
|
-
codecept.init(testRoot)
|
|
29
|
+
codecept = new Codecept(config, options)
|
|
30
|
+
codecept.init(testRoot)
|
|
31
31
|
|
|
32
|
-
if (options.bootstrap) await codecept.bootstrap()
|
|
32
|
+
if (options.bootstrap) await codecept.bootstrap()
|
|
33
33
|
|
|
34
|
-
codecept.loadTests()
|
|
35
|
-
store.dryRun = true
|
|
34
|
+
codecept.loadTests()
|
|
35
|
+
store.dryRun = true
|
|
36
36
|
|
|
37
37
|
if (!options.steps && !options.verbose && !options.debug) {
|
|
38
|
-
printTests(codecept.testFiles)
|
|
39
|
-
return
|
|
38
|
+
printTests(codecept.testFiles)
|
|
39
|
+
return
|
|
40
40
|
}
|
|
41
|
-
event.dispatcher.on(event.all.result, printFooter)
|
|
42
|
-
codecept.run(test)
|
|
41
|
+
event.dispatcher.on(event.all.result, printFooter)
|
|
42
|
+
codecept.run(test)
|
|
43
43
|
} catch (err) {
|
|
44
|
-
console.error(err)
|
|
45
|
-
process.exit(1)
|
|
44
|
+
console.error(err)
|
|
45
|
+
process.exit(1)
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
}
|
|
48
48
|
|
|
49
49
|
function printTests(files) {
|
|
50
|
-
const figures = require('figures')
|
|
51
|
-
const colors = require('chalk')
|
|
50
|
+
const figures = require('figures')
|
|
51
|
+
const colors = require('chalk')
|
|
52
52
|
|
|
53
|
-
output.print(output.styles.debug(`Tests from ${global.codecept_dir}:`))
|
|
54
|
-
output.print()
|
|
53
|
+
output.print(output.styles.debug(`Tests from ${global.codecept_dir}:`))
|
|
54
|
+
output.print()
|
|
55
55
|
|
|
56
|
-
const mocha = Container.mocha()
|
|
57
|
-
mocha.files = files
|
|
58
|
-
mocha.loadFiles()
|
|
56
|
+
const mocha = Container.mocha()
|
|
57
|
+
mocha.files = files
|
|
58
|
+
mocha.loadFiles()
|
|
59
59
|
|
|
60
|
-
let numOfTests = 0
|
|
61
|
-
let numOfSuites = 0
|
|
62
|
-
let outputString = ''
|
|
63
|
-
const filterBy = process.env.grep ? process.env.grep.toLowerCase() : undefined
|
|
60
|
+
let numOfTests = 0
|
|
61
|
+
let numOfSuites = 0
|
|
62
|
+
let outputString = ''
|
|
63
|
+
const filterBy = process.env.grep ? process.env.grep.toLowerCase() : undefined
|
|
64
64
|
|
|
65
65
|
if (filterBy) {
|
|
66
66
|
for (const suite of mocha.suite.suites) {
|
|
67
|
-
const currentSuite = suite.title
|
|
67
|
+
const currentSuite = suite.title
|
|
68
68
|
if (suite.title.toLowerCase().includes(filterBy)) {
|
|
69
|
-
outputString += `${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')} -- ${mocha.suite.suites.length} tests\n
|
|
70
|
-
numOfSuites
|
|
69
|
+
outputString += `${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')} -- ${mocha.suite.suites.length} tests\n`
|
|
70
|
+
numOfSuites++
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
for (test of suite.tests) {
|
|
74
74
|
if (test.title.toLowerCase().includes(filterBy)) {
|
|
75
|
-
numOfTests
|
|
76
|
-
outputString += `${colors.white.bold(test.parent.title)} -- ${output.styles.log(test.parent.file || '')} -- ${mocha.suite.suites.length} tests\n
|
|
77
|
-
outputString += ` ${output.styles.scenario(figures.checkboxOff)} ${test.title}\n
|
|
75
|
+
numOfTests++
|
|
76
|
+
outputString += `${colors.white.bold(test.parent.title)} -- ${output.styles.log(test.parent.file || '')} -- ${mocha.suite.suites.length} tests\n`
|
|
77
|
+
outputString += ` ${output.styles.scenario(figures.checkboxOff)} ${test.title}\n`
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
numOfSuites = countSuites(outputString)
|
|
81
|
+
numOfSuites = countSuites(outputString)
|
|
82
82
|
} else {
|
|
83
83
|
for (const suite of mocha.suite.suites) {
|
|
84
|
-
output.print(
|
|
85
|
-
|
|
84
|
+
output.print(
|
|
85
|
+
`${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')} -- ${mocha.suite.suites.length} tests`,
|
|
86
|
+
)
|
|
87
|
+
numOfSuites++
|
|
86
88
|
|
|
87
89
|
for (test of suite.tests) {
|
|
88
|
-
numOfTests
|
|
89
|
-
output.print(` ${output.styles.scenario(figures.checkboxOff)} ${test.title}`)
|
|
90
|
+
numOfTests++
|
|
91
|
+
output.print(` ${output.styles.scenario(figures.checkboxOff)} ${test.title}`)
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
output.print(removeDuplicates(outputString))
|
|
95
|
-
output.print('')
|
|
96
|
-
output.success(` Total: ${numOfSuites} suites | ${numOfTests} tests `)
|
|
97
|
-
printFooter()
|
|
98
|
-
process.exit(0)
|
|
96
|
+
output.print(removeDuplicates(outputString))
|
|
97
|
+
output.print('')
|
|
98
|
+
output.success(` Total: ${numOfSuites} suites | ${numOfTests} tests `)
|
|
99
|
+
printFooter()
|
|
100
|
+
process.exit(0)
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
function printFooter() {
|
|
102
|
-
output.print()
|
|
103
|
-
output.print('--- DRY MODE: No tests were executed ---')
|
|
104
|
+
output.print()
|
|
105
|
+
output.print('--- DRY MODE: No tests were executed ---')
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
function removeDuplicates(inputString) {
|
|
107
|
-
const array = inputString.split('\n')
|
|
108
|
-
const uniqueLines = [...new Set(array)]
|
|
109
|
-
const resultString = uniqueLines.join('\n')
|
|
109
|
+
const array = inputString.split('\n')
|
|
110
|
+
const uniqueLines = [...new Set(array)]
|
|
111
|
+
const resultString = uniqueLines.join('\n')
|
|
110
112
|
|
|
111
|
-
return resultString
|
|
113
|
+
return resultString
|
|
112
114
|
}
|
|
113
115
|
|
|
114
116
|
function countSuites(inputString) {
|
|
115
|
-
const array = inputString.split('\n')
|
|
117
|
+
const array = inputString.split('\n')
|
|
116
118
|
|
|
117
|
-
const uniqueLines = [...new Set(array)]
|
|
118
|
-
const res = uniqueLines.filter(item => item.includes('-- '))
|
|
119
|
-
return res.length
|
|
119
|
+
const uniqueLines = [...new Set(array)]
|
|
120
|
+
const res = uniqueLines.filter((item) => item.includes('-- '))
|
|
121
|
+
return res.length
|
|
120
122
|
}
|
package/lib/command/generate.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
const colors = require('chalk')
|
|
2
|
-
const fs = require('fs')
|
|
3
|
-
const inquirer = require('inquirer')
|
|
4
|
-
const mkdirp = require('mkdirp')
|
|
5
|
-
const path = require('path')
|
|
6
|
-
const {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
getConfig, getTestRoot, safeFileWrite, readConfig,
|
|
13
|
-
} = require('./utils');
|
|
14
|
-
|
|
15
|
-
let extension = 'js';
|
|
1
|
+
const colors = require('chalk')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const inquirer = require('inquirer')
|
|
4
|
+
const mkdirp = require('mkdirp')
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const { fileExists, ucfirst, lcfirst, beautify } = require('../utils')
|
|
7
|
+
const output = require('../output')
|
|
8
|
+
const generateDefinitions = require('./definitions')
|
|
9
|
+
const { getConfig, getTestRoot, safeFileWrite, readConfig } = require('./utils')
|
|
10
|
+
|
|
11
|
+
let extension = 'js'
|
|
16
12
|
|
|
17
13
|
const testTemplate = `Feature('{{feature}}');
|
|
18
14
|
|
|
19
15
|
Scenario('test something', async ({ {{actor}} }) => {
|
|
20
16
|
|
|
21
17
|
});
|
|
22
|
-
|
|
18
|
+
`
|
|
23
19
|
|
|
24
20
|
// generates empty test
|
|
25
21
|
module.exports.test = function (genPath) {
|
|
26
|
-
const testsPath = getTestRoot(genPath)
|
|
27
|
-
global.codecept_dir = testsPath
|
|
28
|
-
const config = getConfig(testsPath)
|
|
29
|
-
if (!config) return
|
|
30
|
-
|
|
31
|
-
output.print('Creating a new test...')
|
|
32
|
-
output.print('----------------------')
|
|
33
|
-
|
|
34
|
-
const defaultExt = config.tests.match(/([^\*/]*?)$/)[1] || `_test.${extension}
|
|
35
|
-
|
|
36
|
-
return inquirer
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
type: 'input',
|
|
45
|
-
message: 'Filename of a test',
|
|
46
|
-
name: 'filename',
|
|
47
|
-
default(answers) {
|
|
48
|
-
return (answers.feature).replace(' ', '_') + defaultExt;
|
|
22
|
+
const testsPath = getTestRoot(genPath)
|
|
23
|
+
global.codecept_dir = testsPath
|
|
24
|
+
const config = getConfig(testsPath)
|
|
25
|
+
if (!config) return
|
|
26
|
+
|
|
27
|
+
output.print('Creating a new test...')
|
|
28
|
+
output.print('----------------------')
|
|
29
|
+
|
|
30
|
+
const defaultExt = config.tests.match(/([^\*/]*?)$/)[1] || `_test.${extension}`
|
|
31
|
+
|
|
32
|
+
return inquirer
|
|
33
|
+
.prompt([
|
|
34
|
+
{
|
|
35
|
+
type: 'input',
|
|
36
|
+
name: 'feature',
|
|
37
|
+
message: 'Feature which is being tested (ex: account, login, etc)',
|
|
38
|
+
validate: (val) => !!val,
|
|
49
39
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
message: 'Filename of a test',
|
|
43
|
+
name: 'filename',
|
|
44
|
+
default(answers) {
|
|
45
|
+
return answers.feature.replace(' ', '_') + defaultExt
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
])
|
|
49
|
+
.then((result) => {
|
|
50
|
+
const testFilePath = path.dirname(path.join(testsPath, config.tests)).replace(/\*\*$/, '')
|
|
51
|
+
let testFile = path.join(testFilePath, result.filename)
|
|
52
|
+
const ext = path.extname(testFile)
|
|
53
|
+
if (!ext) testFile += defaultExt
|
|
54
|
+
const dir = path.dirname(testFile)
|
|
55
|
+
if (!fileExists(dir)) mkdirp.sync(dir)
|
|
56
|
+
let testContent = testTemplate.replace('{{feature}}', result.feature)
|
|
57
|
+
|
|
58
|
+
const container = require('../container')
|
|
59
|
+
container.create(config, {})
|
|
60
|
+
// translate scenario test
|
|
61
|
+
if (container.translation().loaded) {
|
|
62
|
+
const vocabulary = container.translation().vocabulary
|
|
63
|
+
testContent = testContent.replace('{{actor}}', container.translation().I)
|
|
64
|
+
if (vocabulary.contexts.Feature) testContent = testContent.replace('Feature', vocabulary.contexts.Feature)
|
|
65
|
+
if (vocabulary.contexts.Scenario) testContent = testContent.replace('Scenario', vocabulary.contexts.Scenario)
|
|
66
|
+
output.print(
|
|
67
|
+
`Test was created in ${colors.bold(config.translation)} localization. See: https://codecept.io/translation/`,
|
|
68
|
+
)
|
|
69
|
+
} else {
|
|
70
|
+
testContent = testContent.replace('{{actor}}', 'I')
|
|
71
|
+
}
|
|
72
|
+
if (!config.fullPromiseBased) testContent = testContent.replace('async', '')
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
74
|
+
if (!safeFileWrite(testFile, testContent)) return
|
|
75
|
+
output.success(`\nTest for ${result.filename} was created in ${testFile}`)
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
78
|
|
|
79
79
|
const pageObjectTemplate = `const { I } = inject();
|
|
80
80
|
|
|
@@ -82,7 +82,7 @@ module.exports = {
|
|
|
82
82
|
|
|
83
83
|
// insert your locators and methods here
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
`
|
|
86
86
|
|
|
87
87
|
const poModuleTemplateTS = `const { I } = inject();
|
|
88
88
|
|
|
@@ -90,7 +90,7 @@ export = {
|
|
|
90
90
|
|
|
91
91
|
// insert your locators and methods here
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
`
|
|
94
94
|
|
|
95
95
|
const poClassTemplate = `const { I } = inject();
|
|
96
96
|
|
|
@@ -105,96 +105,101 @@ class {{name}} {
|
|
|
105
105
|
// For inheritance
|
|
106
106
|
module.exports = new {{name}}();
|
|
107
107
|
export = {{name}};
|
|
108
|
-
|
|
108
|
+
`
|
|
109
109
|
|
|
110
110
|
module.exports.pageObject = function (genPath, opts) {
|
|
111
|
-
const testsPath = getTestRoot(genPath)
|
|
112
|
-
const config = getConfig(testsPath)
|
|
113
|
-
const kind = opts.T || 'page'
|
|
114
|
-
if (!config) return
|
|
111
|
+
const testsPath = getTestRoot(genPath)
|
|
112
|
+
const config = getConfig(testsPath)
|
|
113
|
+
const kind = opts.T || 'page'
|
|
114
|
+
if (!config) return
|
|
115
115
|
|
|
116
|
-
let configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
116
|
+
let configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
117
117
|
|
|
118
118
|
if (!fileExists(configFile)) {
|
|
119
|
-
extension = 'ts'
|
|
120
|
-
configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
119
|
+
extension = 'ts'
|
|
120
|
+
configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
121
121
|
}
|
|
122
|
-
output.print(`Creating a new ${kind} object`)
|
|
123
|
-
output.print('--------------------------')
|
|
124
|
-
|
|
125
|
-
return inquirer
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
actorPath =
|
|
122
|
+
output.print(`Creating a new ${kind} object`)
|
|
123
|
+
output.print('--------------------------')
|
|
124
|
+
|
|
125
|
+
return inquirer
|
|
126
|
+
.prompt([
|
|
127
|
+
{
|
|
128
|
+
type: 'input',
|
|
129
|
+
name: 'name',
|
|
130
|
+
message: `Name of a ${kind} object`,
|
|
131
|
+
validate: (val) => !!val,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
type: 'input',
|
|
135
|
+
name: 'filename',
|
|
136
|
+
message: 'Where should it be stored',
|
|
137
|
+
default: (answers) => `./${kind}s/${answers.name}.${extension}`,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: 'list',
|
|
141
|
+
name: 'objectType',
|
|
142
|
+
message: 'What is your preferred object type',
|
|
143
|
+
choices: ['module', 'class'],
|
|
144
|
+
default: 'module',
|
|
145
|
+
},
|
|
146
|
+
])
|
|
147
|
+
.then((result) => {
|
|
148
|
+
const pageObjectFile = path.join(testsPath, result.filename)
|
|
149
|
+
const dir = path.dirname(pageObjectFile)
|
|
150
|
+
if (!fileExists(dir)) fs.mkdirSync(dir)
|
|
151
|
+
|
|
152
|
+
let actor = 'actor'
|
|
153
|
+
|
|
154
|
+
if (config.include.I) {
|
|
155
|
+
let actorPath = config.include.I
|
|
156
|
+
if (actorPath.charAt(0) === '.') {
|
|
157
|
+
// relative path
|
|
158
|
+
actorPath = path.relative(dir, path.dirname(path.join(testsPath, actorPath))) + actorPath.substring(1) // get an upper level
|
|
159
|
+
}
|
|
160
|
+
actor = `require('${actorPath}')`
|
|
156
161
|
}
|
|
157
|
-
actor = `require('${actorPath}')`;
|
|
158
|
-
}
|
|
159
162
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
163
|
+
const name = lcfirst(result.name) + ucfirst(kind)
|
|
164
|
+
if (result.objectType === 'module' && extension === 'ts') {
|
|
165
|
+
if (!safeFileWrite(pageObjectFile, poModuleTemplateTS.replace('{{actor}}', actor))) return
|
|
166
|
+
} else if (result.objectType === 'module' && extension === 'js') {
|
|
167
|
+
if (!safeFileWrite(pageObjectFile, pageObjectTemplate.replace('{{actor}}', actor))) return
|
|
168
|
+
} else if (result.objectType === 'class') {
|
|
169
|
+
const content = poClassTemplate.replace(/{{actor}}/g, actor).replace(/{{name}}/g, name)
|
|
170
|
+
if (!safeFileWrite(pageObjectFile, content)) return
|
|
171
|
+
}
|
|
169
172
|
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
let data = readConfig(configFile)
|
|
174
|
+
config.include[name] = result.filename
|
|
172
175
|
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
if (!data) throw Error('Config file is empty')
|
|
177
|
+
const currentInclude = `${data.match(/include:[\s\S][^\}]*/i)[0]}\n ${name}:${JSON.stringify(config.include[name])}`
|
|
175
178
|
|
|
176
|
-
|
|
179
|
+
data = data.replace(/include:[\s\S][^\}]*/i, `${currentInclude},`)
|
|
177
180
|
|
|
178
|
-
|
|
181
|
+
fs.writeFileSync(configFile, beautify(data), 'utf-8')
|
|
179
182
|
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
output.success(`${ucfirst(kind)} object for ${result.name} was created in ${pageObjectFile}`)
|
|
184
|
+
output.print(`Your config file (${colors.cyan('include')} section) has included the new created PO:
|
|
182
185
|
|
|
183
186
|
include: {
|
|
184
187
|
...
|
|
185
188
|
${name}: '${result.filename}',
|
|
186
|
-
},`)
|
|
189
|
+
},`)
|
|
187
190
|
|
|
188
|
-
|
|
189
|
-
|
|
191
|
+
output.print(`Use ${output.colors.bold(colors.cyan(name))} as parameter in test scenarios to access this object:`)
|
|
192
|
+
output.print(`\nScenario('my new test', ({ I, ${name} })) { /** ... */ }\n`)
|
|
190
193
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
194
|
+
try {
|
|
195
|
+
generateDefinitions(testsPath, {})
|
|
196
|
+
} catch (_err) {
|
|
197
|
+
output.print(
|
|
198
|
+
`Run ${colors.green('npx codeceptjs def')} to update your types to get auto-completion for object.`,
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
}
|
|
198
203
|
|
|
199
204
|
const helperTemplate = `const Helper = require('@codeceptjs/helper');
|
|
200
205
|
|
|
@@ -222,59 +227,64 @@ class {{name}} extends Helper {
|
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
module.exports = {{name}};
|
|
225
|
-
|
|
230
|
+
`
|
|
226
231
|
|
|
227
232
|
module.exports.helper = function (genPath) {
|
|
228
|
-
const testsPath = getTestRoot(genPath)
|
|
229
|
-
|
|
230
|
-
output.print('Creating a new helper')
|
|
231
|
-
output.print('--------------------------')
|
|
232
|
-
|
|
233
|
-
return inquirer
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
233
|
+
const testsPath = getTestRoot(genPath)
|
|
234
|
+
|
|
235
|
+
output.print('Creating a new helper')
|
|
236
|
+
output.print('--------------------------')
|
|
237
|
+
|
|
238
|
+
return inquirer
|
|
239
|
+
.prompt([
|
|
240
|
+
{
|
|
241
|
+
type: 'input',
|
|
242
|
+
name: 'name',
|
|
243
|
+
message: 'Name of a Helper',
|
|
244
|
+
validate: (val) => !!val,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
type: 'input',
|
|
248
|
+
name: 'filename',
|
|
249
|
+
message: 'Where should it be stored',
|
|
250
|
+
default: (answers) => `./${answers.name.toLowerCase()}_helper.${extension}`,
|
|
251
|
+
},
|
|
252
|
+
])
|
|
253
|
+
.then((result) => {
|
|
254
|
+
const name = ucfirst(result.name)
|
|
255
|
+
const helperFile = path.join(testsPath, result.filename)
|
|
256
|
+
const dir = path.dirname(helperFile)
|
|
257
|
+
if (!fileExists(dir)) fs.mkdirSync(dir)
|
|
258
|
+
|
|
259
|
+
if (!safeFileWrite(helperFile, helperTemplate.replace(/{{name}}/g, name))) return
|
|
260
|
+
output.success(`Helper for ${name} was created in ${helperFile}`)
|
|
261
|
+
output.print(`Update your config file (add to ${colors.cyan('helpers')} section):
|
|
252
262
|
|
|
253
263
|
helpers: {
|
|
254
264
|
${name}: {
|
|
255
265
|
require: '${result.filename}',
|
|
256
266
|
},
|
|
257
267
|
},
|
|
258
|
-
`)
|
|
259
|
-
|
|
260
|
-
}
|
|
268
|
+
`)
|
|
269
|
+
})
|
|
270
|
+
}
|
|
261
271
|
|
|
262
|
-
const healTemplate = fs.readFileSync(path.join(__dirname, '../template/heal.js'), 'utf8').toString()
|
|
272
|
+
const healTemplate = fs.readFileSync(path.join(__dirname, '../template/heal.js'), 'utf8').toString()
|
|
263
273
|
|
|
264
274
|
module.exports.heal = function (genPath) {
|
|
265
|
-
const testsPath = getTestRoot(genPath)
|
|
275
|
+
const testsPath = getTestRoot(genPath)
|
|
266
276
|
|
|
267
|
-
let configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
277
|
+
let configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
268
278
|
|
|
269
279
|
if (!fileExists(configFile)) {
|
|
270
|
-
configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
271
|
-
if (fileExists(configFile)) extension = 'ts'
|
|
280
|
+
configFile = path.join(testsPath, `codecept.conf.${extension}`)
|
|
281
|
+
if (fileExists(configFile)) extension = 'ts'
|
|
272
282
|
}
|
|
273
283
|
|
|
274
|
-
output.print('Creating basic heal recipes')
|
|
275
|
-
output.print(`Add your own custom recipes to ./heal.${extension} file`)
|
|
276
|
-
output.print('Require this file in the config file and enable heal plugin:')
|
|
277
|
-
output.print('--------------------------')
|
|
284
|
+
output.print('Creating basic heal recipes')
|
|
285
|
+
output.print(`Add your own custom recipes to ./heal.${extension} file`)
|
|
286
|
+
output.print('Require this file in the config file and enable heal plugin:')
|
|
287
|
+
output.print('--------------------------')
|
|
278
288
|
output.print(`
|
|
279
289
|
require('./heal')
|
|
280
290
|
|
|
@@ -286,9 +296,9 @@ exports.config = {
|
|
|
286
296
|
}
|
|
287
297
|
}
|
|
288
298
|
}
|
|
289
|
-
`)
|
|
299
|
+
`)
|
|
290
300
|
|
|
291
|
-
const healFile = path.join(testsPath, `heal.${extension}`)
|
|
292
|
-
if (!safeFileWrite(healFile, healTemplate)) return
|
|
293
|
-
output.success(`Heal recipes were created in ${healFile}`)
|
|
294
|
-
}
|
|
301
|
+
const healFile = path.join(testsPath, `heal.${extension}`)
|
|
302
|
+
if (!safeFileWrite(healFile, healTemplate)) return
|
|
303
|
+
output.success(`Heal recipes were created in ${healFile}`)
|
|
304
|
+
}
|