codeceptjs 3.6.4-beta.2 → 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/ai.js +47 -1
- 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 +114 -35
- 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 +115 -69
- package/lib/helper/TestCafe.js +490 -491
- package/lib/helper/WebDriver.js +1294 -1156
- package/lib/history.js +16 -3
- 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/pause.js +17 -3
- 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 +5 -3
- 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/index.d.ts +42 -19
- package/typings/promiseBasedTypes.d.ts +280 -1
- package/typings/types.d.ts +76 -1
package/lib/listener/timeout.js
CHANGED
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
const event = require('../event')
|
|
2
|
-
const output = require('../output')
|
|
3
|
-
const recorder = require('../recorder')
|
|
4
|
-
const Config = require('../config')
|
|
5
|
-
const { timeouts } = require('../store')
|
|
6
|
-
const TIMEOUT_ORDER = require('../step').TIMEOUT_ORDER
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const output = require('../output')
|
|
3
|
+
const recorder = require('../recorder')
|
|
4
|
+
const Config = require('../config')
|
|
5
|
+
const { timeouts } = require('../store')
|
|
6
|
+
const TIMEOUT_ORDER = require('../step').TIMEOUT_ORDER
|
|
7
7
|
|
|
8
8
|
module.exports = function () {
|
|
9
|
-
let timeout
|
|
10
|
-
let suiteTimeout = []
|
|
11
|
-
let currentTest
|
|
12
|
-
let currentTimeout
|
|
9
|
+
let timeout
|
|
10
|
+
let suiteTimeout = []
|
|
11
|
+
let currentTest
|
|
12
|
+
let currentTimeout
|
|
13
13
|
|
|
14
14
|
if (!timeouts) {
|
|
15
|
-
console.log('Timeouts were disabled')
|
|
16
|
-
return
|
|
15
|
+
console.log('Timeouts were disabled')
|
|
16
|
+
return
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
event.dispatcher.on(event.suite.before, (suite) => {
|
|
20
|
-
suiteTimeout = []
|
|
21
|
-
let timeoutConfig = Config.get('timeout')
|
|
20
|
+
suiteTimeout = []
|
|
21
|
+
let timeoutConfig = Config.get('timeout')
|
|
22
22
|
|
|
23
23
|
if (timeoutConfig) {
|
|
24
24
|
if (!Number.isNaN(+timeoutConfig)) {
|
|
25
|
-
checkForSeconds(timeoutConfig)
|
|
26
|
-
suiteTimeout.push(timeoutConfig)
|
|
25
|
+
checkForSeconds(timeoutConfig)
|
|
26
|
+
suiteTimeout.push(timeoutConfig)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (!Array.isArray(timeoutConfig)) {
|
|
30
|
-
timeoutConfig = [timeoutConfig]
|
|
30
|
+
timeoutConfig = [timeoutConfig]
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
for (const config of timeoutConfig.filter(c => !!c.Feature)) {
|
|
33
|
+
for (const config of timeoutConfig.filter((c) => !!c.Feature)) {
|
|
34
34
|
if (config.grep) {
|
|
35
|
-
if (!suite.title.includes(config.grep)) continue
|
|
35
|
+
if (!suite.title.includes(config.grep)) continue
|
|
36
36
|
}
|
|
37
|
-
suiteTimeout.push(config.Feature)
|
|
37
|
+
suiteTimeout.push(config.Feature)
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
if (suite.totalTimeout) suiteTimeout.push(suite.totalTimeout)
|
|
42
|
-
output.log(`Timeouts: ${suiteTimeout}`)
|
|
43
|
-
})
|
|
41
|
+
if (suite.totalTimeout) suiteTimeout.push(suite.totalTimeout)
|
|
42
|
+
output.log(`Timeouts: ${suiteTimeout}`)
|
|
43
|
+
})
|
|
44
44
|
|
|
45
45
|
event.dispatcher.on(event.test.before, (test) => {
|
|
46
|
-
currentTest = test
|
|
47
|
-
let testTimeout = null
|
|
46
|
+
currentTest = test
|
|
47
|
+
let testTimeout = null
|
|
48
48
|
|
|
49
|
-
let timeoutConfig = Config.get('timeout')
|
|
49
|
+
let timeoutConfig = Config.get('timeout')
|
|
50
50
|
|
|
51
51
|
if (typeof timeoutConfig === 'object' || Array.isArray(timeoutConfig)) {
|
|
52
52
|
if (!Array.isArray(timeoutConfig)) {
|
|
53
|
-
timeoutConfig = [timeoutConfig]
|
|
53
|
+
timeoutConfig = [timeoutConfig]
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
for (const config of timeoutConfig.filter(c => !!c.Scenario)) {
|
|
57
|
-
console.log('Test Timeout', config, test.title.includes(config.grep))
|
|
56
|
+
for (const config of timeoutConfig.filter((c) => !!c.Scenario)) {
|
|
57
|
+
console.log('Test Timeout', config, test.title.includes(config.grep))
|
|
58
58
|
if (config.grep) {
|
|
59
|
-
if (!test.title.includes(config.grep)) continue
|
|
59
|
+
if (!test.title.includes(config.grep)) continue
|
|
60
60
|
}
|
|
61
|
-
testTimeout = config.Scenario
|
|
61
|
+
testTimeout = config.Scenario
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
timeout = test.totalTimeout || testTimeout || suiteTimeout[suiteTimeout.length - 1]
|
|
66
|
-
if (!timeout) return
|
|
67
|
-
currentTimeout = timeout
|
|
68
|
-
output.debug(`Test Timeout: ${timeout}s`)
|
|
69
|
-
timeout *= 1000
|
|
70
|
-
})
|
|
65
|
+
timeout = test.totalTimeout || testTimeout || suiteTimeout[suiteTimeout.length - 1]
|
|
66
|
+
if (!timeout) return
|
|
67
|
+
currentTimeout = timeout
|
|
68
|
+
output.debug(`Test Timeout: ${timeout}s`)
|
|
69
|
+
timeout *= 1000
|
|
70
|
+
})
|
|
71
71
|
|
|
72
72
|
event.dispatcher.on(event.test.passed, (test) => {
|
|
73
|
-
currentTest = null
|
|
74
|
-
})
|
|
73
|
+
currentTest = null
|
|
74
|
+
})
|
|
75
75
|
|
|
76
76
|
event.dispatcher.on(event.test.failed, (test) => {
|
|
77
|
-
currentTest = null
|
|
78
|
-
})
|
|
77
|
+
currentTest = null
|
|
78
|
+
})
|
|
79
79
|
|
|
80
80
|
event.dispatcher.on(event.step.before, (step) => {
|
|
81
|
-
if (typeof timeout !== 'number') return
|
|
81
|
+
if (typeof timeout !== 'number') return
|
|
82
82
|
|
|
83
83
|
if (timeout < 0) {
|
|
84
|
-
step.setTimeout(0.01, TIMEOUT_ORDER.testOrSuite)
|
|
84
|
+
step.setTimeout(0.01, TIMEOUT_ORDER.testOrSuite)
|
|
85
85
|
} else {
|
|
86
|
-
step.setTimeout(timeout, TIMEOUT_ORDER.testOrSuite)
|
|
86
|
+
step.setTimeout(timeout, TIMEOUT_ORDER.testOrSuite)
|
|
87
87
|
}
|
|
88
|
-
})
|
|
88
|
+
})
|
|
89
89
|
|
|
90
90
|
event.dispatcher.on(event.step.finished, (step) => {
|
|
91
|
-
if (typeof timeout === 'number' && !Number.isNaN(timeout)) timeout -= step.duration
|
|
91
|
+
if (typeof timeout === 'number' && !Number.isNaN(timeout)) timeout -= step.duration
|
|
92
92
|
|
|
93
93
|
if (typeof timeout === 'number' && timeout <= 0 && recorder.isRunning()) {
|
|
94
94
|
if (currentTest && currentTest.callback) {
|
|
95
|
-
recorder.reset()
|
|
95
|
+
recorder.reset()
|
|
96
96
|
// replace mocha timeout with custom timeout
|
|
97
|
-
currentTest.timeout(0)
|
|
98
|
-
currentTest.callback(new Error(`Timeout ${currentTimeout}s exceeded (with Before hook)`))
|
|
99
|
-
currentTest.timedOut = true
|
|
97
|
+
currentTest.timeout(0)
|
|
98
|
+
currentTest.callback(new Error(`Timeout ${currentTimeout}s exceeded (with Before hook)`))
|
|
99
|
+
currentTest.timedOut = true
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
})
|
|
103
|
-
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
104
|
|
|
105
105
|
function checkForSeconds(timeout) {
|
|
106
106
|
if (timeout >= 1000) {
|
|
107
|
-
console.log(`Warning: Timeout was set to ${timeout}secs.\nGlobal timeout should be specified in seconds.`)
|
|
107
|
+
console.log(`Warning: Timeout was set to ${timeout}secs.\nGlobal timeout should be specified in seconds.`)
|
|
108
108
|
}
|
|
109
109
|
}
|
package/lib/pause.js
CHANGED
|
@@ -56,7 +56,15 @@ function pauseSession(passedObject = {}) {
|
|
|
56
56
|
output.print(colors.blue(' Ideas: ask it to fill forms for you or to click'));
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
rl = readline.createInterface({
|
|
61
|
+
input: process.stdin,
|
|
62
|
+
output: process.stdout,
|
|
63
|
+
terminal: true,
|
|
64
|
+
completer,
|
|
65
|
+
history: history.load(),
|
|
66
|
+
historySize: 50, // Adjust the history size as needed
|
|
67
|
+
});
|
|
60
68
|
|
|
61
69
|
rl.on('line', parseInput);
|
|
62
70
|
rl.on('close', () => {
|
|
@@ -105,7 +113,7 @@ async function parseInput(cmd) {
|
|
|
105
113
|
if (cmd.trim().startsWith('=>')) {
|
|
106
114
|
isCustomCommand = true;
|
|
107
115
|
cmd = cmd.trim().substring(2, cmd.length);
|
|
108
|
-
} else if (aiAssistant.isEnabled && !cmd.match(/^\w+\(/) && cmd.includes(' ')) {
|
|
116
|
+
} else if (aiAssistant.isEnabled && cmd.trim() && !cmd.match(/^\w+\(/) && cmd.includes(' ')) {
|
|
109
117
|
const currentOutputLevel = output.level();
|
|
110
118
|
output.level(0);
|
|
111
119
|
const res = I.grabSource();
|
|
@@ -121,7 +129,7 @@ async function parseInput(cmd) {
|
|
|
121
129
|
output.level(currentOutputLevel);
|
|
122
130
|
}
|
|
123
131
|
|
|
124
|
-
const spinner = ora("Processing
|
|
132
|
+
const spinner = ora("Processing AI request...").start();
|
|
125
133
|
cmd = await aiAssistant.writeSteps(cmd);
|
|
126
134
|
spinner.stop();
|
|
127
135
|
output.print('');
|
|
@@ -200,4 +208,10 @@ function completer(line) {
|
|
|
200
208
|
return [hits && hits.length ? hits : completions, line];
|
|
201
209
|
}
|
|
202
210
|
|
|
211
|
+
function registerVariable(name, value) {
|
|
212
|
+
registeredVariables[name] = value;
|
|
213
|
+
}
|
|
214
|
+
|
|
203
215
|
module.exports = pause;
|
|
216
|
+
|
|
217
|
+
module.exports.registerVariable = registerVariable;
|
package/lib/plugin/allure.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
module.exports = () => {
|
|
2
|
-
console.log('Allure plugin was moved to @codeceptjs/allure-legacy. Please install it and update your config')
|
|
3
|
-
console.log()
|
|
4
|
-
console.log('npm install @codeceptjs/allure-legacy --save-dev')
|
|
5
|
-
console.log()
|
|
6
|
-
console.log('Then update your config to use it:')
|
|
7
|
-
console.log()
|
|
8
|
-
console.log('plugins: {')
|
|
9
|
-
console.log(' allure: {')
|
|
10
|
-
console.log(' enabled: true,')
|
|
11
|
-
console.log(
|
|
12
|
-
console.log(' }')
|
|
13
|
-
console.log('}')
|
|
14
|
-
console.log()
|
|
15
|
-
}
|
|
2
|
+
console.log('Allure plugin was moved to @codeceptjs/allure-legacy. Please install it and update your config')
|
|
3
|
+
console.log()
|
|
4
|
+
console.log('npm install @codeceptjs/allure-legacy --save-dev')
|
|
5
|
+
console.log()
|
|
6
|
+
console.log('Then update your config to use it:')
|
|
7
|
+
console.log()
|
|
8
|
+
console.log('plugins: {')
|
|
9
|
+
console.log(' allure: {')
|
|
10
|
+
console.log(' enabled: true,')
|
|
11
|
+
console.log(" require: '@codeceptjs/allure-legacy',")
|
|
12
|
+
console.log(' }')
|
|
13
|
+
console.log('}')
|
|
14
|
+
console.log()
|
|
15
|
+
}
|
package/lib/plugin/autoDelay.js
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
const Container = require('../container')
|
|
2
|
-
const store = require('../store')
|
|
3
|
-
const recorder = require('../recorder')
|
|
4
|
-
const event = require('../event')
|
|
5
|
-
const log = require('../output').log
|
|
6
|
-
const supportedHelpers = require('./standardActingHelpers').slice()
|
|
1
|
+
const Container = require('../container')
|
|
2
|
+
const store = require('../store')
|
|
3
|
+
const recorder = require('../recorder')
|
|
4
|
+
const event = require('../event')
|
|
5
|
+
const log = require('../output').log
|
|
6
|
+
const supportedHelpers = require('./standardActingHelpers').slice()
|
|
7
7
|
|
|
8
|
-
const methodsToDelay = [
|
|
9
|
-
'click',
|
|
10
|
-
'fillField',
|
|
11
|
-
'checkOption',
|
|
12
|
-
'pressKey',
|
|
13
|
-
'doubleClick',
|
|
14
|
-
'rightClick',
|
|
15
|
-
];
|
|
8
|
+
const methodsToDelay = ['click', 'fillField', 'checkOption', 'pressKey', 'doubleClick', 'rightClick']
|
|
16
9
|
|
|
17
10
|
const defaultConfig = {
|
|
18
11
|
methods: methodsToDelay,
|
|
19
12
|
delayBefore: 100,
|
|
20
13
|
delayAfter: 200,
|
|
21
|
-
}
|
|
14
|
+
}
|
|
22
15
|
|
|
23
16
|
/**
|
|
24
17
|
*
|
|
@@ -59,41 +52,41 @@ const defaultConfig = {
|
|
|
59
52
|
*
|
|
60
53
|
*/
|
|
61
54
|
module.exports = function (config) {
|
|
62
|
-
supportedHelpers.push('REST')
|
|
63
|
-
const helpers = Container.helpers()
|
|
64
|
-
let helper
|
|
55
|
+
supportedHelpers.push('REST')
|
|
56
|
+
const helpers = Container.helpers()
|
|
57
|
+
let helper
|
|
65
58
|
|
|
66
|
-
config = Object.assign(defaultConfig, config)
|
|
59
|
+
config = Object.assign(defaultConfig, config)
|
|
67
60
|
|
|
68
61
|
for (const helperName of supportedHelpers) {
|
|
69
62
|
if (Object.keys(helpers).indexOf(helperName) > -1) {
|
|
70
|
-
helper = helpers[helperName]
|
|
63
|
+
helper = helpers[helperName]
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
66
|
|
|
74
|
-
if (!helper) return
|
|
67
|
+
if (!helper) return // no helpers for auto-delay
|
|
75
68
|
|
|
76
69
|
event.dispatcher.on(event.step.before, (step) => {
|
|
77
|
-
if (config.methods.indexOf(step.helperMethod) < 0) return
|
|
70
|
+
if (config.methods.indexOf(step.helperMethod) < 0) return // skip non-actions
|
|
78
71
|
|
|
79
72
|
recorder.add('auto-delay', async () => {
|
|
80
|
-
if (store.debugMode) return
|
|
81
|
-
log(`Delaying for ${config.delayBefore}ms`)
|
|
73
|
+
if (store.debugMode) return // no need to delay in debug
|
|
74
|
+
log(`Delaying for ${config.delayBefore}ms`)
|
|
82
75
|
return new Promise((resolve) => {
|
|
83
|
-
setTimeout(resolve, config.delayBefore)
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
})
|
|
76
|
+
setTimeout(resolve, config.delayBefore)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
})
|
|
87
80
|
|
|
88
81
|
event.dispatcher.on(event.step.after, (step) => {
|
|
89
|
-
if (config.methods.indexOf(step.helperMethod) < 0) return
|
|
82
|
+
if (config.methods.indexOf(step.helperMethod) < 0) return // skip non-actions
|
|
90
83
|
|
|
91
84
|
recorder.add('auto-delay', async () => {
|
|
92
|
-
if (store.debugMode) return
|
|
93
|
-
log(`Delaying for ${config.delayAfter}ms`)
|
|
85
|
+
if (store.debugMode) return // no need to delay in debug
|
|
86
|
+
log(`Delaying for ${config.delayAfter}ms`)
|
|
94
87
|
return new Promise((resolve) => {
|
|
95
|
-
setTimeout(resolve, config.delayAfter)
|
|
96
|
-
})
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
}
|
|
88
|
+
setTimeout(resolve, config.delayAfter)
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
}
|
package/lib/plugin/autoLogin.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const { fileExists } = require('../utils')
|
|
4
|
-
const container = require('../container')
|
|
5
|
-
const store = require('../store')
|
|
6
|
-
const recorder = require('../recorder')
|
|
7
|
-
const { debug } = require('../output')
|
|
8
|
-
const isAsyncFunction = require('../utils').isAsyncFunction
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { fileExists } = require('../utils')
|
|
4
|
+
const container = require('../container')
|
|
5
|
+
const store = require('../store')
|
|
6
|
+
const recorder = require('../recorder')
|
|
7
|
+
const { debug } = require('../output')
|
|
8
|
+
const isAsyncFunction = require('../utils').isAsyncFunction
|
|
9
9
|
|
|
10
10
|
const defaultUser = {
|
|
11
|
-
fetch: I => I.grabCookie(),
|
|
11
|
+
fetch: (I) => I.grabCookie(),
|
|
12
12
|
check: () => {},
|
|
13
13
|
restore: (I, cookies) => {
|
|
14
|
-
I.amOnPage('/')
|
|
15
|
-
I.setCookie(cookies)
|
|
14
|
+
I.amOnPage('/') // open a page
|
|
15
|
+
I.setCookie(cookies)
|
|
16
16
|
},
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
|
|
19
19
|
const defaultConfig = {
|
|
20
20
|
saveToFile: false,
|
|
21
21
|
inject: 'login',
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Logs user in for the first test and reuses session for next tests.
|
|
@@ -249,88 +249,92 @@ const defaultConfig = {
|
|
|
249
249
|
* })
|
|
250
250
|
*
|
|
251
251
|
*
|
|
252
|
-
*/
|
|
252
|
+
*/
|
|
253
253
|
module.exports = function (config) {
|
|
254
|
-
config = Object.assign(defaultConfig, config)
|
|
255
|
-
Object.keys(config.users).map(
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
254
|
+
config = Object.assign(defaultConfig, config)
|
|
255
|
+
Object.keys(config.users).map(
|
|
256
|
+
(u) =>
|
|
257
|
+
(config.users[u] = {
|
|
258
|
+
...defaultUser,
|
|
259
|
+
...config.users[u],
|
|
260
|
+
}),
|
|
261
|
+
)
|
|
259
262
|
|
|
260
263
|
if (config.saveToFile) {
|
|
261
264
|
// loading from file
|
|
262
265
|
for (const name in config.users) {
|
|
263
|
-
const fileName = path.join(global.output_dir, `${name}_session.json`)
|
|
264
|
-
if (!fileExists(fileName)) continue
|
|
265
|
-
const data = fs.readFileSync(fileName).toString()
|
|
266
|
+
const fileName = path.join(global.output_dir, `${name}_session.json`)
|
|
267
|
+
if (!fileExists(fileName)) continue
|
|
268
|
+
const data = fs.readFileSync(fileName).toString()
|
|
266
269
|
try {
|
|
267
|
-
store[`${name}_session`] = JSON.parse(data)
|
|
270
|
+
store[`${name}_session`] = JSON.parse(data)
|
|
268
271
|
} catch (err) {
|
|
269
|
-
throw new Error(`Could not load session from ${fileName}\n${err}`)
|
|
272
|
+
throw new Error(`Could not load session from ${fileName}\n${err}`)
|
|
270
273
|
}
|
|
271
|
-
debug(`Loaded user session for ${name}`)
|
|
274
|
+
debug(`Loaded user session for ${name}`)
|
|
272
275
|
}
|
|
273
276
|
}
|
|
274
277
|
|
|
275
278
|
const loginFunction = async (name) => {
|
|
276
|
-
const userSession = config.users[name]
|
|
277
|
-
const I = container.support('I')
|
|
278
|
-
const cookies = store[`${name}_session`]
|
|
279
|
-
const shouldAwait =
|
|
280
|
-
|| isAsyncFunction(userSession.restore)
|
|
281
|
-
|| isAsyncFunction(userSession.check);
|
|
279
|
+
const userSession = config.users[name]
|
|
280
|
+
const I = container.support('I')
|
|
281
|
+
const cookies = store[`${name}_session`]
|
|
282
|
+
const shouldAwait =
|
|
283
|
+
isAsyncFunction(userSession.login) || isAsyncFunction(userSession.restore) || isAsyncFunction(userSession.check)
|
|
282
284
|
|
|
283
285
|
const loginAndSave = async () => {
|
|
284
286
|
if (shouldAwait) {
|
|
285
|
-
await userSession.login(I)
|
|
287
|
+
await userSession.login(I)
|
|
286
288
|
} else {
|
|
287
|
-
userSession.login(I)
|
|
289
|
+
userSession.login(I)
|
|
288
290
|
}
|
|
289
291
|
|
|
290
|
-
const cookies = await userSession.fetch(I)
|
|
292
|
+
const cookies = await userSession.fetch(I)
|
|
291
293
|
if (!cookies) {
|
|
292
|
-
debug(
|
|
293
|
-
return
|
|
294
|
+
debug("Cannot save user session with empty cookies from auto login's fetch method")
|
|
295
|
+
return
|
|
294
296
|
}
|
|
295
297
|
if (config.saveToFile) {
|
|
296
|
-
debug(`Saved user session into file for ${name}`)
|
|
297
|
-
fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies))
|
|
298
|
+
debug(`Saved user session into file for ${name}`)
|
|
299
|
+
fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies))
|
|
298
300
|
}
|
|
299
|
-
store[`${name}_session`] = cookies
|
|
300
|
-
}
|
|
301
|
+
store[`${name}_session`] = cookies
|
|
302
|
+
}
|
|
301
303
|
|
|
302
|
-
if (!cookies) return loginAndSave()
|
|
304
|
+
if (!cookies) return loginAndSave()
|
|
303
305
|
|
|
304
|
-
recorder.session.start('check login')
|
|
306
|
+
recorder.session.start('check login')
|
|
305
307
|
if (shouldAwait) {
|
|
306
|
-
await userSession.restore(I, cookies)
|
|
307
|
-
await userSession.check(I, cookies)
|
|
308
|
+
await userSession.restore(I, cookies)
|
|
309
|
+
await userSession.check(I, cookies)
|
|
308
310
|
} else {
|
|
309
|
-
userSession.restore(I, cookies)
|
|
310
|
-
userSession.check(I, cookies)
|
|
311
|
+
userSession.restore(I, cookies)
|
|
312
|
+
userSession.check(I, cookies)
|
|
311
313
|
}
|
|
312
314
|
recorder.session.catch((err) => {
|
|
313
|
-
debug(`Failed auto login for ${name} due to ${err}`)
|
|
314
|
-
debug('Logging in again')
|
|
315
|
-
recorder.session.start('auto login')
|
|
316
|
-
return loginAndSave()
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
315
|
+
debug(`Failed auto login for ${name} due to ${err}`)
|
|
316
|
+
debug('Logging in again')
|
|
317
|
+
recorder.session.start('auto login')
|
|
318
|
+
return loginAndSave()
|
|
319
|
+
.then(() => {
|
|
320
|
+
recorder.add(() => recorder.session.restore('auto login'))
|
|
321
|
+
recorder.catch(() => debug('continue'))
|
|
322
|
+
})
|
|
323
|
+
.catch((err) => {
|
|
324
|
+
recorder.session.restore('auto login')
|
|
325
|
+
recorder.session.restore('check login')
|
|
326
|
+
recorder.throw(err)
|
|
327
|
+
})
|
|
328
|
+
})
|
|
325
329
|
recorder.add(() => {
|
|
326
|
-
recorder.session.restore('check login')
|
|
327
|
-
})
|
|
330
|
+
recorder.session.restore('check login')
|
|
331
|
+
})
|
|
328
332
|
|
|
329
|
-
return recorder.promise()
|
|
330
|
-
}
|
|
333
|
+
return recorder.promise()
|
|
334
|
+
}
|
|
331
335
|
|
|
332
336
|
// adding this to DI container
|
|
333
|
-
const support = {}
|
|
334
|
-
support[config.inject] = loginFunction
|
|
335
|
-
container.append({ support })
|
|
336
|
-
}
|
|
337
|
+
const support = {}
|
|
338
|
+
support[config.inject] = loginFunction
|
|
339
|
+
container.append({ support })
|
|
340
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const event = require('../event')
|
|
2
|
-
const recorder = require('../recorder')
|
|
3
|
-
const { MetaStep } = require('../step')
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const recorder = require('../recorder')
|
|
3
|
+
const { MetaStep } = require('../step')
|
|
4
4
|
|
|
5
|
-
let currentCommentStep
|
|
5
|
+
let currentCommentStep
|
|
6
6
|
|
|
7
|
-
const defaultGlobalName = '__'
|
|
7
|
+
const defaultGlobalName = '__'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Add descriptive nested steps for your tests:
|
|
@@ -101,36 +101,36 @@ const defaultGlobalName = '__';
|
|
|
101
101
|
*/
|
|
102
102
|
module.exports = function (config) {
|
|
103
103
|
event.dispatcher.on(event.test.started, () => {
|
|
104
|
-
currentCommentStep = null
|
|
105
|
-
})
|
|
104
|
+
currentCommentStep = null
|
|
105
|
+
})
|
|
106
106
|
|
|
107
107
|
event.dispatcher.on(event.step.started, (step) => {
|
|
108
108
|
if (currentCommentStep) {
|
|
109
|
-
const metaStep = getRootMetaStep(step)
|
|
109
|
+
const metaStep = getRootMetaStep(step)
|
|
110
110
|
|
|
111
111
|
if (metaStep !== currentCommentStep) {
|
|
112
|
-
metaStep.metaStep = currentCommentStep
|
|
112
|
+
metaStep.metaStep = currentCommentStep
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
})
|
|
115
|
+
})
|
|
116
116
|
|
|
117
117
|
if (config.registerGlobal) {
|
|
118
118
|
if (config.registerGlobal === true) {
|
|
119
|
-
config.registerGlobal = defaultGlobalName
|
|
119
|
+
config.registerGlobal = defaultGlobalName
|
|
120
120
|
}
|
|
121
|
-
global[config.registerGlobal] = setCommentString
|
|
121
|
+
global[config.registerGlobal] = setCommentString
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
return setCommentString
|
|
125
|
-
}
|
|
124
|
+
return setCommentString
|
|
125
|
+
}
|
|
126
126
|
|
|
127
127
|
function getRootMetaStep(step) {
|
|
128
|
-
if (step.metaStep) return getRootMetaStep(step.metaStep)
|
|
129
|
-
return step
|
|
128
|
+
if (step.metaStep) return getRootMetaStep(step.metaStep)
|
|
129
|
+
return step
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
function setCommentString(string) {
|
|
133
133
|
recorder.add('set comment metastep', () => {
|
|
134
|
-
currentCommentStep = new MetaStep(String.raw(string), '')
|
|
135
|
-
})
|
|
134
|
+
currentCommentStep = new MetaStep(String.raw(string), '')
|
|
135
|
+
})
|
|
136
136
|
}
|