codeceptjs 3.6.0-beta.1.ai-healers → 3.6.0
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 +2 -1
- package/docs/webapi/dontSeeTraffic.mustache +13 -0
- package/docs/webapi/flushNetworkTraffics.mustache +5 -0
- package/docs/webapi/grabRecordedNetworkTraffics.mustache +10 -0
- package/docs/webapi/seeTraffic.mustache +36 -0
- package/docs/webapi/startRecordingTraffic.mustache +8 -0
- package/docs/webapi/startRecordingWebSocketMessages.mustache +8 -0
- package/docs/webapi/stopRecordingTraffic.mustache +5 -0
- package/docs/webapi/stopRecordingWebSocketMessages.mustache +7 -0
- package/docs/webapi/waitForCookie.mustache +9 -0
- package/lib/actor.js +6 -3
- package/lib/command/dryRun.js +44 -13
- package/lib/helper/Appium.js +36 -12
- package/lib/helper/Expect.js +11 -8
- package/lib/helper/JSONResponse.js +8 -8
- package/lib/helper/MockServer.js +221 -0
- package/lib/helper/Playwright.js +107 -371
- package/lib/helper/Puppeteer.js +404 -71
- package/lib/helper/REST.js +4 -1
- package/lib/helper/WebDriver.js +189 -13
- package/lib/helper/errors/ElementAssertion.js +38 -0
- package/lib/helper/extras/PlaywrightReactVueLocator.js +6 -1
- package/lib/helper/network/actions.js +123 -0
- package/lib/helper/network/utils.js +187 -0
- package/lib/locator.js +36 -5
- package/lib/plugin/coverage.js +112 -99
- package/lib/step.js +3 -1
- package/package.json +48 -37
- package/typings/index.d.ts +19 -2
- package/typings/promiseBasedTypes.d.ts +505 -41
- package/typings/types.d.ts +609 -56
- package/docs/advanced.md +0 -351
- package/docs/ai.md +0 -365
- package/docs/api.md +0 -323
- package/docs/basics.md +0 -979
- package/docs/bdd.md +0 -539
- package/docs/best.md +0 -237
- package/docs/books.md +0 -37
- package/docs/bootstrap.md +0 -135
- package/docs/build/AI.js +0 -124
- package/docs/build/ApiDataFactory.js +0 -410
- package/docs/build/Appium.js +0 -2027
- package/docs/build/Expect.js +0 -422
- package/docs/build/FileSystem.js +0 -228
- package/docs/build/GraphQL.js +0 -229
- package/docs/build/GraphQLDataFactory.js +0 -309
- package/docs/build/JSONResponse.js +0 -338
- package/docs/build/Mochawesome.js +0 -71
- package/docs/build/Nightmare.js +0 -2152
- package/docs/build/OpenAI.js +0 -126
- package/docs/build/Playwright.js +0 -5110
- package/docs/build/Protractor.js +0 -2706
- package/docs/build/Puppeteer.js +0 -3905
- package/docs/build/REST.js +0 -344
- package/docs/build/TestCafe.js +0 -2125
- package/docs/build/WebDriver.js +0 -4240
- package/docs/changelog.md +0 -2572
- package/docs/commands.md +0 -266
- package/docs/community-helpers.md +0 -58
- package/docs/configuration.md +0 -157
- package/docs/continuous-integration.md +0 -22
- package/docs/custom-helpers.md +0 -306
- package/docs/data.md +0 -379
- package/docs/detox.md +0 -235
- package/docs/docker.md +0 -136
- package/docs/email.md +0 -183
- package/docs/examples.md +0 -149
- package/docs/heal.md +0 -186
- package/docs/helpers/ApiDataFactory.md +0 -266
- package/docs/helpers/Appium.md +0 -1374
- package/docs/helpers/Detox.md +0 -586
- package/docs/helpers/Expect.md +0 -275
- package/docs/helpers/FileSystem.md +0 -152
- package/docs/helpers/GraphQL.md +0 -151
- package/docs/helpers/GraphQLDataFactory.md +0 -226
- package/docs/helpers/JSONResponse.md +0 -254
- package/docs/helpers/Mochawesome.md +0 -8
- package/docs/helpers/MockRequest.md +0 -377
- package/docs/helpers/Nightmare.md +0 -1305
- package/docs/helpers/OpenAI.md +0 -70
- package/docs/helpers/Playwright.md +0 -2759
- package/docs/helpers/Polly.md +0 -44
- package/docs/helpers/Protractor.md +0 -1769
- package/docs/helpers/Puppeteer-firefox.md +0 -86
- package/docs/helpers/Puppeteer.md +0 -2317
- package/docs/helpers/REST.md +0 -218
- package/docs/helpers/TestCafe.md +0 -1321
- package/docs/helpers/WebDriver.md +0 -2547
- package/docs/hooks.md +0 -340
- package/docs/index.md +0 -111
- package/docs/installation.md +0 -75
- package/docs/internal-api.md +0 -266
- package/docs/locators.md +0 -339
- package/docs/mobile-react-native-locators.md +0 -67
- package/docs/mobile.md +0 -338
- package/docs/pageobjects.md +0 -291
- package/docs/parallel.md +0 -400
- package/docs/playwright.md +0 -632
- package/docs/plugins.md +0 -1247
- package/docs/puppeteer.md +0 -316
- package/docs/quickstart.md +0 -162
- package/docs/react.md +0 -70
- package/docs/reports.md +0 -392
- package/docs/secrets.md +0 -36
- package/docs/shadow.md +0 -68
- package/docs/shared/keys.mustache +0 -31
- package/docs/shared/react.mustache +0 -1
- package/docs/testcafe.md +0 -174
- package/docs/translation.md +0 -247
- package/docs/tutorial.md +0 -271
- package/docs/typescript.md +0 -180
- package/docs/ui.md +0 -59
- package/docs/videos.md +0 -28
- package/docs/visual.md +0 -202
- package/docs/vue.md +0 -143
- package/docs/webdriver.md +0 -701
- package/docs/wiki/Books-&-Posts.md +0 -27
- package/docs/wiki/Community-Helpers-&-Plugins.md +0 -53
- package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +0 -61
- package/docs/wiki/Examples.md +0 -145
- package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +0 -68
- package/docs/wiki/Home.md +0 -16
- package/docs/wiki/Migration-to-Appium-v2---CodeceptJS.md +0 -83
- package/docs/wiki/Release-Process.md +0 -24
- package/docs/wiki/Roadmap.md +0 -23
- package/docs/wiki/Tests.md +0 -1393
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +0 -153
- package/docs/wiki/Videos.md +0 -19
package/docs/heal.md
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
# Self-Healing Tests
|
|
2
|
-
|
|
3
|
-
Browser and Mobile tests can fail for vareity of reasons. However, on a big projects there are about 5-10 causes of flaky tests. The more you work and understand your end-to-end tests the more you learn patterns of failure. And after the research you understand how a test could have been fixed: to reload a page, to click that button once again, restart API request. If by looking into a failure you understand what, as a user, you would do to fix that error, then maybe you could teach your tests to heal themselves.
|
|
4
|
-
|
|
5
|
-
## What is Healing
|
|
6
|
-
|
|
7
|
-
**Healing defines the way how a test reacts to failure**. You can define multiple healing recipes that could take all needed information: error message, failed test, step, page URL, HTML, etc. A healing recipe can perform some action to fix the failing test on the fly and continue its execution.
|
|
8
|
-
|
|
9
|
-

