codeceptjs 4.0.0-beta.4 → 4.0.0-beta.6.esm-aria
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 +89 -119
- package/bin/codecept.js +53 -54
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +70 -102
- package/lib/ai.js +131 -121
- package/lib/assert/empty.js +11 -12
- package/lib/assert/equal.js +16 -21
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +11 -15
- package/lib/assert/throws.js +3 -5
- package/lib/assert/truth.js +10 -7
- package/lib/assert.js +18 -18
- package/lib/codecept.js +112 -101
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +13 -14
- package/lib/command/definitions.js +24 -36
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +38 -39
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +49 -15
- package/lib/command/init.js +41 -37
- package/lib/command/interactive.js +22 -13
- package/lib/command/list.js +11 -10
- package/lib/command/run-multiple/chunk.js +50 -47
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +27 -47
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +15 -66
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +22 -21
- package/lib/command/workers/runTests.js +131 -241
- package/lib/config.js +111 -49
- package/lib/container.js +589 -244
- package/lib/data/context.js +16 -18
- package/lib/data/dataScenarioConfig.js +9 -9
- package/lib/data/dataTableArgument.js +7 -7
- package/lib/data/table.js +6 -12
- package/lib/effects.js +307 -0
- package/lib/els.js +160 -0
- package/lib/event.js +24 -19
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -81
- package/lib/helper/AI.js +3 -2
- package/lib/helper/ApiDataFactory.js +19 -19
- package/lib/helper/Appium.js +47 -51
- package/lib/helper/FileSystem.js +35 -15
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +4 -4
- package/lib/helper/JSONResponse.js +72 -45
- package/lib/helper/Mochawesome.js +14 -11
- package/lib/helper/Playwright.js +832 -434
- package/lib/helper/Puppeteer.js +393 -292
- package/lib/helper/REST.js +32 -27
- package/lib/helper/WebDriver.js +320 -219
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +33 -48
- package/lib/helper/network/utils.js +76 -83
- package/lib/helper/scripts/blurElement.js +6 -6
- package/lib/helper/scripts/focusElement.js +6 -6
- package/lib/helper/scripts/highlightElement.js +9 -9
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -1
- package/lib/history.js +23 -20
- package/lib/hooks.js +10 -10
- package/lib/html.js +90 -100
- package/lib/index.js +48 -21
- package/lib/listener/config.js +8 -9
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/exit.js +10 -12
- package/lib/listener/{retry.js → globalRetry.js} +10 -10
- package/lib/listener/globalTimeout.js +166 -0
- package/lib/listener/helpers.js +43 -24
- package/lib/listener/mocha.js +4 -5
- package/lib/listener/result.js +11 -0
- package/lib/listener/steps.js +26 -23
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +264 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +160 -0
- package/lib/{interfaces → mocha}/featureConfig.js +33 -13
- package/lib/{interfaces → mocha}/gherkin.js +75 -45
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +32 -8
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +178 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +229 -0
- package/lib/output.js +86 -64
- package/lib/parser.js +44 -44
- package/lib/pause.js +160 -139
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +137 -43
- package/lib/plugin/autoDelay.js +19 -15
- package/lib/plugin/coverage.js +22 -27
- package/lib/plugin/customLocator.js +5 -5
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/heal.js +49 -17
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +60 -19
- package/lib/plugin/screenshotOnFail.js +80 -83
- package/lib/plugin/stepByStepReport.js +70 -31
- package/lib/plugin/stepTimeout.js +7 -13
- package/lib/plugin/subtitles.js +10 -9
- package/lib/recorder.js +167 -126
- package/lib/rerun.js +94 -50
- package/lib/result.js +161 -0
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -332
- package/lib/steps.js +54 -0
- package/lib/store.js +37 -5
- package/lib/template/heal.js +2 -11
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +354 -250
- package/lib/workerStorage.js +16 -16
- package/lib/workers.js +366 -282
- package/package.json +107 -95
- package/translations/de-DE.js +5 -4
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +23 -9
- package/translations/it-IT.js +5 -4
- package/translations/ja-JP.js +5 -4
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +5 -4
- package/translations/pt-BR.js +5 -4
- package/translations/ru-RU.js +5 -4
- package/translations/utils.js +18 -0
- package/translations/zh-CN.js +5 -4
- package/translations/zh-TW.js +5 -4
- package/typings/index.d.ts +177 -186
- package/typings/promiseBasedTypes.d.ts +3573 -5941
- package/typings/types.d.ts +4042 -6370
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/Nightmare.js +0 -1504
- package/lib/helper/Protractor.js +0 -1863
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1414
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -62
- package/lib/interfaces/bdd.js +0 -81
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -113
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -127
- package/lib/plugin/selenoid.js +0 -384
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/plugin/tryTo.js +0 -115
- package/lib/plugin/wdio.js +0 -249
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
- package/lib/within.js +0 -70
package/README.md
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
[](https://stand-with-ukraine.pp.ua)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
3
|
[<img src="https://img.shields.io/badge/slack-@codeceptjs-purple.svg?logo=slack">](https://join.slack.com/t/codeceptjs/shared_invite/enQtMzA5OTM4NDM2MzA4LWE4MThhN2NmYTgxNTU5MTc4YzAyYWMwY2JkMmZlYWI5MWQ2MDM5MmRmYzZmYmNiNmY5NTAzM2EwMGIwOTNhOGQ) [<img src="https://img.shields.io/badge/discourse-codeceptjs-purple">](https://codecept.discourse.group) [![NPM version][npm-image]][npm-url] [<img src="https://img.shields.io/badge/dockerhub-images-blue.svg?logo=codeceptjs">](https://hub.docker.com/r/codeceptjs/codeceptjs)
|
|
6
|
-
[](https://github.com/codeceptjs/CodeceptJS/edit/3.x/docs/ai.md) [](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)
|
|
7
|
-
|
|
8
|
-
Build Status:
|
|
4
|
+
[](https://github.com/codeceptjs/CodeceptJS/edit/3.x/docs/ai.md) [](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
[](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appiumV2_Android.yml)
|
|
6
|
+
## Build Status
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
[](https://github.com/codeceptjs/CodeceptJS/actions/workflows/playwright.yml) |
|
|
11
|
+
| 🌐 Web | Puppeteer | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/puppeteer.yml) |
|
|
12
|
+
| 🌐 Web | WebDriver | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/webdriver.yml) |
|
|
13
|
+
| 🌐 Web | TestCafe | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/testcafe.yml) |
|
|
14
|
+
| 📱 Mobile | Appium | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appium_Android.yml) |
|
|
18
15
|
|
|
19
16
|
# CodeceptJS [](https://stand-with-ukraine.pp.ua)
|
|
20
17
|
|
|
@@ -27,28 +24,28 @@ It abstracts browser interaction to simple steps that are written from a user's
|
|
|
27
24
|
A simple test that verifies the "Welcome" text is present on a main page of a site will look like:
|
|
28
25
|
|
|
29
26
|
```js
|
|
30
|
-
Feature('CodeceptJS demo')
|
|
27
|
+
Feature('CodeceptJS demo')
|
|
31
28
|
|
|
32
29
|
Scenario('check Welcome page on site', ({ I }) => {
|
|
33
|
-
I.amOnPage('/')
|
|
34
|
-
I.see('Welcome')
|
|
35
|
-
})
|
|
30
|
+
I.amOnPage('/')
|
|
31
|
+
I.see('Welcome')
|
|
32
|
+
})
|
|
36
33
|
```
|
|
37
34
|
|
|
38
35
|
CodeceptJS tests are:
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
- **Synchronous**. You don't need to care about callbacks or promises or test scenarios which are linear. But, your tests should be linear.
|
|
38
|
+
- Written from **user's perspective**. Every action is a method of `I`. That makes test easy to read, write and maintain even for non-tech persons.
|
|
39
|
+
- Backend **API agnostic**. We don't know which WebDriver implementation is running this test.
|
|
43
40
|
|
|
44
41
|
CodeceptJS uses **Helper** modules to provide actions to `I` object. Currently, CodeceptJS has these helpers:
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
- [**Playwright**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Playwright.md) - is a Node library to automate the Chromium, WebKit and Firefox browsers with a single API.
|
|
44
|
+
- [**Puppeteer**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Puppeteer.md) - uses Google Chrome's Puppeteer for fast headless testing.
|
|
45
|
+
- [**WebDriver**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) - uses [webdriverio](http://webdriver.io/) to run tests via WebDriver or Devtools protocol.
|
|
46
|
+
- [**TestCafe**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/TestCafe.md) - cheap and fast cross-browser test automation.
|
|
47
|
+
- [**Appium**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Appium.md) - for **mobile testing** with Appium
|
|
48
|
+
- [**Detox**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Detox.md) - This is a wrapper on top of Detox library, aimed to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially well for React Native apps.
|
|
52
49
|
|
|
53
50
|
And more to come...
|
|
54
51
|
|
|
@@ -58,17 +55,16 @@ CodeceptJS is a successor of [Codeception](http://codeception.com), a popular fu
|
|
|
58
55
|
With CodeceptJS your scenario-driven functional and acceptance tests will be as simple and clean as they can be.
|
|
59
56
|
You don't need to worry about asynchronous nature of NodeJS or about various APIs of Playwright, Selenium, Puppeteer, TestCafe, etc. as CodeceptJS unifies them and makes them work as they are synchronous.
|
|
60
57
|
|
|
61
|
-
|
|
62
58
|
## Features
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
|
|
60
|
+
- 🪄 **AI-powered** with GPT features to assist and heal failing tests.
|
|
61
|
+
- ☕ Based on [Mocha](https://mochajs.org/) testing framework.
|
|
62
|
+
- 💼 Designed for scenario driven acceptance testing in BDD-style.
|
|
63
|
+
- 💻 Uses ES6 natively without transpiler.
|
|
64
|
+
- Also plays nice with TypeScript.
|
|
65
|
+
- </> Smart locators: use names, labels, matching text, CSS or XPath to locate elements.
|
|
66
|
+
- 🌐 Interactive debugging shell: pause test at any point and try different commands in a browser.
|
|
67
|
+
- Easily create tests, pageobjects, stepobjects with CLI generators.
|
|
72
68
|
|
|
73
69
|
## Installation
|
|
74
70
|
|
|
@@ -105,7 +101,8 @@ npx codeceptjs def .
|
|
|
105
101
|
Later you can even automagically update Type Definitions to include your own custom [helpers methods](docs/helpers.md).
|
|
106
102
|
|
|
107
103
|
Note:
|
|
108
|
-
|
|
104
|
+
|
|
105
|
+
- CodeceptJS requires Node.js version `12+` or later.
|
|
109
106
|
|
|
110
107
|
## Usage
|
|
111
108
|
|
|
@@ -116,18 +113,18 @@ Learn CodeceptJS by examples. Let's assume we have CodeceptJS installed and WebD
|
|
|
116
113
|
Let's see how we can handle basic form testing:
|
|
117
114
|
|
|
118
115
|
```js
|
|
119
|
-
Feature('CodeceptJS Demonstration')
|
|
116
|
+
Feature('CodeceptJS Demonstration')
|
|
120
117
|
|
|
121
118
|
Scenario('test some forms', ({ I }) => {
|
|
122
|
-
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
|
|
123
|
-
I.fillField('Email', 'hello@world.com')
|
|
124
|
-
I.fillField('Password', secret('123456'))
|
|
125
|
-
I.checkOption('Active')
|
|
126
|
-
I.checkOption('Male')
|
|
127
|
-
I.click('Create User')
|
|
128
|
-
I.see('User is valid')
|
|
129
|
-
I.dontSeeInCurrentUrl('/documentation')
|
|
130
|
-
})
|
|
119
|
+
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
|
|
120
|
+
I.fillField('Email', 'hello@world.com')
|
|
121
|
+
I.fillField('Password', secret('123456'))
|
|
122
|
+
I.checkOption('Active')
|
|
123
|
+
I.checkOption('Male')
|
|
124
|
+
I.click('Create User')
|
|
125
|
+
I.see('User is valid')
|
|
126
|
+
I.dontSeeInCurrentUrl('/documentation')
|
|
127
|
+
})
|
|
131
128
|
```
|
|
132
129
|
|
|
133
130
|
All actions are performed by `I` object; assertions functions start with `see` function.
|
|
@@ -172,11 +169,11 @@ The same way you can locate element by name, `CSS` or `XPath` locators in tests:
|
|
|
172
169
|
|
|
173
170
|
```js
|
|
174
171
|
// by name
|
|
175
|
-
I.fillField('user_basic[email]', 'hello@world.com')
|
|
172
|
+
I.fillField('user_basic[email]', 'hello@world.com')
|
|
176
173
|
// by CSS
|
|
177
|
-
I.fillField('#user_basic_email', 'hello@world.com')
|
|
174
|
+
I.fillField('#user_basic_email', 'hello@world.com')
|
|
178
175
|
// don't make us guess locator type, specify it
|
|
179
|
-
I.fillField({css: '#user_basic_email'}, 'hello@world.com')
|
|
176
|
+
I.fillField({ css: '#user_basic_email' }, 'hello@world.com')
|
|
180
177
|
```
|
|
181
178
|
|
|
182
179
|
Other methods like `checkOption`, and `click` work in a similar manner. They can take labels or CSS or XPath locators to find elements to interact.
|
|
@@ -187,9 +184,9 @@ Assertions start with `see` or `dontSee` prefix. In our case we are asserting th
|
|
|
187
184
|
However, we can narrow the search to particular element by providing a second parameter:
|
|
188
185
|
|
|
189
186
|
```js
|
|
190
|
-
I.see('User is valid')
|
|
187
|
+
I.see('User is valid')
|
|
191
188
|
// better to specify context:
|
|
192
|
-
I.see('User is valid', '.alert-success')
|
|
189
|
+
I.see('User is valid', '.alert-success')
|
|
193
190
|
```
|
|
194
191
|
|
|
195
192
|
In this case 'User is valid' string will be searched only inside elements located by CSS `.alert-success`.
|
|
@@ -200,13 +197,13 @@ In case you need to return a value from a webpage and use it directly in test, y
|
|
|
200
197
|
They are expected to be used inside `async/await` functions, and their results will be available in test:
|
|
201
198
|
|
|
202
199
|
```js
|
|
203
|
-
Feature('CodeceptJS Demonstration')
|
|
200
|
+
Feature('CodeceptJS Demonstration')
|
|
204
201
|
|
|
205
202
|
Scenario('test page title', async ({ I }) => {
|
|
206
|
-
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
|
|
207
|
-
const title = await I.grabTitle()
|
|
208
|
-
I.expectEqual(title, 'Example application with SimpleForm and Twitter Bootstrap')
|
|
209
|
-
})
|
|
203
|
+
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
|
|
204
|
+
const title = await I.grabTitle()
|
|
205
|
+
I.expectEqual(title, 'Example application with SimpleForm and Twitter Bootstrap') // Avaiable with Expect helper. -> https://codecept.io/helpers/Expect/
|
|
206
|
+
})
|
|
210
207
|
```
|
|
211
208
|
|
|
212
209
|
The same way you can grab text, attributes, or form values and use them in next test steps.
|
|
@@ -216,23 +213,24 @@ The same way you can grab text, attributes, or form values and use them in next
|
|
|
216
213
|
Common preparation steps like opening a web page, logging in a user, can be placed in `Before` or `Background`:
|
|
217
214
|
|
|
218
215
|
```js
|
|
219
|
-
const { I } = inject()
|
|
216
|
+
const { I } = inject()
|
|
220
217
|
|
|
221
|
-
Feature('CodeceptJS Demonstration')
|
|
218
|
+
Feature('CodeceptJS Demonstration')
|
|
222
219
|
|
|
223
|
-
Before(() => {
|
|
224
|
-
|
|
225
|
-
|
|
220
|
+
Before(() => {
|
|
221
|
+
// or Background
|
|
222
|
+
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
|
|
223
|
+
})
|
|
226
224
|
|
|
227
225
|
Scenario('test some forms', () => {
|
|
228
|
-
I.click('Create User')
|
|
229
|
-
I.see('User is valid')
|
|
230
|
-
I.dontSeeInCurrentUrl('/documentation')
|
|
231
|
-
})
|
|
226
|
+
I.click('Create User')
|
|
227
|
+
I.see('User is valid')
|
|
228
|
+
I.dontSeeInCurrentUrl('/documentation')
|
|
229
|
+
})
|
|
232
230
|
|
|
233
231
|
Scenario('test title', () => {
|
|
234
|
-
I.seeInTitle('Example application')
|
|
235
|
-
})
|
|
232
|
+
I.seeInTitle('Example application')
|
|
233
|
+
})
|
|
236
234
|
```
|
|
237
235
|
|
|
238
236
|
## PageObjects
|
|
@@ -248,83 +246,55 @@ It will create a page object file for you and add it to the config.
|
|
|
248
246
|
Let's assume we created one named `docsPage`:
|
|
249
247
|
|
|
250
248
|
```js
|
|
251
|
-
const { I } = inject()
|
|
249
|
+
const { I } = inject()
|
|
252
250
|
|
|
253
251
|
module.exports = {
|
|
254
252
|
fields: {
|
|
255
253
|
email: '#user_basic_email',
|
|
256
|
-
password: '#user_basic_password'
|
|
254
|
+
password: '#user_basic_password',
|
|
257
255
|
},
|
|
258
|
-
submitButton: {css: '#new_user_basic input[type=submit]'},
|
|
256
|
+
submitButton: { css: '#new_user_basic input[type=submit]' },
|
|
259
257
|
|
|
260
258
|
sendForm(email, password) {
|
|
261
|
-
I.fillField(this.fields.email, email)
|
|
262
|
-
I.fillField(this.fields.password, password)
|
|
263
|
-
I.click(this.submitButton)
|
|
264
|
-
}
|
|
259
|
+
I.fillField(this.fields.email, email)
|
|
260
|
+
I.fillField(this.fields.password, password)
|
|
261
|
+
I.click(this.submitButton)
|
|
262
|
+
},
|
|
265
263
|
}
|
|
266
264
|
```
|
|
267
265
|
|
|
268
266
|
You can easily inject it to test by providing its name in test arguments:
|
|
269
267
|
|
|
270
268
|
```js
|
|
271
|
-
Feature('CodeceptJS Demonstration')
|
|
269
|
+
Feature('CodeceptJS Demonstration')
|
|
272
270
|
|
|
273
|
-
Before(({ I }) => {
|
|
274
|
-
|
|
275
|
-
|
|
271
|
+
Before(({ I }) => {
|
|
272
|
+
// or Background
|
|
273
|
+
I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
|
|
274
|
+
})
|
|
276
275
|
|
|
277
276
|
Scenario('test some forms', ({ I, docsPage }) => {
|
|
278
|
-
docsPage.sendForm('hello@world.com','123456')
|
|
279
|
-
I.see('User is valid')
|
|
280
|
-
I.dontSeeInCurrentUrl('/documentation')
|
|
281
|
-
})
|
|
277
|
+
docsPage.sendForm('hello@world.com', '123456')
|
|
278
|
+
I.see('User is valid')
|
|
279
|
+
I.dontSeeInCurrentUrl('/documentation')
|
|
280
|
+
})
|
|
282
281
|
```
|
|
283
282
|
|
|
284
283
|
When using Typescript, replace `module.exports` with `export` for autocompletion.
|
|
285
284
|
|
|
286
|
-
|
|
287
285
|
## Contributing
|
|
288
286
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
287
|
+
- ### [Contributing Guide](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CONTRIBUTING.md)
|
|
288
|
+
- ### [Code of conduct](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CODE_OF_CONDUCT.md)
|
|
292
289
|
|
|
293
290
|
## Contributors
|
|
294
291
|
|
|
295
|
-
Thanks
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
<a href="https://github.com/reubenmiller"><img src="https://avatars.githubusercontent.com/u/3029781?v=4" title="reubenmiller" width="80" height="80"></a>
|
|
302
|
-
<a href="https://github.com/Arhell"><img src="https://avatars.githubusercontent.com/u/26163841?v=4" title="Arhell" width="80" height="80"></a>
|
|
303
|
-
<a href="https://github.com/APshenkin"><img src="https://avatars.githubusercontent.com/u/14344430?v=4" title="APshenkin" width="80" height="80"></a>
|
|
304
|
-
<a href="https://github.com/fabioel"><img src="https://avatars.githubusercontent.com/u/9824235?v=4" title="fabioel" width="80" height="80"></a>
|
|
305
|
-
<a href="https://github.com/pablopaul"><img src="https://avatars.githubusercontent.com/u/635526?v=4" title="pablopaul" width="80" height="80"></a>
|
|
306
|
-
<a href="https://github.com/mirao"><img src="https://avatars.githubusercontent.com/u/12584138?v=4" title="mirao" width="80" height="80"></a>
|
|
307
|
-
<a href="https://github.com/Georgegriff"><img src="https://avatars.githubusercontent.com/u/9056958?v=4" title="Georgegriff" width="80" height="80"></a>
|
|
308
|
-
<a href="https://github.com/KMKoushik"><img src="https://avatars.githubusercontent.com/u/24666922?v=4" title="KMKoushik" width="80" height="80"></a>
|
|
309
|
-
<a href="https://github.com/nikocanvacom"><img src="https://avatars.githubusercontent.com/u/83254493?v=4" title="nikocanvacom" width="80" height="80"></a>
|
|
310
|
-
<a href="https://github.com/elukoyanov"><img src="https://avatars.githubusercontent.com/u/11647141?v=4" title="elukoyanov" width="80" height="80"></a>
|
|
311
|
-
<a href="https://github.com/gkushang"><img src="https://avatars.githubusercontent.com/u/3663389?v=4" title="gkushang" width="80" height="80"></a>
|
|
312
|
-
<a href="https://github.com/tsuemura"><img src="https://avatars.githubusercontent.com/u/17092259?v=4" title="tsuemura" width="80" height="80"></a>
|
|
313
|
-
<a href="https://github.com/EgorBodnar"><img src="https://avatars.githubusercontent.com/u/63167966?v=4" title="EgorBodnar" width="80" height="80"></a>
|
|
314
|
-
<a href="https://github.com/VikalpP"><img src="https://avatars.githubusercontent.com/u/11846339?v=4" title="VikalpP" width="80" height="80"></a>
|
|
315
|
-
<a href="https://github.com/thomashohn"><img src="https://avatars.githubusercontent.com/u/3414869?v=4" title="thomashohn" 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
|
-
<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/ngraf"><img src="https://avatars.githubusercontent.com/u/7094389?v=4" title="ngraf" width="80" height="80"></a>
|
|
319
|
-
<a href="https://github.com/nitschSB"><img src="https://avatars.githubusercontent.com/u/39341455?v=4" title="nitschSB" width="80" height="80"></a>
|
|
320
|
-
<a href="https://github.com/hubidu"><img src="https://avatars.githubusercontent.com/u/13134082?v=4" title="hubidu" width="80" height="80"></a>
|
|
321
|
-
<a href="https://github.com/jploskonka"><img src="https://avatars.githubusercontent.com/u/669483?v=4" title="jploskonka" width="80" height="80"></a>
|
|
322
|
-
<a href="https://github.com/maojunxyz"><img src="https://avatars.githubusercontent.com/u/28778042?v=4" title="maojunxyz" width="80" height="80"></a>
|
|
323
|
-
<a href="https://github.com/abhimanyupandian"><img src="https://avatars.githubusercontent.com/u/36107381?v=4" title="abhimanyupandian" width="80" height="80"></a>
|
|
324
|
-
<a href="https://github.com/martomo"><img src="https://avatars.githubusercontent.com/u/1850135?v=4" title="martomo" width="80" height="80"></a>
|
|
325
|
-
<a href="https://github.com/hatufacci"><img src="https://avatars.githubusercontent.com/u/4963181?v=4" title="hatufacci" width="80" height="80"></a>
|
|
326
|
-
|
|
327
|
-
[//]: contributor-faces
|
|
292
|
+
Thanks to our awesome contributors! 🎉
|
|
293
|
+
<a href="https://github.com/codeceptjs/codeceptjs/graphs/contributors">
|
|
294
|
+
<img src="https://contrib.rocks/image?repo=codeceptjs/codeceptjs" />
|
|
295
|
+
</a>
|
|
296
|
+
|
|
297
|
+
Made with [contrib.rocks](https://contrib.rocks).
|
|
328
298
|
|
|
329
299
|
## License
|
|
330
300
|
|
package/bin/codecept.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { Command } from 'commander'
|
|
3
|
+
const program = new Command()
|
|
4
|
+
import Codecept from '../lib/codecept.js'
|
|
5
|
+
import output from '../lib/output.js'
|
|
6
|
+
const { print, error } = output
|
|
7
|
+
import { printError } from '../lib/command/utils.js'
|
|
6
8
|
|
|
7
9
|
const commandFlags = {
|
|
8
10
|
ai: {
|
|
@@ -32,7 +34,7 @@ const commandFlags = {
|
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
const errorHandler =
|
|
35
|
-
|
|
37
|
+
fn =>
|
|
36
38
|
async (...args) => {
|
|
37
39
|
try {
|
|
38
40
|
await fn(...args)
|
|
@@ -42,6 +44,23 @@ const errorHandler =
|
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
const dynamicImport = async modulePath => {
|
|
48
|
+
const module = await import(modulePath)
|
|
49
|
+
return module.default || module
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const commandHandler = modulePath =>
|
|
53
|
+
errorHandler(async (...args) => {
|
|
54
|
+
const handler = await dynamicImport(modulePath)
|
|
55
|
+
return handler(...args)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const commandHandlerWithProperty = (modulePath, property) =>
|
|
59
|
+
errorHandler(async (...args) => {
|
|
60
|
+
const module = await dynamicImport(modulePath)
|
|
61
|
+
return module[property](...args)
|
|
62
|
+
})
|
|
63
|
+
|
|
45
64
|
if (process.versions.node && process.versions.node.split('.') && process.versions.node.split('.')[0] < 12) {
|
|
46
65
|
error('NodeJS >= 12 is required to run.')
|
|
47
66
|
print()
|
|
@@ -53,15 +72,16 @@ if (process.versions.node && process.versions.node.split('.') && process.version
|
|
|
53
72
|
program.usage('<command> [options]')
|
|
54
73
|
program.version(Codecept.version())
|
|
55
74
|
|
|
56
|
-
program
|
|
57
|
-
.command('init [path]')
|
|
58
|
-
.description('Creates dummy config in current dir or [path]')
|
|
59
|
-
.action(errorHandler(require('../lib/command/init')))
|
|
75
|
+
program.command('init [path]').description('Creates dummy config in current dir or [path]').action(commandHandler('../lib/command/init.js'))
|
|
60
76
|
|
|
61
77
|
program
|
|
62
|
-
.command('
|
|
63
|
-
.
|
|
64
|
-
.
|
|
78
|
+
.command('check')
|
|
79
|
+
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
80
|
+
.description('Checks configuration and environment before running tests')
|
|
81
|
+
.option('-t, --timeout [ms]', 'timeout for checks in ms, 50000 by default')
|
|
82
|
+
.action(commandHandler('../lib/command/check.js'))
|
|
83
|
+
|
|
84
|
+
program.command('migrate [path]').description('Migrate json config to js config in current dir or [path]').action(commandHandler('../lib/command/configMigrate.js'))
|
|
65
85
|
|
|
66
86
|
program
|
|
67
87
|
.command('shell [path]')
|
|
@@ -71,34 +91,30 @@ program
|
|
|
71
91
|
.option(commandFlags.profile.flag, commandFlags.profile.description)
|
|
72
92
|
.option(commandFlags.ai.flag, commandFlags.ai.description)
|
|
73
93
|
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
74
|
-
.action(
|
|
94
|
+
.action(commandHandler('../lib/command/interactive.js'))
|
|
75
95
|
|
|
76
|
-
program
|
|
77
|
-
.command('list [path]')
|
|
78
|
-
.alias('l')
|
|
79
|
-
.description('List all actions for I.')
|
|
80
|
-
.action(errorHandler(require('../lib/command/list')))
|
|
96
|
+
program.command('list [path]').alias('l').description('List all actions for I.').action(commandHandler('../lib/command/list.js'))
|
|
81
97
|
|
|
82
98
|
program
|
|
83
99
|
.command('def [path]')
|
|
84
100
|
.description('Generates TypeScript definitions for all I actions.')
|
|
85
101
|
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
86
102
|
.option('-o, --output [folder]', 'target folder to paste definitions')
|
|
87
|
-
.action(
|
|
103
|
+
.action(commandHandler('../lib/command/definitions.js'))
|
|
88
104
|
|
|
89
105
|
program
|
|
90
106
|
.command('gherkin:init [path]')
|
|
91
107
|
.alias('bdd:init')
|
|
92
108
|
.description('Prepare CodeceptJS to run feature files.')
|
|
93
109
|
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
94
|
-
.action(
|
|
110
|
+
.action(commandHandler('../lib/command/gherkin/init.js'))
|
|
95
111
|
|
|
96
112
|
program
|
|
97
113
|
.command('gherkin:steps [path]')
|
|
98
114
|
.alias('bdd:steps')
|
|
99
115
|
.description('Prints all defined gherkin steps.')
|
|
100
116
|
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
101
|
-
.action(
|
|
117
|
+
.action(commandHandler('../lib/command/gherkin/steps.js'))
|
|
102
118
|
|
|
103
119
|
program
|
|
104
120
|
.command('gherkin:snippets [path]')
|
|
@@ -108,38 +124,22 @@ program
|
|
|
108
124
|
.option(commandFlags.config.flag, commandFlags.config.description)
|
|
109
125
|
.option('--feature [file]', 'feature files(s) to scan')
|
|
110
126
|
.option('--path [file]', 'file in which to place the new snippets')
|
|
111
|
-
.action(
|
|
127
|
+
.action(commandHandler('../lib/command/gherkin/snippets.js'))
|
|
112
128
|
|
|
113
|
-
program
|
|
114
|
-
.command('generate:test [path]')
|
|
115
|
-
.alias('gt')
|
|
116
|
-
.description('Generates an empty test')
|
|
117
|
-
.action(errorHandler(require('../lib/command/generate').test))
|
|
129
|
+
program.command('generate:test [path]').alias('gt').description('Generates an empty test').action(commandHandlerWithProperty('../lib/command/generate.js', 'test'))
|
|
118
130
|
|
|
119
|
-
program
|
|
120
|
-
.command('generate:pageobject [path]')
|
|
121
|
-
.alias('gpo')
|
|
122
|
-
.description('Generates an empty page object')
|
|
123
|
-
.action(errorHandler(require('../lib/command/generate').pageObject))
|
|
131
|
+
program.command('generate:pageobject [path]').alias('gpo').description('Generates an empty page object').action(commandHandlerWithProperty('../lib/command/generate.js', 'pageObject'))
|
|
124
132
|
|
|
125
133
|
program
|
|
126
134
|
.command('generate:object [path]')
|
|
127
135
|
.alias('go')
|
|
128
136
|
.option('--type, -t [kind]', 'type of object to be created')
|
|
129
137
|
.description('Generates an empty support object (page/step/fragment)')
|
|
130
|
-
.action(
|
|
138
|
+
.action(commandHandlerWithProperty('../lib/command/generate.js', 'pageObject'))
|
|
131
139
|
|
|
132
|
-
program
|
|
133
|
-
.command('generate:helper [path]')
|
|
134
|
-
.alias('gh')
|
|
135
|
-
.description('Generates a new helper')
|
|
136
|
-
.action(errorHandler(require('../lib/command/generate').helper))
|
|
140
|
+
program.command('generate:helper [path]').alias('gh').description('Generates a new helper').action(commandHandlerWithProperty('../lib/command/generate.js', 'helper'))
|
|
137
141
|
|
|
138
|
-
program
|
|
139
|
-
.command('generate:heal [path]')
|
|
140
|
-
.alias('gr')
|
|
141
|
-
.description('Generates basic heal recipes')
|
|
142
|
-
.action(errorHandler(require('../lib/command/generate').heal))
|
|
142
|
+
program.command('generate:heal [path]').alias('gr').description('Generates basic heal recipes').action(commandHandlerWithProperty('../lib/command/generate.js', 'heal'))
|
|
143
143
|
|
|
144
144
|
program
|
|
145
145
|
.command('run [test]')
|
|
@@ -178,7 +178,7 @@ program
|
|
|
178
178
|
.option('--recursive', 'include sub directories')
|
|
179
179
|
.option('--trace', 'trace function calls')
|
|
180
180
|
.option('--child <string>', 'option for child processes')
|
|
181
|
-
.action(
|
|
181
|
+
.action(commandHandler('../lib/command/run.js'))
|
|
182
182
|
|
|
183
183
|
program
|
|
184
184
|
.command('run-workers <workers> [selectedRuns...]')
|
|
@@ -197,7 +197,7 @@ program
|
|
|
197
197
|
.option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
|
|
198
198
|
.option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
|
|
199
199
|
.option('-R, --reporter <name>', 'specify the reporter to use')
|
|
200
|
-
.action(
|
|
200
|
+
.action(commandHandler('../lib/command/run-workers.js'))
|
|
201
201
|
|
|
202
202
|
program
|
|
203
203
|
.command('run-multiple [suites...]')
|
|
@@ -223,13 +223,9 @@ program
|
|
|
223
223
|
// mocha options
|
|
224
224
|
.option('--colors', 'force enabling of colors')
|
|
225
225
|
|
|
226
|
-
.action(
|
|
226
|
+
.action(commandHandler('../lib/command/run-multiple.js'))
|
|
227
227
|
|
|
228
|
-
program
|
|
229
|
-
.command('info [path]')
|
|
230
|
-
.description('Print debugging information concerning the local environment')
|
|
231
|
-
.option('-c, --config', 'your config file path')
|
|
232
|
-
.action(errorHandler(require('../lib/command/info')))
|
|
228
|
+
program.command('info [path]').description('Print debugging information concerning the local environment').option('-c, --config', 'your config file path').action(commandHandler('../lib/command/info.js'))
|
|
233
229
|
|
|
234
230
|
program
|
|
235
231
|
.command('dry-run [test]')
|
|
@@ -246,7 +242,7 @@ program
|
|
|
246
242
|
.option(commandFlags.steps.flag, commandFlags.steps.description)
|
|
247
243
|
.option(commandFlags.verbose.flag, commandFlags.verbose.description)
|
|
248
244
|
.option(commandFlags.debug.flag, commandFlags.debug.description)
|
|
249
|
-
.action(
|
|
245
|
+
.action(commandHandler('../lib/command/dryRun.js'))
|
|
250
246
|
|
|
251
247
|
program
|
|
252
248
|
.command('run-rerun [test]')
|
|
@@ -284,9 +280,12 @@ program
|
|
|
284
280
|
.option('--trace', 'trace function calls')
|
|
285
281
|
.option('--child <string>', 'option for child processes')
|
|
286
282
|
|
|
287
|
-
.action(
|
|
283
|
+
.action(async (...args) => {
|
|
284
|
+
const runRerun = await dynamicImport('../lib/command/run-rerun.js')
|
|
285
|
+
return runRerun(...args)
|
|
286
|
+
})
|
|
288
287
|
|
|
289
|
-
program.on('command:*',
|
|
288
|
+
program.on('command:*', cmd => {
|
|
290
289
|
console.log(`\nUnknown command ${cmd}\n`)
|
|
291
290
|
program.outputHelp()
|
|
292
291
|
})
|
|
@@ -3,7 +3,7 @@ if none provided clears all cookies.
|
|
|
3
3
|
|
|
4
4
|
```js
|
|
5
5
|
I.clearCookie();
|
|
6
|
-
I.clearCookie('test');
|
|
6
|
+
I.clearCookie('test');
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
@param {?string} [cookie=null] (optional, `null` by default) cookie name
|