codeceptjs 3.6.7 → 4.0.0-beta.2
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 +81 -84
- package/lib/actor.js +13 -13
- package/lib/ai.js +13 -10
- package/lib/assert/empty.js +21 -20
- package/lib/assert/equal.js +39 -37
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +47 -46
- package/lib/assert/throws.js +11 -13
- package/lib/assert/truth.js +22 -19
- package/lib/assert.js +2 -4
- package/lib/cli.js +49 -57
- package/lib/codecept.js +155 -142
- package/lib/colorUtils.js +3 -3
- package/lib/command/configMigrate.js +52 -58
- package/lib/command/definitions.js +89 -88
- package/lib/command/dryRun.js +68 -71
- package/lib/command/generate.js +188 -197
- package/lib/command/gherkin/init.js +16 -27
- package/lib/command/gherkin/snippets.js +20 -20
- package/lib/command/gherkin/steps.js +8 -8
- package/lib/command/info.js +38 -40
- package/lib/command/init.js +288 -290
- package/lib/command/interactive.js +32 -32
- package/lib/command/list.js +26 -26
- package/lib/command/run-multiple/chunk.js +5 -5
- package/lib/command/run-multiple/collection.js +3 -3
- package/lib/command/run-multiple/run.js +2 -6
- package/lib/command/run-multiple.js +93 -113
- package/lib/command/run-rerun.js +25 -20
- package/lib/command/run-workers.js +66 -64
- package/lib/command/run.js +29 -26
- package/lib/command/utils.js +65 -80
- package/lib/command/workers/runTests.js +10 -10
- package/lib/config.js +9 -10
- package/lib/container.js +48 -40
- package/lib/data/context.js +59 -60
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +29 -29
- package/lib/data/table.js +20 -26
- package/lib/dirname.js +5 -0
- package/lib/event.js +167 -163
- package/lib/heal.js +17 -13
- package/lib/helper/AI.js +41 -130
- package/lib/helper/ApiDataFactory.js +69 -73
- package/lib/helper/Appium.js +381 -412
- package/lib/helper/Expect.js +425 -0
- package/lib/helper/ExpectHelper.js +48 -40
- package/lib/helper/FileSystem.js +79 -80
- package/lib/helper/GraphQL.js +43 -44
- package/lib/helper/GraphQLDataFactory.js +50 -50
- package/lib/helper/JSONResponse.js +62 -65
- package/lib/helper/Mochawesome.js +28 -28
- package/lib/helper/MockServer.js +14 -12
- package/lib/helper/Nightmare.js +566 -662
- package/lib/helper/Playwright.js +1216 -1361
- package/lib/helper/Protractor.js +627 -663
- package/lib/helper/Puppeteer.js +1128 -1231
- package/lib/helper/REST.js +68 -159
- package/lib/helper/SoftExpectHelper.js +2 -2
- package/lib/helper/TestCafe.js +484 -490
- package/lib/helper/WebDriver.js +1156 -1297
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- package/lib/helper/errors/ConnectionRefused.js +1 -1
- package/lib/helper/errors/ElementAssertion.js +2 -2
- package/lib/helper/errors/ElementNotFound.js +2 -2
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
- package/lib/helper/extras/Console.js +1 -1
- package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
- package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
- package/lib/helper/extras/PlaywrightRestartOpts.js +18 -21
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +3 -3
- package/lib/helper/network/actions.js +7 -14
- package/lib/helper/network/utils.js +2 -3
- package/lib/helper/scripts/blurElement.js +1 -1
- package/lib/helper/scripts/focusElement.js +1 -1
- package/lib/helper/scripts/highlightElement.js +1 -1
- package/lib/helper/scripts/isElementClickable.js +1 -1
- package/lib/helper/testcafe/testControllerHolder.js +1 -1
- package/lib/helper/testcafe/testcafe-utils.js +7 -6
- package/lib/helper.js +3 -1
- package/lib/history.js +5 -6
- package/lib/hooks.js +6 -6
- package/lib/html.js +7 -7
- package/lib/index.js +41 -25
- package/lib/interfaces/bdd.js +64 -47
- package/lib/interfaces/featureConfig.js +19 -19
- package/lib/interfaces/gherkin.js +118 -124
- package/lib/interfaces/scenarioConfig.js +29 -29
- package/lib/listener/artifacts.js +9 -9
- package/lib/listener/config.js +24 -24
- 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 +30 -32
- package/lib/listener/steps.js +53 -50
- package/lib/listener/timeout.js +54 -54
- package/lib/locator.js +10 -6
- package/lib/mochaFactory.js +15 -18
- package/lib/output.js +10 -6
- package/lib/parser.js +12 -15
- package/lib/pause.js +33 -40
- package/lib/plugin/allure.js +15 -15
- package/lib/plugin/autoDelay.js +37 -29
- package/lib/plugin/autoLogin.js +65 -70
- package/lib/plugin/commentStep.js +18 -18
- package/lib/plugin/coverage.js +67 -115
- package/lib/plugin/customLocator.js +20 -21
- package/lib/plugin/debugErrors.js +24 -24
- package/lib/plugin/eachElement.js +38 -38
- package/lib/plugin/fakerTransform.js +6 -6
- package/lib/plugin/heal.js +108 -67
- package/lib/plugin/pauseOnFail.js +11 -11
- package/lib/plugin/retryFailedStep.js +39 -32
- package/lib/plugin/retryTo.js +40 -46
- package/lib/plugin/screenshotOnFail.js +87 -109
- package/lib/plugin/selenoid.js +118 -131
- package/lib/plugin/standardActingHelpers.js +8 -2
- package/lib/plugin/stepByStepReport.js +91 -110
- package/lib/plugin/stepTimeout.js +23 -24
- package/lib/plugin/subtitles.js +35 -34
- package/lib/plugin/tryTo.js +30 -40
- package/lib/plugin/wdio.js +75 -78
- package/lib/recorder.js +17 -14
- package/lib/rerun.js +10 -11
- package/lib/scenario.js +23 -25
- package/lib/secret.js +2 -4
- package/lib/session.js +10 -10
- package/lib/step.js +9 -12
- package/lib/store.js +3 -2
- package/lib/transform.js +1 -1
- package/lib/translation.js +8 -7
- package/lib/ui.js +14 -12
- package/lib/utils.js +72 -70
- package/lib/within.js +10 -10
- package/lib/workerStorage.js +25 -27
- package/lib/workers.js +32 -29
- package/package.json +53 -51
- package/translations/de-DE.js +1 -1
- package/translations/fr-FR.js +1 -1
- package/translations/index.js +13 -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 +65 -415
package/lib/plugin/coverage.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
import { CoverageReport } from 'monocart-coverage-reports';
|
|
3
|
+
import container from '../container.js';
|
|
4
|
+
import recorder from '../recorder.js';
|
|
5
|
+
import * as event from '../event.js';
|
|
6
|
+
import * as output from '../output.js';
|
|
7
|
+
import { deepMerge } from '../utils.js';
|
|
8
8
|
|
|
9
9
|
const defaultConfig = {
|
|
10
10
|
name: 'CodeceptJS Coverage Report',
|
|
11
11
|
outputDir: 'output/coverage',
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
|
|
14
|
-
const supportedHelpers = ['Puppeteer', 'Playwright'
|
|
14
|
+
const supportedHelpers = ['Puppeteer', 'Playwright'];
|
|
15
15
|
|
|
16
16
|
const v8CoverageHelpers = {
|
|
17
17
|
Playwright: {
|
|
@@ -23,15 +23,15 @@ const v8CoverageHelpers = {
|
|
|
23
23
|
page.coverage.startCSSCoverage({
|
|
24
24
|
resetOnNavigation: false,
|
|
25
25
|
}),
|
|
26
|
-
])
|
|
26
|
+
]);
|
|
27
27
|
},
|
|
28
28
|
takeCoverage: async (page, coverageReport) => {
|
|
29
29
|
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
30
30
|
page.coverage.stopJSCoverage(),
|
|
31
31
|
page.coverage.stopCSSCoverage(),
|
|
32
|
-
])
|
|
33
|
-
const coverageList = [...jsCoverage, ...cssCoverage]
|
|
34
|
-
await coverageReport.add(coverageList)
|
|
32
|
+
]);
|
|
33
|
+
const coverageList = [...jsCoverage, ...cssCoverage];
|
|
34
|
+
await coverageReport.add(coverageList);
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
Puppeteer: {
|
|
@@ -44,57 +44,24 @@ const v8CoverageHelpers = {
|
|
|
44
44
|
page.coverage.startCSSCoverage({
|
|
45
45
|
resetOnNavigation: false,
|
|
46
46
|
}),
|
|
47
|
-
])
|
|
47
|
+
]);
|
|
48
48
|
},
|
|
49
49
|
takeCoverage: async (page, coverageReport) => {
|
|
50
50
|
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
51
51
|
page.coverage.stopJSCoverage(),
|
|
52
52
|
page.coverage.stopCSSCoverage(),
|
|
53
|
-
])
|
|
53
|
+
]);
|
|
54
54
|
// to raw V8 script coverage
|
|
55
|
-
const coverageList = [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
...cssCoverage,
|
|
63
|
-
]
|
|
64
|
-
await coverageReport.add(coverageList)
|
|
55
|
+
const coverageList = [...jsCoverage.map((it) => {
|
|
56
|
+
return {
|
|
57
|
+
source: it.text,
|
|
58
|
+
...it.rawScriptCoverage,
|
|
59
|
+
};
|
|
60
|
+
}), ...cssCoverage];
|
|
61
|
+
await coverageReport.add(coverageList);
|
|
65
62
|
},
|
|
66
63
|
},
|
|
67
|
-
|
|
68
|
-
startCoverage: async (page) => {
|
|
69
|
-
await Promise.all([
|
|
70
|
-
page.coverage.startJSCoverage({
|
|
71
|
-
resetOnNavigation: false,
|
|
72
|
-
includeRawScriptCoverage: true,
|
|
73
|
-
}),
|
|
74
|
-
page.coverage.startCSSCoverage({
|
|
75
|
-
resetOnNavigation: false,
|
|
76
|
-
}),
|
|
77
|
-
])
|
|
78
|
-
},
|
|
79
|
-
takeCoverage: async (page, coverageReport) => {
|
|
80
|
-
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
81
|
-
page.coverage.stopJSCoverage(),
|
|
82
|
-
page.coverage.stopCSSCoverage(),
|
|
83
|
-
])
|
|
84
|
-
// to raw V8 script coverage
|
|
85
|
-
const coverageList = [
|
|
86
|
-
...jsCoverage.map((it) => {
|
|
87
|
-
return {
|
|
88
|
-
source: it.text,
|
|
89
|
-
...it.rawScriptCoverage,
|
|
90
|
-
}
|
|
91
|
-
}),
|
|
92
|
-
...cssCoverage,
|
|
93
|
-
]
|
|
94
|
-
await coverageReport.add(coverageList)
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
}
|
|
64
|
+
};
|
|
98
65
|
|
|
99
66
|
/**
|
|
100
67
|
* Dumps code coverage from Playwright/Puppeteer after every test.
|
|
@@ -122,82 +89,67 @@ const v8CoverageHelpers = {
|
|
|
122
89
|
* * `sourcePath`: option to resolve a custom path.
|
|
123
90
|
*
|
|
124
91
|
*/
|
|
125
|
-
module.exports = function (config) {
|
|
126
|
-
config = deepMerge(defaultConfig, config)
|
|
127
92
|
|
|
128
|
-
|
|
93
|
+
export default function (config) {
|
|
94
|
+
config = deepMerge(defaultConfig, config);
|
|
95
|
+
if (config.debug) config.logging = 'debug';
|
|
96
|
+
const helpers = container.helpers();
|
|
97
|
+
console.log(helpers);
|
|
98
|
+
let coverageRunning = false;
|
|
129
99
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const v8Names = Object.keys(v8CoverageHelpers)
|
|
134
|
-
const helperName = Object.keys(helpers).find((it) => v8Names.includes(it))
|
|
100
|
+
const v8Names = Object.keys(v8CoverageHelpers);
|
|
101
|
+
const helperName = Object.keys(helpers).find((it) => v8Names.includes(it));
|
|
135
102
|
if (!helperName) {
|
|
136
|
-
console.error(`Coverage is only supported in ${supportedHelpers.join(' or ')}`)
|
|
103
|
+
console.error(`Coverage is only supported in ${supportedHelpers.join(' or ')}`);
|
|
137
104
|
// no helpers for screenshot
|
|
138
|
-
return
|
|
105
|
+
return;
|
|
139
106
|
}
|
|
140
107
|
|
|
141
|
-
config.name = `${config.name} - in ${helperName}
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
const helper = helpers[helperName]
|
|
145
|
-
|
|
146
|
-
if (helperName === 'WebDriver' && !helper.config.devtoolsProtocol)
|
|
147
|
-
throw Error('Coverage is currently supporting the WebDriver running with Devtools protocol.')
|
|
108
|
+
config.name = `${config.name} - in ${helperName}`;
|
|
109
|
+
const logger = debug(`codeceptjs:plugin:${helperName.toLowerCase()}Coverage`);
|
|
148
110
|
|
|
149
|
-
const
|
|
111
|
+
const helper = helpers[helperName];
|
|
112
|
+
const v8Helper = v8CoverageHelpers[helperName];
|
|
150
113
|
|
|
151
114
|
const coverageOptions = {
|
|
152
115
|
...config,
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const coverageReport = new CoverageReport(coverageOptions)
|
|
158
|
-
coverageReport.cleanCache()
|
|
116
|
+
};
|
|
117
|
+
const coverageReport = new CoverageReport(coverageOptions);
|
|
118
|
+
coverageReport.cleanCache();
|
|
159
119
|
|
|
160
120
|
event.dispatcher.on(event.all.after, async () => {
|
|
161
|
-
output.print(`writing ${coverageOptions.outputDir}`)
|
|
162
|
-
await coverageReport.generate()
|
|
163
|
-
})
|
|
121
|
+
output.print(`writing ${coverageOptions.outputDir}`);
|
|
122
|
+
await coverageReport.generate();
|
|
123
|
+
});
|
|
164
124
|
|
|
165
125
|
// we're going to try to "start" coverage before each step because this is
|
|
166
126
|
// when the browser is already up and is ready to start coverage.
|
|
167
127
|
event.dispatcher.on(event.step.before, () => {
|
|
168
|
-
recorder.add(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
},
|
|
181
|
-
true,
|
|
182
|
-
)
|
|
183
|
-
})
|
|
128
|
+
recorder.add('start coverage', async () => {
|
|
129
|
+
if (coverageRunning) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!helper.page || !helper.page.coverage) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
coverageRunning = true;
|
|
136
|
+
logger('--> starting coverage <--');
|
|
137
|
+
await v8Helper.startCoverage(helper.page);
|
|
138
|
+
}, true);
|
|
139
|
+
});
|
|
184
140
|
|
|
185
141
|
// Save coverage data after every test run
|
|
186
142
|
event.dispatcher.on(event.test.after, (test) => {
|
|
187
|
-
recorder.add(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
},
|
|
200
|
-
true,
|
|
201
|
-
)
|
|
202
|
-
})
|
|
143
|
+
recorder.add('take coverage', async () => {
|
|
144
|
+
if (!coverageRunning) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (!helper.page || !helper.page.coverage) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
coverageRunning = false;
|
|
151
|
+
logger('--> stopping coverage <--');
|
|
152
|
+
await v8Helper.takeCoverage(helper.page, coverageReport);
|
|
153
|
+
}, true);
|
|
154
|
+
});
|
|
203
155
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import Locator from '../locator.js';
|
|
2
|
+
import { xpathLocator } from '../utils.js';
|
|
3
3
|
|
|
4
4
|
const defaultConfig = {
|
|
5
5
|
prefix: '$',
|
|
6
6
|
attribute: 'data-test-id',
|
|
7
7
|
strategy: 'xpath',
|
|
8
8
|
showActual: false,
|
|
9
|
-
}
|
|
9
|
+
};
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Creates a [custom locator](https://codecept.io/locators#custom-locators) by using special attributes in HTML.
|
|
@@ -111,35 +111,34 @@ const defaultConfig = {
|
|
|
111
111
|
* I.click('=sign-up'); // matches => [data-qa=sign-up],[data-test=sign-up]
|
|
112
112
|
* ```
|
|
113
113
|
*/
|
|
114
|
-
|
|
115
|
-
config = { ...defaultConfig, ...config }
|
|
114
|
+
export default (config) => {
|
|
115
|
+
config = { ...defaultConfig, ...config };
|
|
116
116
|
|
|
117
117
|
Locator.addFilter((value, locatorObj) => {
|
|
118
|
-
if (typeof value !== 'string') return
|
|
119
|
-
if (!value.startsWith(config.prefix)) return
|
|
118
|
+
if (typeof value !== 'string') return;
|
|
119
|
+
if (!value.startsWith(config.prefix)) return;
|
|
120
120
|
|
|
121
|
-
if (!['String', 'Array'].includes(config.attribute.constructor.name)) return
|
|
121
|
+
if (!['String', 'Array'].includes(config.attribute.constructor.name)) return;
|
|
122
122
|
|
|
123
|
-
const val = value.substr(config.prefix.length)
|
|
123
|
+
const val = value.substr(config.prefix.length);
|
|
124
124
|
|
|
125
125
|
if (config.strategy.toLowerCase() === 'xpath') {
|
|
126
|
-
locatorObj.value = `.//*[${
|
|
127
|
-
.concat(config.attribute)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
locatorObj.type = 'xpath'
|
|
126
|
+
locatorObj.value = `.//*[${
|
|
127
|
+
[].concat(config.attribute)
|
|
128
|
+
.map((attr) => `@${attr}=${xpathLocator.literal(val)}`)
|
|
129
|
+
.join(' or ')}]`;
|
|
130
|
+
locatorObj.type = 'xpath';
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
if (config.strategy.toLowerCase() === 'css') {
|
|
134
|
-
locatorObj.value = []
|
|
135
|
-
.concat(config.attribute)
|
|
134
|
+
locatorObj.value = [].concat(config.attribute)
|
|
136
135
|
.map((attr) => `[${attr}=${val}]`)
|
|
137
|
-
.join(',')
|
|
138
|
-
locatorObj.type = 'css'
|
|
136
|
+
.join(',');
|
|
137
|
+
locatorObj.type = 'css';
|
|
139
138
|
}
|
|
140
139
|
|
|
141
140
|
if (config.showActual) {
|
|
142
|
-
locatorObj.output = locatorObj.value
|
|
141
|
+
locatorObj.output = locatorObj.value;
|
|
143
142
|
}
|
|
144
|
-
})
|
|
145
|
-
}
|
|
143
|
+
});
|
|
144
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import Container from '../container.js';
|
|
2
|
+
import recorder from '../recorder.js';
|
|
3
|
+
import * as event from '../event.js';
|
|
4
|
+
import supportedHelpers from './standardActingHelpers.js';
|
|
5
|
+
import { scanForErrorMessages } from '../html';
|
|
6
|
+
import { output } from '..';
|
|
7
7
|
|
|
8
8
|
const defaultConfig = {
|
|
9
9
|
errorClasses: ['error', 'warning', 'alert', 'danger'],
|
|
10
|
-
}
|
|
10
|
+
};
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Prints errors found in HTML code after each failed test.
|
|
@@ -29,39 +29,39 @@ const defaultConfig = {
|
|
|
29
29
|
* * `errorClasses` - list of classes to search for errors (default: `['error', 'warning', 'alert', 'danger']`)
|
|
30
30
|
*
|
|
31
31
|
*/
|
|
32
|
-
|
|
33
|
-
const helpers = Container.helpers()
|
|
34
|
-
let helper
|
|
32
|
+
export default function (config = {}) {
|
|
33
|
+
const helpers = Container.helpers();
|
|
34
|
+
let helper;
|
|
35
35
|
|
|
36
|
-
config = Object.assign(defaultConfig, config)
|
|
36
|
+
config = Object.assign(defaultConfig, config);
|
|
37
37
|
|
|
38
38
|
for (const helperName of supportedHelpers) {
|
|
39
39
|
if (Object.keys(helpers).indexOf(helperName) > -1) {
|
|
40
|
-
helper = helpers[helperName]
|
|
40
|
+
helper = helpers[helperName];
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
if (!helper) return // no helpers for screenshot
|
|
44
|
+
if (!helper) return; // no helpers for screenshot
|
|
45
45
|
|
|
46
46
|
event.dispatcher.on(event.test.failed, (test) => {
|
|
47
47
|
recorder.add('HTML snapshot failed test', async () => {
|
|
48
48
|
try {
|
|
49
|
-
const currentOutputLevel = output.level()
|
|
50
|
-
output.level(0)
|
|
51
|
-
const html = await helper.grabHTMLFrom('body')
|
|
52
|
-
output.level(currentOutputLevel)
|
|
49
|
+
const currentOutputLevel = output.level();
|
|
50
|
+
output.level(0);
|
|
51
|
+
const html = await helper.grabHTMLFrom('body');
|
|
52
|
+
output.level(currentOutputLevel);
|
|
53
53
|
|
|
54
|
-
if (!html) return
|
|
54
|
+
if (!html) return;
|
|
55
55
|
|
|
56
|
-
const errors = scanForErrorMessages(html, config.errorClasses)
|
|
56
|
+
const errors = scanForErrorMessages(html, config.errorClasses);
|
|
57
57
|
if (errors.length) {
|
|
58
|
-
output.debug('Detected errors in HTML code')
|
|
59
|
-
errors.forEach((error) => output.debug(error))
|
|
60
|
-
test.artifacts.errors = errors
|
|
58
|
+
output.debug('Detected errors in HTML code');
|
|
59
|
+
errors.forEach((error) => output.debug(error));
|
|
60
|
+
test.artifacts.errors = errors;
|
|
61
61
|
}
|
|
62
62
|
} catch (err) {
|
|
63
63
|
// not really needed
|
|
64
64
|
}
|
|
65
|
-
})
|
|
66
|
-
})
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
67
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import * as output from '../output.js';
|
|
2
|
+
import { store } from '../store.js';
|
|
3
|
+
import recorder from '../recorder.js';
|
|
4
|
+
import container from '../container.js';
|
|
5
|
+
import * as event from '../event.js';
|
|
6
|
+
import { Step } from '../step.js';
|
|
7
|
+
import { isAsyncFunction } from '../utils.js';
|
|
8
8
|
|
|
9
9
|
const defaultConfig = {
|
|
10
10
|
registerGlobal: true,
|
|
11
|
-
}
|
|
11
|
+
};
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Provides `eachElement` global function to iterate over found elements to perform actions on them.
|
|
15
15
|
*
|
|
16
16
|
* `eachElement` takes following args:
|
|
17
|
-
* * `purpose` - the goal of an action. A comment text that will be displayed in output.
|
|
17
|
+
* * `purpose` - the goal of an action. A comment text that will be displayed in output.output.
|
|
18
18
|
* * `locator` - a CSS/XPath locator to match elements
|
|
19
19
|
* * `fn(element, index)` - **asynchronous** function which will be executed for each matched element.
|
|
20
20
|
*
|
|
@@ -69,59 +69,59 @@ const defaultConfig = {
|
|
|
69
69
|
* @return {Promise<*> | undefined}
|
|
70
70
|
*/
|
|
71
71
|
function eachElement(purpose, locator, fn) {
|
|
72
|
-
if (store.dryRun) return
|
|
73
|
-
const helpers = Object.values(container.helpers())
|
|
72
|
+
if (store.dryRun) return;
|
|
73
|
+
const helpers = Object.values(container.helpers());
|
|
74
74
|
|
|
75
|
-
const helper = helpers.filter(
|
|
75
|
+
const helper = helpers.filter(h => !!h._locate)[0];
|
|
76
76
|
|
|
77
77
|
if (!helper) {
|
|
78
|
-
throw new Error('No helper enabled with _locate method with returns a list of elements.')
|
|
78
|
+
throw new Error('No helper enabled with _locate method with returns a list of elements.');
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
if (!isAsyncFunction(fn)) {
|
|
82
|
-
throw new Error('Async function should be passed into each element')
|
|
82
|
+
throw new Error('Async function should be passed into each element');
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
const step = new Step(helper, `${purpose || 'each element'} within "${locator}"`)
|
|
86
|
-
step.helperMethod = '_locate'
|
|
85
|
+
const step = new Step(helper, `${purpose || 'each element'} within "${locator}"`);
|
|
86
|
+
step.helperMethod = '_locate';
|
|
87
87
|
// eachElement('select all users', 'locator', async (el) => {
|
|
88
|
-
event.dispatcher.emit(event.step.before, step)
|
|
88
|
+
event.dispatcher.emit(event.step.before, step);
|
|
89
89
|
|
|
90
90
|
return recorder.add('register each element wrapper', async () => {
|
|
91
|
-
event.emit(event.step.started, step)
|
|
92
|
-
const els = await helper._locate(locator)
|
|
93
|
-
output.debug(`Found ${els.length} elements for each elements to iterate`)
|
|
91
|
+
event.emit(event.step.started, step);
|
|
92
|
+
const els = await helper._locate(locator);
|
|
93
|
+
output.output.debug(`Found ${els.length} elements for each elements to iterate`);
|
|
94
94
|
|
|
95
|
-
const errs = []
|
|
96
|
-
let i = 0
|
|
95
|
+
const errs = [];
|
|
96
|
+
let i = 0;
|
|
97
97
|
for (const el of els) {
|
|
98
98
|
try {
|
|
99
|
-
await fn(el, i)
|
|
99
|
+
await fn(el, i);
|
|
100
100
|
} catch (err) {
|
|
101
|
-
output.error(`eachElement: failed operation on element #${i} ${el}`)
|
|
102
|
-
errs.push(err)
|
|
101
|
+
output.output.error(`eachElement: failed operation on element #${i} ${el}`);
|
|
102
|
+
errs.push(err);
|
|
103
103
|
}
|
|
104
|
-
i
|
|
104
|
+
i++;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
if (errs.length) {
|
|
108
|
-
event.dispatcher.emit(event.step.after, step)
|
|
109
|
-
event.emit(event.step.failed, step, errs[0])
|
|
110
|
-
event.emit(event.step.finished, step)
|
|
111
|
-
throw errs[0]
|
|
108
|
+
event.dispatcher.emit(event.step.after, step);
|
|
109
|
+
event.emit(event.step.failed, step, errs[0]);
|
|
110
|
+
event.emit(event.step.finished, step);
|
|
111
|
+
throw errs[0];
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
event.dispatcher.emit(event.step.after, step)
|
|
115
|
-
event.emit(event.step.passed, step, null)
|
|
116
|
-
event.emit(event.step.finished, step)
|
|
117
|
-
})
|
|
114
|
+
event.dispatcher.emit(event.step.after, step);
|
|
115
|
+
event.emit(event.step.passed, step, null);
|
|
116
|
+
event.emit(event.step.finished, step);
|
|
117
|
+
});
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
config = Object.assign(defaultConfig, config)
|
|
120
|
+
export default function (config) {
|
|
121
|
+
config = Object.assign(defaultConfig, config);
|
|
122
122
|
|
|
123
123
|
if (config.registerGlobal) {
|
|
124
|
-
global.eachElement = eachElement
|
|
124
|
+
global.eachElement = eachElement;
|
|
125
125
|
}
|
|
126
|
-
return eachElement
|
|
126
|
+
return eachElement;
|
|
127
127
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import transform from '../transform';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Use the `@faker-js/faker` package to generate fake data inside examples on your gherkin tests
|
|
@@ -39,11 +39,11 @@ const transform = require('../transform')
|
|
|
39
39
|
* ```
|
|
40
40
|
*
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
export default function (config) {
|
|
43
43
|
transform.addTransformerBeforeAll('gherkin.examples', (value) => {
|
|
44
44
|
if (typeof value === 'string' && value.length > 0) {
|
|
45
|
-
return faker.helpers.fake(value)
|
|
45
|
+
return faker.helpers.fake(value);
|
|
46
46
|
}
|
|
47
|
-
return value
|
|
48
|
-
})
|
|
47
|
+
return value;
|
|
48
|
+
});
|
|
49
49
|
}
|