|
|
10
|
-
|
|
11
|
-
Let's start with an example the most basic healing recipe. If after a click test has failed, try to reload page, and continue.
|
|
12
|
-
|
|
13
|
-
```js
|
|
14
|
-
heal.addRecipe('reload', {
|
|
15
|
-
priority: 10,
|
|
16
|
-
steps: ['click'],
|
|
17
|
-
fn: async () => {
|
|
18
|
-
return ({ I }) => {
|
|
19
|
-
I.refreshPage();
|
|
20
|
-
};
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Sure, this won't always work and probably won't be useful on every project. But let's follow the idea: if a click has failed, probably the button is not on a page, maybe it is an issue of rendering, maybe some other element overlapped our button, so if we try to reload page we can continue test execution. At least, this is what manual QA would do if they will run the following test in a browser. They will try to reload a page before reporting "it has failed".
|
|
26
|
-
|
|
27
|
-
So if it is a long end-2-end test that implements user journey, it is more valuable to continue its execution when possible, then fixing a minor issues like overlapping elements. Healing like this can improve the stability of a test.
|
|
28
|
-
|
|
29
|
-
The example above is only one way a test can be healed. But you can define as many heal recipes as you like. What heal recipe would be effective in your case is depends on a system you test, so **there are no pre-defined heal recipes**.
|
|
30
|
-
|
|
31
|
-
## Healing Patterns
|
|
32
|
-
|
|
33
|
-
There are some ideas where healing can be useful to you:
|
|
34
|
-
|
|
35
|
-
* **Networking**. If a test depends on a remote resource, and fails because this resource is not available, you may try to send API request to restore that resource before throwing an error.
|
|
36
|
-
* **Data Consistency**. A test may fail because you noticed the data glitch in a system. Instead of failing a test you may try to clean up the data and try again to proceed.
|
|
37
|
-
* **UI Change**. If there is a planned UI migration of a component, for instance Button was changed to Dropdown. You can prepare test so if it fails clicking Button it can try to do so with Dropdown.
|
|
38
|
-
* **Do it again**. If you know, that going one step back and trying to do same actions may solve the issue, you can do so from healers. For instance, a modal didn't render correctly, so you can close it and try to click to open it again.
|
|
39
|
-
|
|
40
|
-
## Healing vs Retries
|
|
41
|
-
|
|
42
|
-
Unlike retries heal recipes has following benefits:
|
|
43
|
-
|
|
44
|
-
* Heal recipes are **declarative**, they are not added directly into into the test code. This keeps test clean and scenario-focused,
|
|
45
|
-
* Retry can only re-run failed step(s), but heal recipe can **perform wide set of actions**
|
|
46
|
-
* Heal recipe **can react to any step of any test**. So if you catch a common error and you can heal it, you won't need to guess where it can be thrown.
|
|
47
|
-
|
|
48
|
-
## How to Start Healing
|
|
49
|
-
|
|
50
|
-
To enable healing, you need to define healing recipes and enable heal plugin.
|
|
51
|
-
|
|
52
|
-
Create basic healing recipes using this command:
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
npx codeceptjs geenrate:heal
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
or
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
npx codeceptjs gr
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
this will generate `recipes.js` (or `recipes.ts`) in the root directory. Provided default recipe include [AI healing](#ai-healing) and `clickAndType` recipe that replaces `fillField` with `click`+`type`. Use them as examples to write your own heal recipes that will fit for application you are testing.
|
|
65
|
-
|
|
66
|
-
Require `recipes` file and add `heal` plugin to `codecept.conf` file:
|
|
67
|
-
|
|
68
|
-
```js
|
|
69
|
-
|
|
70
|
-
require('./heal')
|
|
71
|
-
|
|
72
|
-
exports.config = {
|
|
73
|
-
// ...
|
|
74
|
-
plugins: {
|
|
75
|
-
heal: {
|
|
76
|
-
enabled: true
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
> Please note that, healing has no sense while developing tests, so it won't work in `--debug` mode.
|
|
83
|
-
|
|
84
|
-
## Writing Recipes
|
|
85
|
-
|
|
86
|
-
Custom heal recipes can be added by running `heal.addRecipe()` function. By default it should be added to `recipes.js` (or `recipes.ts`) file.
|
|
87
|
-
|
|
88
|
-
Let's see what recipe consist of:
|
|
89
|
-
|
|
90
|
-
```js
|
|
91
|
-
heal.addRecipe('reloadPageOnUserAccount', {
|
|
92
|
-
// recipe priority
|
|
93
|
-
// which recipe should be tried first
|
|
94
|
-
priority: 10,
|
|
95
|
-
|
|
96
|
-
// an array of steps which may cause the error
|
|
97
|
-
// after which a recipe should be activate
|
|
98
|
-
steps: [
|
|
99
|
-
'click',
|
|
100
|
-
],
|
|
101
|
-
|
|
102
|
-
// if you need some additional information like URL of a page,
|
|
103
|
-
// or its HTML, you can add this context to healing function by
|
|
104
|
-
// defining `prepare` list of variable
|
|
105
|
-
prepare: {
|
|
106
|
-
url: ({ I }) => I.grabCurrentUrl(),
|
|
107
|
-
html: ({ I }) => I.grabHTMLFrom('body'),
|
|
108
|
-
// don't add variables that you won't use inside the recipe
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
// probably we want to execute recipes only on some tests
|
|
112
|
-
// so you can set a string or regex which will check if a test title matches the name
|
|
113
|
-
// in this case we execute recipe only on tests that have "@flaky" in their name
|
|
114
|
-
grep: '@flaky',
|
|
115
|
-
|
|
116
|
-
// function to launch to heal the
|
|
117
|
-
fn: async ({
|
|
118
|
-
// standard context variables
|
|
119
|
-
step, test, error, prevSteps,
|
|
120
|
-
|
|
121
|
-
// variables coming from prepare function
|
|
122
|
-
html, url,
|
|
123
|
-
|
|
124
|
-
}) => {
|
|
125
|
-
const stepArgs = step.args;
|
|
126
|
-
|
|
127
|
-
// at this point we can decide, should we provide a healing recipe or not
|
|
128
|
-
// for instance, if URL is not the one we can heal at, we should not provide any recipes
|
|
129
|
-
if (!url.includes('/user/acccount')) return;
|
|
130
|
-
|
|
131
|
-
// otherwise we return a function that will be executed
|
|
132
|
-
return ({ I }) => {
|
|
133
|
-
// this is a very basic example action
|
|
134
|
-
// probably you should do something more sophisticated
|
|
135
|
-
// to heal the test
|
|
136
|
-
I.reloadPage();
|
|
137
|
-
I.wait(1);
|
|
138
|
-
};
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Let's briefly sum up the properties of a recipe:
|
|
144
|
-
|
|
145
|
-
* `grep` - selects tests by their name to apply heal to
|
|
146
|
-
* `steps` - defines on which steps a recipe should react
|
|
147
|
-
* `priority` - sets the order of recipes being applied
|
|
148
|
-
* `prepare` - declare variables from a context, which can be used for healing
|
|
149
|
-
* `fn` - a function to be applied for healing. It takes all context params: `test`, `step`, `error`, `prevSteps` and returns return either a function or a markdown text with recipes (used by AI healers). If no recipes match the context should not return anything;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
## AI Healing
|
|
153
|
-
|
|
154
|
-
AI can be used to heal failed tests. Large Language Models can analyze HTML of a failed test and provide a suggestion what actions should be performed instead. This can be helpful when running tests on CI as AI can make basic decisions to stabilize failing tests.
|
|
155
|
-
|
|
156
|
-
> Use **OpenAI, Azure OpenAI, Claude**, or any of other LLM that can take a prompt, analyze request and provide valid JS code which can be executed by CodeceptJS as a healing suggestion.
|
|
157
|
-
|
|
158
|
-
AI healing recipe is created within `recipes.js` file:
|
|
159
|
-
|
|
160
|
-
```js
|
|
161
|
-
heal.addRecipe('ai', {
|
|
162
|
-
priority: 10,
|
|
163
|
-
prepare: {
|
|
164
|
-
html: ({ I }) => I.grabHTMLFrom('body'),
|
|
165
|
-
},
|
|
166
|
-
steps: [
|
|
167
|
-
'click',
|
|
168
|
-
'fillField',
|
|
169
|
-
'appendField',
|
|
170
|
-
'selectOption',
|
|
171
|
-
'attachFile',
|
|
172
|
-
'checkOption',
|
|
173
|
-
'uncheckOption',
|
|
174
|
-
'doubleClick',
|
|
175
|
-
],
|
|
176
|
-
fn: async (args) => {
|
|
177
|
-
return ai.healFailedStep(args);
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
As you usee, it will be activated on failed steps and will use HTML of a page as additional information. The prompt, error, and the HTML will be sent to AI provider you configured.
|
|
183
|
-
|
|
184
|
-
Learn more how you can [configure AI provider](./ai).
|
|
185
|
-
|
|
186
|
-
To activate the AI healer don't forget to run tests with `--ai` flag.
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
permalink: /helpers/ApiDataFactory
|
|
3
|
-
editLink: false
|
|
4
|
-
sidebar: auto
|
|
5
|
-
title: ApiDataFactory
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
|
9
|
-
|
|
10
|
-
## ApiDataFactory
|
|
11
|
-
|
|
12
|
-
**Extends Helper**
|
|
13
|
-
|
|
14
|
-
Helper for managing remote data using REST API.
|
|
15
|
-
Uses data generators like [rosie][1] or factory girl to create new record.
|
|
16
|
-
|
|
17
|
-
By defining a factory you set the rules of how data is generated.
|
|
18
|
-
This data will be saved on server via REST API and deleted in the end of a test.
|
|
19
|
-
|
|
20
|
-
## Use Case
|
|
21
|
-
|
|
22
|
-
Acceptance tests interact with a websites using UI and real browser.
|
|
23
|
-
There is no way to create data for a specific test other than from user interface.
|
|
24
|
-
That makes tests slow and fragile. Instead of testing a single feature you need to follow all creation/removal process.
|
|
25
|
-
|
|
26
|
-
This helper solves this problem.
|
|
27
|
-
Most of web application have API, and it can be used to create and delete test records.
|
|
28
|
-
By combining REST API with Factories you can easily create records for tests:
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
I.have('user', { login: 'davert', email: 'davert@mail.com' });
|
|
32
|
-
let id = await I.have('post', { title: 'My first post'});
|
|
33
|
-
I.haveMultiple('comment', 3, {post_id: id});
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
To make this work you need
|
|
37
|
-
|
|
38
|
-
1. REST API endpoint which allows to perform create / delete requests and
|
|
39
|
-
2. define data generation rules
|
|
40
|
-
|
|
41
|
-
### Setup
|
|
42
|
-
|
|
43
|
-
Install [Rosie][1] and [Faker][2] libraries.
|
|
44
|
-
|
|
45
|
-
```sh
|
|
46
|
-
npm i rosie @faker-js/faker --save-dev
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Create a factory file for a resource.
|
|
50
|
-
|
|
51
|
-
See the example for Posts factories:
|
|
52
|
-
|
|
53
|
-
```js
|
|
54
|
-
// tests/factories/posts.js
|
|
55
|
-
|
|
56
|
-
const { Factory } = require('rosie');
|
|
57
|
-
const { faker } = require('@faker-js/faker');
|
|
58
|
-
|
|
59
|
-
module.exports = new Factory()
|
|
60
|
-
// no need to set id, it will be set by REST API
|
|
61
|
-
.attr('author', () => faker.name.findName())
|
|
62
|
-
.attr('title', () => faker.lorem.sentence())
|
|
63
|
-
.attr('body', () => faker.lorem.paragraph());
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
For more options see [rosie documentation][1].
|
|
67
|
-
|
|
68
|
-
Then configure ApiDataHelper to match factories and REST API:
|
|
69
|
-
|
|
70
|
-
### Configuration
|
|
71
|
-
|
|
72
|
-
ApiDataFactory has following config options:
|
|
73
|
-
|
|
74
|
-
- `endpoint`: base URL for the API to send requests to.
|
|
75
|
-
- `cleanup` (default: true): should inserted records be deleted up after tests
|
|
76
|
-
- `factories`: list of defined factories
|
|
77
|
-
- `returnId` (default: false): return id instead of a complete response when creating items.
|
|
78
|
-
- `headers`: list of headers
|
|
79
|
-
- `REST`: configuration for REST requests
|
|
80
|
-
|
|
81
|
-
See the example:
|
|
82
|
-
|
|
83
|
-
```js
|
|
84
|
-
ApiDataFactory: {
|
|
85
|
-
endpoint: "http://user.com/api",
|
|
86
|
-
cleanup: true,
|
|
87
|
-
headers: {
|
|
88
|
-
'Content-Type': 'application/json',
|
|
89
|
-
'Accept': 'application/json',
|
|
90
|
-
},
|
|
91
|
-
factories: {
|
|
92
|
-
post: {
|
|
93
|
-
uri: "/posts",
|
|
94
|
-
factory: "./factories/post",
|
|
95
|
-
},
|
|
96
|
-
comment: {
|
|
97
|
-
factory: "./factories/comment",
|
|
98
|
-
create: { post: "/comments/create" },
|
|
99
|
-
delete: { post: "/comments/delete/{id}" },
|
|
100
|
-
fetchId: (data) => data.result.id
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
It is required to set REST API `endpoint` which is the baseURL for all API requests.
|
|
107
|
-
Factory file is expected to be passed via `factory` option.
|
|
108
|
-
|
|
109
|
-
This Helper uses [REST][3] helper and accepts its configuration in "REST" section.
|
|
110
|
-
For instance, to set timeout you should add:
|
|
111
|
-
|
|
112
|
-
```js
|
|
113
|
-
"ApiDataFactory": {
|
|
114
|
-
"REST": {
|
|
115
|
-
"timeout": "100000",
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### Requests
|
|
121
|
-
|
|
122
|
-
By default to create a record ApiDataFactory will use endpoint and plural factory name:
|
|
123
|
-
|
|
124
|
-
- create: `POST {endpoint}/{resource} data`
|
|
125
|
-
- delete: `DELETE {endpoint}/{resource}/id`
|
|
126
|
-
|
|
127
|
-
Example (`endpoint`: `http://app.com/api`):
|
|
128
|
-
|
|
129
|
-
- create: POST request to `http://app.com/api/users`
|
|
130
|
-
- delete: DELETE request to `http://app.com/api/users/1`
|
|
131
|
-
|
|
132
|
-
This behavior can be configured with following options:
|
|
133
|
-
|
|
134
|
-
- `uri`: set different resource uri. Example: `uri: account` => `http://app.com/api/account`.
|
|
135
|
-
- `create`: override create options. Expected format: `{ method: uri }`. Example: `{ "post": "/users/create" }`
|
|
136
|
-
- `delete`: override delete options. Expected format: `{ method: uri }`. Example: `{ "post": "/users/delete/{id}" }`
|
|
137
|
-
|
|
138
|
-
Requests can also be overridden with a function which returns [axois request config][4].
|
|
139
|
-
|
|
140
|
-
```js
|
|
141
|
-
create: (data) => ({ method: 'post', url: '/posts', data }),
|
|
142
|
-
delete: (id) => ({ method: 'delete', url: '/posts', data: { id } })
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Requests can be updated on the fly by using `onRequest` function. For instance, you can pass in current session from a cookie.
|
|
146
|
-
|
|
147
|
-
```js
|
|
148
|
-
onRequest: async (request) => {
|
|
149
|
-
// using global codeceptjs instance
|
|
150
|
-
let cookie = await codeceptjs.container.helpers('WebDriver').grabCookie('session');
|
|
151
|
-
request.headers = { Cookie: `session=${cookie.value}` };
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Responses
|
|
156
|
-
|
|
157
|
-
By default `I.have()` returns a promise with a created data:
|
|
158
|
-
|
|
159
|
-
```js
|
|
160
|
-
let client = await I.have('client');
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Ids of created records are collected and used in the end of a test for the cleanup.
|
|
164
|
-
If you need to receive `id` instead of full response enable `returnId` in a helper config:
|
|
165
|
-
|
|
166
|
-
```js
|
|
167
|
-
// returnId: false
|
|
168
|
-
let clientId = await I.have('client');
|
|
169
|
-
// clientId == 1
|
|
170
|
-
|
|
171
|
-
// returnId: true
|
|
172
|
-
let clientId = await I.have('client');
|
|
173
|
-
// client == { name: 'John', email: 'john@snow.com' }
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
By default `id` property of response is taken. This behavior can be changed by setting `fetchId` function in a factory config.
|
|
177
|
-
|
|
178
|
-
```js
|
|
179
|
-
factories: {
|
|
180
|
-
post: {
|
|
181
|
-
uri: "/posts",
|
|
182
|
-
factory: "./factories/post",
|
|
183
|
-
fetchId: (data) => data.result.posts[0].id
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Methods
|
|
189
|
-
|
|
190
|
-
### Parameters
|
|
191
|
-
|
|
192
|
-
- `config`
|
|
193
|
-
|
|
194
|
-
### _requestCreate
|
|
195
|
-
|
|
196
|
-
Executes request to create a record in API.
|
|
197
|
-
Can be replaced from a in custom helper.
|
|
198
|
-
|
|
199
|
-
#### Parameters
|
|
200
|
-
|
|
201
|
-
- `factory` **any**
|
|
202
|
-
- `data` **any**
|
|
203
|
-
|
|
204
|
-
### _requestDelete
|
|
205
|
-
|
|
206
|
-
Executes request to delete a record in API
|
|
207
|
-
Can be replaced from a custom helper.
|
|
208
|
-
|
|
209
|
-
#### Parameters
|
|
210
|
-
|
|
211
|
-
- `factory` **any**
|
|
212
|
-
- `id` **any**
|
|
213
|
-
|
|
214
|
-
### have
|
|
215
|
-
|
|
216
|
-
Generates a new record using factory and saves API request to store it.
|
|
217
|
-
|
|
218
|
-
```js
|
|
219
|
-
// create a user
|
|
220
|
-
I.have('user');
|
|
221
|
-
// create user with defined email
|
|
222
|
-
// and receive it when inside async function
|
|
223
|
-
const user = await I.have('user', { email: 'user@user.com'});
|
|
224
|
-
// create a user with options that will not be included in the final request
|
|
225
|
-
I.have('user', { }, { age: 33, height: 55 })
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
#### Parameters
|
|
229
|
-
|
|
230
|
-
- `factory` **any** factory to use
|
|
231
|
-
- `params` **any?** predefined parameters
|
|
232
|
-
- `options` **any?** options for programmatically generate the attributes
|
|
233
|
-
|
|
234
|
-
Returns **[Promise][5]<any>**
|
|
235
|
-
|
|
236
|
-
### haveMultiple
|
|
237
|
-
|
|
238
|
-
Generates bunch of records and saves multiple API requests to store them.
|
|
239
|
-
|
|
240
|
-
```js
|
|
241
|
-
// create 3 posts
|
|
242
|
-
I.haveMultiple('post', 3);
|
|
243
|
-
|
|
244
|
-
// create 3 posts by one author
|
|
245
|
-
I.haveMultiple('post', 3, { author: 'davert' });
|
|
246
|
-
|
|
247
|
-
// create 3 posts by one author with options
|
|
248
|
-
I.haveMultiple('post', 3, { author: 'davert' }, { publish_date: '01.01.1997' });
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
#### Parameters
|
|
252
|
-
|
|
253
|
-
- `factory` **any**
|
|
254
|
-
- `times` **any**
|
|
255
|
-
- `params` **any?**
|
|
256
|
-
- `options` **any?**
|
|
257
|
-
|
|
258
|
-
[1]: https://github.com/rosiejs/rosie
|
|
259
|
-
|
|
260
|
-
[2]: https://www.npmjs.com/package/faker
|
|
261
|
-
|
|
262
|
-
[3]: http://codecept.io/helpers/REST/
|
|
263
|
-
|
|
264
|
-
[4]: https://github.com/axios/axios#request-config
|
|
265
|
-
|
|
266
|
-
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
|