codeceptjs 3.5.15 → 3.6.0-beta.1.ai-healers
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 +2 -2
- package/bin/codecept.js +66 -30
- package/docs/advanced.md +351 -0
- package/docs/ai.md +365 -0
- package/docs/api.md +323 -0
- package/docs/basics.md +979 -0
- package/docs/bdd.md +539 -0
- package/docs/best.md +237 -0
- package/docs/books.md +37 -0
- package/docs/bootstrap.md +135 -0
- package/docs/build/AI.js +124 -0
- package/docs/build/ApiDataFactory.js +410 -0
- package/docs/build/Appium.js +2027 -0
- package/docs/build/Expect.js +422 -0
- package/docs/build/FileSystem.js +228 -0
- package/docs/build/GraphQL.js +229 -0
- package/docs/build/GraphQLDataFactory.js +309 -0
- package/docs/build/JSONResponse.js +338 -0
- package/docs/build/Mochawesome.js +71 -0
- package/docs/build/Nightmare.js +2152 -0
- package/docs/build/Playwright.js +5110 -0
- package/docs/build/Protractor.js +2706 -0
- package/docs/build/Puppeteer.js +3905 -0
- package/docs/build/REST.js +344 -0
- package/docs/build/TestCafe.js +2125 -0
- package/docs/build/WebDriver.js +4240 -0
- package/docs/changelog.md +2572 -0
- package/docs/commands.md +266 -0
- package/docs/community-helpers.md +58 -0
- package/docs/configuration.md +157 -0
- package/docs/continuous-integration.md +22 -0
- package/docs/custom-helpers.md +306 -0
- package/docs/data.md +379 -0
- package/docs/detox.md +235 -0
- package/docs/docker.md +136 -0
- package/docs/email.md +183 -0
- package/docs/examples.md +149 -0
- package/docs/heal.md +186 -0
- package/docs/helpers/ApiDataFactory.md +266 -0
- package/docs/helpers/Appium.md +1374 -0
- package/docs/helpers/Detox.md +586 -0
- package/docs/helpers/Expect.md +275 -0
- package/docs/helpers/FileSystem.md +152 -0
- package/docs/helpers/GraphQL.md +151 -0
- package/docs/helpers/GraphQLDataFactory.md +226 -0
- package/docs/helpers/JSONResponse.md +254 -0
- package/docs/helpers/Mochawesome.md +8 -0
- package/docs/helpers/MockRequest.md +377 -0
- package/docs/helpers/Nightmare.md +1305 -0
- package/docs/helpers/OpenAI.md +70 -0
- package/docs/helpers/Playwright.md +2759 -0
- package/docs/helpers/Polly.md +44 -0
- package/docs/helpers/Protractor.md +1769 -0
- package/docs/helpers/Puppeteer-firefox.md +86 -0
- package/docs/helpers/Puppeteer.md +2317 -0
- package/docs/helpers/REST.md +218 -0
- package/docs/helpers/TestCafe.md +1321 -0
- package/docs/helpers/WebDriver.md +2547 -0
- package/docs/hooks.md +340 -0
- package/docs/index.md +111 -0
- package/docs/installation.md +75 -0
- package/docs/internal-api.md +266 -0
- package/docs/locators.md +339 -0
- package/docs/mobile-react-native-locators.md +67 -0
- package/docs/mobile.md +338 -0
- package/docs/pageobjects.md +291 -0
- package/docs/parallel.md +400 -0
- package/docs/playwright.md +632 -0
- package/docs/plugins.md +1247 -0
- package/docs/puppeteer.md +316 -0
- package/docs/quickstart.md +162 -0
- package/docs/react.md +70 -0
- package/docs/reports.md +392 -0
- package/docs/secrets.md +36 -0
- package/docs/shadow.md +68 -0
- package/docs/shared/keys.mustache +31 -0
- package/docs/shared/react.mustache +1 -0
- package/docs/testcafe.md +174 -0
- package/docs/translation.md +247 -0
- package/docs/tutorial.md +271 -0
- package/docs/typescript.md +180 -0
- package/docs/ui.md +59 -0
- package/docs/videos.md +28 -0
- package/docs/visual.md +202 -0
- package/docs/vue.md +143 -0
- package/docs/webdriver.md +701 -0
- package/docs/wiki/Books-&-Posts.md +27 -0
- package/docs/wiki/Community-Helpers-&-Plugins.md +53 -0
- package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +61 -0
- package/docs/wiki/Examples.md +145 -0
- package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +68 -0
- package/docs/wiki/Home.md +16 -0
- package/docs/wiki/Migration-to-Appium-v2---CodeceptJS.md +83 -0
- package/docs/wiki/Release-Process.md +24 -0
- package/docs/wiki/Roadmap.md +23 -0
- package/docs/wiki/Tests.md +1393 -0
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +153 -0
- package/docs/wiki/Videos.md +19 -0
- package/lib/actor.js +3 -6
- package/lib/ai.js +152 -80
- package/lib/cli.js +1 -0
- package/lib/command/dryRun.js +13 -44
- package/lib/command/generate.js +34 -0
- package/lib/command/run-workers.js +3 -0
- package/lib/command/run.js +3 -0
- package/lib/container.js +2 -0
- package/lib/heal.js +172 -0
- package/lib/helper/AI.js +124 -0
- package/lib/helper/Appium.js +12 -36
- package/lib/helper/Expect.js +8 -11
- package/lib/helper/JSONResponse.js +8 -8
- package/lib/helper/Playwright.js +240 -100
- package/lib/helper/Puppeteer.js +68 -182
- package/lib/helper/REST.js +1 -4
- package/lib/helper/WebDriver.js +10 -324
- package/lib/index.js +3 -0
- package/lib/listener/steps.js +0 -2
- package/lib/locator.js +4 -13
- package/lib/plugin/coverage.js +99 -112
- package/lib/plugin/heal.js +26 -117
- package/lib/recorder.js +11 -5
- package/lib/step.js +1 -3
- package/lib/store.js +2 -0
- package/lib/template/heal.js +39 -0
- package/package.json +35 -47
- package/typings/index.d.ts +0 -17
- package/typings/promiseBasedTypes.d.ts +57 -340
- package/typings/types.d.ts +73 -433
- package/docs/webapi/dontSeeTraffic.mustache +0 -13
- package/docs/webapi/flushNetworkTraffics.mustache +0 -5
- package/docs/webapi/grabRecordedNetworkTraffics.mustache +0 -10
- package/docs/webapi/seeTraffic.mustache +0 -36
- package/docs/webapi/startRecordingTraffic.mustache +0 -8
- package/docs/webapi/stopRecordingTraffic.mustache +0 -5
- package/docs/webapi/waitForCookie.mustache +0 -9
- package/lib/helper/MockServer.js +0 -221
- package/lib/helper/errors/ElementAssertion.js +0 -38
- package/lib/helper/networkTraffics/utils.js +0 -137
- /package/{lib/helper → docs/build}/OpenAI.js +0 -0
package/README.md
CHANGED
|
@@ -313,10 +313,10 @@ Thanks all to those who are and will have contributing to this awesome project!
|
|
|
313
313
|
<a href="https://github.com/tsuemura"><img src="https://avatars.githubusercontent.com/u/17092259?v=4" title="tsuemura" width="80" height="80"></a>
|
|
314
314
|
<a href="https://github.com/EgorBodnar"><img src="https://avatars.githubusercontent.com/u/63167966?v=4" title="EgorBodnar" width="80" height="80"></a>
|
|
315
315
|
<a href="https://github.com/VikalpP"><img src="https://avatars.githubusercontent.com/u/11846339?v=4" title="VikalpP" width="80" height="80"></a>
|
|
316
|
-
<a href="https://github.com/elaichenkov"><img src="https://avatars.githubusercontent.com/u/29764053?v=4" title="elaichenkov" width="80" height="80"></a>
|
|
317
316
|
<a href="https://github.com/BorisOsipov"><img src="https://avatars.githubusercontent.com/u/6514276?v=4" title="BorisOsipov" width="80" height="80"></a>
|
|
318
|
-
<a href="https://github.com/
|
|
317
|
+
<a href="https://github.com/elaichenkov"><img src="https://avatars.githubusercontent.com/u/29764053?v=4" title="elaichenkov" width="80" height="80"></a>
|
|
319
318
|
<a href="https://github.com/nitschSB"><img src="https://avatars.githubusercontent.com/u/39341455?v=4" title="nitschSB" width="80" height="80"></a>
|
|
319
|
+
<a href="https://github.com/hubidu"><img src="https://avatars.githubusercontent.com/u/13134082?v=4" title="hubidu" width="80" height="80"></a>
|
|
320
320
|
<a href="https://github.com/jploskonka"><img src="https://avatars.githubusercontent.com/u/669483?v=4" title="jploskonka" width="80" height="80"></a>
|
|
321
321
|
<a href="https://github.com/ngraf"><img src="https://avatars.githubusercontent.com/u/7094389?v=4" title="ngraf" width="80" height="80"></a>
|
|
322
322
|
<a href="https://github.com/maojunxyz"><img src="https://avatars.githubusercontent.com/u/28778042?v=4" title="maojunxyz" width="80" height="80"></a>
|
package/bin/codecept.js
CHANGED
|
@@ -4,6 +4,33 @@ const Codecept = require('../lib/codecept');
|
|
|
4
4
|
const { print, error } = require('../lib/output');
|
|
5
5
|
const { printError } = require('../lib/command/utils');
|
|
6
6
|
|
|
7
|
+
const commandFlags = {
|
|
8
|
+
ai: {
|
|
9
|
+
flag: '--ai',
|
|
10
|
+
description: 'enable AI assistant',
|
|
11
|
+
},
|
|
12
|
+
verbose: {
|
|
13
|
+
flag: '--verbose',
|
|
14
|
+
description: 'output internal logging information',
|
|
15
|
+
},
|
|
16
|
+
debug: {
|
|
17
|
+
flag: '--debug',
|
|
18
|
+
description: 'output additional information',
|
|
19
|
+
},
|
|
20
|
+
config: {
|
|
21
|
+
flag: '-c, --config [file]',
|
|
22
|
+
description: 'configuration file to be used',
|
|
23
|
+
},
|
|
24
|
+
profile: {
|
|
25
|
+
flag: '--profile [value]',
|
|
26
|
+
description: 'configuration profile to be used',
|
|
27
|
+
},
|
|
28
|
+
steps: {
|
|
29
|
+
flag: '--steps',
|
|
30
|
+
description: 'show step-by-step execution',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
7
34
|
const errorHandler = (fn) => async (...args) => {
|
|
8
35
|
try {
|
|
9
36
|
await fn(...args);
|
|
@@ -35,9 +62,10 @@ program.command('migrate [path]')
|
|
|
35
62
|
program.command('shell [path]')
|
|
36
63
|
.alias('sh')
|
|
37
64
|
.description('Interactive shell')
|
|
38
|
-
.option(
|
|
39
|
-
.option(
|
|
40
|
-
.option(
|
|
65
|
+
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
66
|
+
.option(commandFlags.profile.flag, commandFlags.profile.description)
|
|
67
|
+
.option(commandFlags.ai.flag, commandFlags.ai.description)
|
|
68
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
41
69
|
.action(errorHandler(require('../lib/command/interactive')));
|
|
42
70
|
|
|
43
71
|
program.command('list [path]')
|
|
@@ -47,27 +75,27 @@ program.command('list [path]')
|
|
|
47
75
|
|
|
48
76
|
program.command('def [path]')
|
|
49
77
|
.description('Generates TypeScript definitions for all I actions.')
|
|
50
|
-
.option(
|
|
78
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
51
79
|
.option('-o, --output [folder]', 'target folder to paste definitions')
|
|
52
80
|
.action(errorHandler(require('../lib/command/definitions')));
|
|
53
81
|
|
|
54
82
|
program.command('gherkin:init [path]')
|
|
55
83
|
.alias('bdd:init')
|
|
56
84
|
.description('Prepare CodeceptJS to run feature files.')
|
|
57
|
-
.option(
|
|
85
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
58
86
|
.action(errorHandler(require('../lib/command/gherkin/init')));
|
|
59
87
|
|
|
60
88
|
program.command('gherkin:steps [path]')
|
|
61
89
|
.alias('bdd:steps')
|
|
62
90
|
.description('Prints all defined gherkin steps.')
|
|
63
|
-
.option(
|
|
91
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
64
92
|
.action(errorHandler(require('../lib/command/gherkin/steps')));
|
|
65
93
|
|
|
66
94
|
program.command('gherkin:snippets [path]')
|
|
67
95
|
.alias('bdd:snippets')
|
|
68
96
|
.description('Generate step definitions from steps.')
|
|
69
97
|
.option('--dry-run', "don't save snippets to file")
|
|
70
|
-
.option(
|
|
98
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
71
99
|
.option('--feature [file]', 'feature files(s) to scan')
|
|
72
100
|
.option('--path [file]', 'file in which to place the new snippets')
|
|
73
101
|
.action(errorHandler(require('../lib/command/gherkin/snippets')));
|
|
@@ -93,16 +121,22 @@ program.command('generate:helper [path]')
|
|
|
93
121
|
.description('Generates a new helper')
|
|
94
122
|
.action(errorHandler(require('../lib/command/generate').helper));
|
|
95
123
|
|
|
124
|
+
program.command('generate:heal [path]')
|
|
125
|
+
.alias('gr')
|
|
126
|
+
.description('Generates basic heal recipes')
|
|
127
|
+
.action(errorHandler(require('../lib/command/generate').heal));
|
|
128
|
+
|
|
96
129
|
program.command('run [test]')
|
|
97
130
|
.description('Executes tests')
|
|
98
131
|
|
|
99
132
|
// codecept-only options
|
|
100
|
-
.option(
|
|
101
|
-
.option(
|
|
102
|
-
.option(
|
|
133
|
+
.option(commandFlags.ai.flag, commandFlags.ai.description)
|
|
134
|
+
.option(commandFlags.steps.flag, commandFlags.steps.description)
|
|
135
|
+
.option(commandFlags.debug.flag, commandFlags.debug.description)
|
|
136
|
+
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
103
137
|
.option('-o, --override [value]', 'override current config options')
|
|
104
|
-
.option(
|
|
105
|
-
.option(
|
|
138
|
+
.option(commandFlags.profile.flag, commandFlags.profile.description)
|
|
139
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
106
140
|
.option('--features', 'run only *.feature files and skip tests')
|
|
107
141
|
.option('--tests', 'run only JS test files and skip features')
|
|
108
142
|
.option('--no-timeouts', 'disable all timeouts')
|
|
@@ -132,16 +166,17 @@ program.command('run [test]')
|
|
|
132
166
|
|
|
133
167
|
program.command('run-workers <workers> [selectedRuns...]')
|
|
134
168
|
.description('Executes tests in workers')
|
|
135
|
-
.option(
|
|
169
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
136
170
|
.option('-g, --grep <pattern>', 'only run tests matching <pattern>')
|
|
137
171
|
.option('-i, --invert', 'inverts --grep matches')
|
|
138
172
|
.option('-o, --override [value]', 'override current config options')
|
|
139
173
|
.option('--suites', 'parallel execution of suites not single tests')
|
|
140
|
-
.option(
|
|
141
|
-
.option(
|
|
174
|
+
.option(commandFlags.debug.flag, commandFlags.debug.description)
|
|
175
|
+
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
142
176
|
.option('--features', 'run only *.feature files and skip tests')
|
|
143
177
|
.option('--tests', 'run only JS test files and skip features')
|
|
144
|
-
.option(
|
|
178
|
+
.option(commandFlags.profile.flag, commandFlags.profile.description)
|
|
179
|
+
.option(commandFlags.ai.flag, commandFlags.ai.description)
|
|
145
180
|
.option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
|
|
146
181
|
.option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
|
|
147
182
|
.option('-R, --reporter <name>', 'specify the reporter to use')
|
|
@@ -149,17 +184,18 @@ program.command('run-workers <workers> [selectedRuns...]')
|
|
|
149
184
|
|
|
150
185
|
program.command('run-multiple [suites...]')
|
|
151
186
|
.description('Executes tests multiple')
|
|
152
|
-
.option(
|
|
153
|
-
.option(
|
|
187
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
188
|
+
.option(commandFlags.profile.flag, commandFlags.profile.description)
|
|
154
189
|
.option('--all', 'run all suites')
|
|
155
190
|
.option('--features', 'run only *.feature files and skip tests')
|
|
156
191
|
.option('--tests', 'run only JS test files and skip features')
|
|
192
|
+
.option(commandFlags.ai.flag, commandFlags.ai.description)
|
|
157
193
|
.option('-g, --grep <pattern>', 'only run tests matching <pattern>')
|
|
158
194
|
.option('-f, --fgrep <string>', 'only run tests containing <string>')
|
|
159
195
|
.option('-i, --invert', 'inverts --grep and --fgrep matches')
|
|
160
|
-
.option(
|
|
161
|
-
.option(
|
|
162
|
-
.option(
|
|
196
|
+
.option(commandFlags.steps.flag, commandFlags.steps.description)
|
|
197
|
+
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
198
|
+
.option(commandFlags.debug.flag, commandFlags.debug.description)
|
|
163
199
|
.option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
|
|
164
200
|
.option('-o, --override [value]', 'override current config options')
|
|
165
201
|
.option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
|
|
@@ -180,28 +216,28 @@ program.command('dry-run [test]')
|
|
|
180
216
|
.description('Prints step-by-step scenario for a test without actually running it')
|
|
181
217
|
.option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
|
|
182
218
|
.option('--bootstrap', 'enable bootstrap & teardown scripts for dry-run')
|
|
183
|
-
.option(
|
|
219
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
184
220
|
.option('--all', 'run all suites')
|
|
185
221
|
.option('--features', 'run only *.feature files and skip tests')
|
|
186
222
|
.option('--tests', 'run only JS test files and skip features')
|
|
187
223
|
.option('-g, --grep <pattern>', 'only run tests matching <pattern>')
|
|
188
224
|
.option('-f, --fgrep <string>', 'only run tests containing <string>')
|
|
189
225
|
.option('-i, --invert', 'inverts --grep and --fgrep matches')
|
|
190
|
-
.option(
|
|
191
|
-
.option(
|
|
192
|
-
.option(
|
|
226
|
+
.option(commandFlags.steps.flag, commandFlags.steps.description)
|
|
227
|
+
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
228
|
+
.option(commandFlags.debug.flag, commandFlags.debug.description)
|
|
193
229
|
.action(errorHandler(require('../lib/command/dryRun')));
|
|
194
230
|
|
|
195
231
|
program.command('run-rerun [test]')
|
|
196
232
|
.description('Executes tests in more than one test suite run')
|
|
197
233
|
|
|
198
234
|
// codecept-only options
|
|
199
|
-
.option(
|
|
200
|
-
.option(
|
|
201
|
-
.option(
|
|
235
|
+
.option(commandFlags.steps.flag, commandFlags.steps.description)
|
|
236
|
+
.option(commandFlags.debug.flag, commandFlags.debug.description)
|
|
237
|
+
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
202
238
|
.option('-o, --override [value]', 'override current config options')
|
|
203
|
-
.option(
|
|
204
|
-
.option(
|
|
239
|
+
.option(commandFlags.profile.flag, commandFlags.profile.description)
|
|
240
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
205
241
|
.option('--features', 'run only *.feature files and skip tests')
|
|
206
242
|
.option('--tests', 'run only JS test files and skip features')
|
|
207
243
|
.option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
|
package/docs/advanced.md
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /advanced
|
|
3
|
+
title: Advanced Usage
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Advanced Usage
|
|
7
|
+
|
|
8
|
+
## Data Driven Tests
|
|
9
|
+
|
|
10
|
+
Execute the same scenario on a different data set.
|
|
11
|
+
|
|
12
|
+
Let's say you want to test login for different user accounts.
|
|
13
|
+
In this case, you need to create a datatable and fill it in with credentials.
|
|
14
|
+
Then use `Data().Scenario` to include this data and generate multiple scenarios:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
// Define data table inside a test or load from another module
|
|
18
|
+
let accounts = new DataTable(['login', 'password']); //
|
|
19
|
+
accounts.add(['davert', '123456']); // adding records to a table
|
|
20
|
+
accounts.add(['admin', '123456']);
|
|
21
|
+
|
|
22
|
+
// You can skip some data. But add them to report as skipped (just like with usual scenarios):
|
|
23
|
+
accounts.xadd(['admin', '23456'])
|
|
24
|
+
|
|
25
|
+
// Pass dataTable to Data()
|
|
26
|
+
// Use special param `current` to get current data set
|
|
27
|
+
Data(accounts).Scenario('Test Login', ({ I, current }) => {
|
|
28
|
+
I.fillField('Username', current.login); // current is reserved!
|
|
29
|
+
I.fillField('Password', current.password);
|
|
30
|
+
I.click('Sign In');
|
|
31
|
+
I.see('Welcome '+ current.login);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// Also you can set only for Data tests. It will launch executes only the current test but with all data options
|
|
36
|
+
Data(accounts).only.Scenario('Test Login', ({ I, current }) => {
|
|
37
|
+
I.fillField('Username', current.login); // current is reserved!
|
|
38
|
+
I.fillField('Password', current.password);
|
|
39
|
+
I.click('Sign In');
|
|
40
|
+
I.see('Welcome '+ current.login);
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
*Important: you can't use name `current` for pageObjects or helpers in data scenarios*
|
|
45
|
+
|
|
46
|
+
This will produce 2 tests with different data sets.
|
|
47
|
+
Current data set is appended to a test name in output:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
✓ Test Login | {"login":"davert","password":"123456"}
|
|
51
|
+
✓ Test Login | {"login":"admin","password":"123456"}
|
|
52
|
+
S Test Login | {"login":"admin","password":"23456"}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
// You can filter your data table
|
|
57
|
+
Data(accounts.filter(account => account.login == 'admin')
|
|
58
|
+
.Scenario('Test Login', ({ I, current }) => {
|
|
59
|
+
I.fillField('Username', current.login);
|
|
60
|
+
I.fillField('Password', current.password);
|
|
61
|
+
I.click('Sign In');
|
|
62
|
+
I.see('Welcome '+ current.login);
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This will limit data sets accoring passed function:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
✓ Test Login | {"login":"admin","password":"123456"}
|
|
70
|
+
S Test Login | {"login":"admin","password":"23456"}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Data sets can also be defined with array, generator, or a function.
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
Data(function*() {
|
|
77
|
+
yield { user: 'davert'};
|
|
78
|
+
yield { user: 'andrey'};
|
|
79
|
+
}).Scenario() // ...
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
*HINT: If you don't use DataTable. add `toString()` method to each object added to data set, so the data could be pretty printed in a test name*
|
|
83
|
+
|
|
84
|
+
## Tags
|
|
85
|
+
|
|
86
|
+
Append `@tag` to your test name, so
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
Scenario('update user profile @slow')
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Alternativly, use `tag` method of Scenario to set additional tags:
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
Scenario('update user profile', ({ }) => {
|
|
96
|
+
// test goes here
|
|
97
|
+
}).tag('@slow').tag('important');
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
All tests with `@tag` could be executed with `--grep '@tag'` option.
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
codeceptjs run --grep '@slow'
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Use regex for more flexible filtering:
|
|
107
|
+
|
|
108
|
+
* `--grep '(?=.*@smoke2)(?=.*@smoke3)'` - run tests with @smoke2 and @smoke3 in name
|
|
109
|
+
* `--grep "\@smoke2|\@smoke3"` - run tests with @smoke2 or @smoke3 in name
|
|
110
|
+
* `--grep '((?=.*@smoke2)(?=.*@smoke3))|@smoke4'` - run tests with (@smoke2 and @smoke3) or @smoke4 in name
|
|
111
|
+
* `--grep '(?=.*@smoke2)^(?!.*@smoke3)'` - run tests with @smoke2 but without @smoke3 in name
|
|
112
|
+
* `--grep '(?=.*)^(?!.*@smoke4)'` - run all tests except @smoke4
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## Debug
|
|
117
|
+
|
|
118
|
+
CodeceptJS provides a debug mode in which additional information is printed.
|
|
119
|
+
It can be turned on with `--debug` flag.
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
npx codeceptjs run --debug
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
to receive even more information turn on `--verbose` flag:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
npx codeceptjs run --verbose
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
> You can pause execution and enter **interactive console** mode by calling `pause()` inside your test.
|
|
132
|
+
|
|
133
|
+
To see a complete internal debug of CodeceptJS use `DEBUG` env variable:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
DEBUG=codeceptjs:* npx codeceptjs run
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
For an interactive debugging use NodeJS debugger. In **WebStorm**:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
node $NODE_DEBUG_OPTION ./node_modules/.bin/codeceptjs run
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
For **Visual Studio Code**, add the following configuration in launch.json:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"type": "node",
|
|
150
|
+
"request": "launch",
|
|
151
|
+
"name": "codeceptjs",
|
|
152
|
+
"args": ["run", "--grep", "@your_test_tag"],
|
|
153
|
+
"program": "${workspaceFolder}/node_modules/codeceptjs/bin/codecept.js"
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
## Test Options
|
|
159
|
+
|
|
160
|
+
Features and Scenarios have their options that can be set by passing a hash after their names:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
Feature('My feature', {key: val});
|
|
164
|
+
|
|
165
|
+
Scenario('My scenario', {key: val},({ I }) => {});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
You can use this options for build your own [plugins](https://codecept.io/hooks/#plugins) with [event listners](https://codecept.io/hooks/#api). Example:
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
// for test
|
|
172
|
+
event.dispatcher.on(event.test.before, (test) => {
|
|
173
|
+
...
|
|
174
|
+
if (test.opts.key) {
|
|
175
|
+
...
|
|
176
|
+
}
|
|
177
|
+
...
|
|
178
|
+
});
|
|
179
|
+
// or for suite
|
|
180
|
+
event.dispatcher.on(event.suite.before, (suite) => {
|
|
181
|
+
...
|
|
182
|
+
if (suite.opts.key) {
|
|
183
|
+
...
|
|
184
|
+
}
|
|
185
|
+
...
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Timeout
|
|
190
|
+
|
|
191
|
+
Tests can get stuck due to various reasons such as network connection issues, crashed browser, etc.
|
|
192
|
+
This can make tests process hang. To prevent these situations timeouts can be used. Timeouts can be set explicitly for flaky parts of code, or implicitly in a config.
|
|
193
|
+
|
|
194
|
+
> Previous timeout implementation was disabled as it had no effect when dealing with steps and promises.
|
|
195
|
+
|
|
196
|
+
### Steps Timeout
|
|
197
|
+
|
|
198
|
+
It is possible to limit a step execution to specified time with `I.limitTime` command.
|
|
199
|
+
It will set timeout in seconds for the next executed step:
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
// limit clicking to 5 seconds
|
|
203
|
+
I.limitTime(5).click('Link')
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
It is possible to set a timeout for all steps implicitly (except waiters) using [stepTimeout plugin](/plugins/#steptimeout).
|
|
207
|
+
|
|
208
|
+
### Tests Timeout
|
|
209
|
+
|
|
210
|
+
Test timeout can be set in seconds via Scenario options:
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
// limit test to 20 seconds
|
|
214
|
+
Scenario('slow test that should be stopped', { timeout: 20 }, ({ I }) => {
|
|
215
|
+
// ...
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
This timeout can be set globally in `codecept.conf.js` in seconds:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
exports.config = {
|
|
223
|
+
|
|
224
|
+
// each test must not run longer than 5 mins
|
|
225
|
+
timeout: 300,
|
|
226
|
+
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Suites Timeout
|
|
231
|
+
|
|
232
|
+
A timeout for a group of tests can be set on Feature level via options.
|
|
233
|
+
|
|
234
|
+
```js
|
|
235
|
+
// limit all tests in this suite to 30 seconds
|
|
236
|
+
Feature('flaky tests', { timeout: 30 })
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Timeout Confguration
|
|
240
|
+
|
|
241
|
+
<Badge text="Updated in 3.4" type="warning"/>
|
|
242
|
+
|
|
243
|
+
Timeout rules can be set globally via config.
|
|
244
|
+
|
|
245
|
+
To set a timeout for all running tests provide a **number of seconds** to `timeout` config option:
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
```js
|
|
249
|
+
// inside codecept.conf.js or codecept.conf.ts
|
|
250
|
+
timeout: 30, // limit all tests in all suites to 30 secs
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
It is possible to tune this configuration for a different groups of tests passing options as array and using `grep` option to filter tests:
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
// inside codecept.conf.js or codecept.conf.ts
|
|
257
|
+
|
|
258
|
+
timeout: [
|
|
259
|
+
10, // default timeout is 10secs
|
|
260
|
+
|
|
261
|
+
// but increase timeout for slow tests
|
|
262
|
+
{
|
|
263
|
+
grep: '@slow',
|
|
264
|
+
Feature: 50
|
|
265
|
+
},
|
|
266
|
+
]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
> ℹ️ `grep` value can be string or regexp
|
|
270
|
+
|
|
271
|
+
It is possible to set a timeout for Scenario or Feature:
|
|
272
|
+
|
|
273
|
+
```js
|
|
274
|
+
// inside codecept.conf.js or codecept.conf.ts
|
|
275
|
+
timeout: [
|
|
276
|
+
|
|
277
|
+
// timeout for Feature with @slow in title
|
|
278
|
+
{
|
|
279
|
+
grep: '@slow',
|
|
280
|
+
Feature: 50
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
// timeout for Scenario with 'flaky0' .. `flaky1` in title
|
|
284
|
+
{
|
|
285
|
+
// regexp can be passed to grep
|
|
286
|
+
grep: /flaky[0-9]/,
|
|
287
|
+
Scenario: 10
|
|
288
|
+
},
|
|
289
|
+
|
|
290
|
+
// timeout for all suites
|
|
291
|
+
{
|
|
292
|
+
Feature: 20
|
|
293
|
+
}
|
|
294
|
+
]
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Global timeouts will be overridden by explicit timeouts of a test or steps.
|
|
298
|
+
|
|
299
|
+
### Disable Timeouts
|
|
300
|
+
|
|
301
|
+
To execute tests ignoring all timeout settings use `--no-timeouts` option:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
npx codeceptjs run --no-timeouts
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Dynamic Configuration
|
|
308
|
+
|
|
309
|
+
Helpers can be reconfigured per scenario or per feature.
|
|
310
|
+
This might be useful when some tests should be executed with different settings than others.
|
|
311
|
+
In order to reconfigure tests use `.config()` method of `Scenario` or `Feature`.
|
|
312
|
+
|
|
313
|
+
```js
|
|
314
|
+
Scenario('should be executed in firefox', ({ I }) => {
|
|
315
|
+
// I.amOnPage(..)
|
|
316
|
+
}).config({ browser: 'firefox' })
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
In this case `config` overrides current config of the first helper.
|
|
320
|
+
To change config of specific helper pass two arguments: helper name and config values:
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
Scenario('should create data via v2 version of API', ({ I }) => {
|
|
324
|
+
// I.amOnPage(..)
|
|
325
|
+
}).config('REST', { endpoint: 'https://api.mysite.com/v2' })
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Config can also be set by a function, in this case you can get a test object and specify config values based on it.
|
|
329
|
+
This is very useful when running tests against cloud providers, like BrowserStack. This function can also be asynchronous.
|
|
330
|
+
|
|
331
|
+
```js
|
|
332
|
+
Scenario('should report to BrowserStack', ({ I }) => {
|
|
333
|
+
// I.amOnPage(..)
|
|
334
|
+
}).config((test) => {
|
|
335
|
+
return { desiredCapabilities: {
|
|
336
|
+
project: test.suite.title,
|
|
337
|
+
name: test.title,
|
|
338
|
+
}}
|
|
339
|
+
});
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Config changes can be applied to all tests in suite:
|
|
343
|
+
|
|
344
|
+
```js
|
|
345
|
+
Feature('Admin Panel').config({ url: 'https://mysite.com/admin' });
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Please note that some config changes can't be applied on the fly. For instance, if you set `restart: false` in your config and then changing value `browser` won't take an effect as browser is already started and won't be closed untill all tests finish.
|
|
349
|
+
|
|
350
|
+
Configuration changes will be reverted after a test or a suite.
|
|
351
|
+
|