codeceptjs 3.5.12-beta.2 → 3.5.12-beta.3
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/lib/locator.js +7 -12
- package/package.json +3 -5
- package/docs/advanced.md +0 -351
- package/docs/ai.md +0 -248
- 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/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/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 -1259
- 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/webapi/amOnPage.mustache +0 -11
- package/docs/webapi/appendField.mustache +0 -11
- package/docs/webapi/attachFile.mustache +0 -12
- package/docs/webapi/blur.mustache +0 -18
- package/docs/webapi/checkOption.mustache +0 -13
- package/docs/webapi/clearCookie.mustache +0 -9
- package/docs/webapi/clearField.mustache +0 -9
- package/docs/webapi/click.mustache +0 -25
- package/docs/webapi/clickLink.mustache +0 -8
- package/docs/webapi/closeCurrentTab.mustache +0 -7
- package/docs/webapi/closeOtherTabs.mustache +0 -8
- package/docs/webapi/dontSee.mustache +0 -11
- package/docs/webapi/dontSeeCheckboxIsChecked.mustache +0 -10
- package/docs/webapi/dontSeeCookie.mustache +0 -8
- package/docs/webapi/dontSeeCurrentUrlEquals.mustache +0 -10
- package/docs/webapi/dontSeeElement.mustache +0 -8
- package/docs/webapi/dontSeeElementInDOM.mustache +0 -8
- package/docs/webapi/dontSeeInCurrentUrl.mustache +0 -4
- package/docs/webapi/dontSeeInField.mustache +0 -11
- package/docs/webapi/dontSeeInSource.mustache +0 -8
- package/docs/webapi/dontSeeInTitle.mustache +0 -8
- package/docs/webapi/doubleClick.mustache +0 -13
- package/docs/webapi/downloadFile.mustache +0 -12
- package/docs/webapi/dragAndDrop.mustache +0 -9
- package/docs/webapi/dragSlider.mustache +0 -11
- package/docs/webapi/executeAsyncScript.mustache +0 -24
- package/docs/webapi/executeScript.mustache +0 -26
- package/docs/webapi/fillField.mustache +0 -16
- package/docs/webapi/focus.mustache +0 -13
- package/docs/webapi/forceClick.mustache +0 -28
- package/docs/webapi/forceRightClick.mustache +0 -18
- package/docs/webapi/grabAllWindowHandles.mustache +0 -7
- package/docs/webapi/grabAttributeFrom.mustache +0 -10
- package/docs/webapi/grabAttributeFromAll.mustache +0 -9
- package/docs/webapi/grabBrowserLogs.mustache +0 -9
- package/docs/webapi/grabCookie.mustache +0 -11
- package/docs/webapi/grabCssPropertyFrom.mustache +0 -11
- package/docs/webapi/grabCssPropertyFromAll.mustache +0 -10
- package/docs/webapi/grabCurrentUrl.mustache +0 -9
- package/docs/webapi/grabCurrentWindowHandle.mustache +0 -6
- package/docs/webapi/grabDataFromPerformanceTiming.mustache +0 -20
- package/docs/webapi/grabElementBoundingRect.mustache +0 -20
- package/docs/webapi/grabGeoLocation.mustache +0 -8
- package/docs/webapi/grabHTMLFrom.mustache +0 -10
- package/docs/webapi/grabHTMLFromAll.mustache +0 -9
- package/docs/webapi/grabNumberOfOpenTabs.mustache +0 -8
- package/docs/webapi/grabNumberOfVisibleElements.mustache +0 -9
- package/docs/webapi/grabPageScrollPosition.mustache +0 -8
- package/docs/webapi/grabPopupText.mustache +0 -5
- package/docs/webapi/grabSource.mustache +0 -8
- package/docs/webapi/grabTextFrom.mustache +0 -10
- package/docs/webapi/grabTextFromAll.mustache +0 -9
- package/docs/webapi/grabTitle.mustache +0 -8
- package/docs/webapi/grabValueFrom.mustache +0 -9
- package/docs/webapi/grabValueFromAll.mustache +0 -8
- package/docs/webapi/grabWebElement.mustache +0 -9
- package/docs/webapi/grabWebElements.mustache +0 -9
- package/docs/webapi/moveCursorTo.mustache +0 -12
- package/docs/webapi/openNewTab.mustache +0 -7
- package/docs/webapi/pressKey.mustache +0 -12
- package/docs/webapi/pressKeyDown.mustache +0 -12
- package/docs/webapi/pressKeyUp.mustache +0 -12
- package/docs/webapi/pressKeyWithKeyNormalization.mustache +0 -60
- package/docs/webapi/refreshPage.mustache +0 -6
- package/docs/webapi/resizeWindow.mustache +0 -6
- package/docs/webapi/rightClick.mustache +0 -14
- package/docs/webapi/saveElementScreenshot.mustache +0 -10
- package/docs/webapi/saveScreenshot.mustache +0 -12
- package/docs/webapi/say.mustache +0 -10
- package/docs/webapi/scrollIntoView.mustache +0 -11
- package/docs/webapi/scrollPageToBottom.mustache +0 -6
- package/docs/webapi/scrollPageToTop.mustache +0 -6
- package/docs/webapi/scrollTo.mustache +0 -12
- package/docs/webapi/see.mustache +0 -11
- package/docs/webapi/seeAttributesOnElements.mustache +0 -9
- package/docs/webapi/seeCheckboxIsChecked.mustache +0 -10
- package/docs/webapi/seeCookie.mustache +0 -8
- package/docs/webapi/seeCssPropertiesOnElements.mustache +0 -9
- package/docs/webapi/seeCurrentUrlEquals.mustache +0 -11
- package/docs/webapi/seeElement.mustache +0 -8
- package/docs/webapi/seeElementInDOM.mustache +0 -8
- package/docs/webapi/seeInCurrentUrl.mustache +0 -8
- package/docs/webapi/seeInField.mustache +0 -12
- package/docs/webapi/seeInPopup.mustache +0 -8
- package/docs/webapi/seeInSource.mustache +0 -7
- package/docs/webapi/seeInTitle.mustache +0 -8
- package/docs/webapi/seeNumberOfElements.mustache +0 -11
- package/docs/webapi/seeNumberOfVisibleElements.mustache +0 -10
- package/docs/webapi/seeTextEquals.mustache +0 -9
- package/docs/webapi/seeTitleEquals.mustache +0 -8
- package/docs/webapi/selectOption.mustache +0 -21
- package/docs/webapi/setCookie.mustache +0 -16
- package/docs/webapi/setGeoLocation.mustache +0 -12
- package/docs/webapi/switchTo.mustache +0 -9
- package/docs/webapi/switchToNextTab.mustache +0 -10
- package/docs/webapi/switchToPreviousTab.mustache +0 -10
- package/docs/webapi/type.mustache +0 -21
- package/docs/webapi/uncheckOption.mustache +0 -13
- package/docs/webapi/wait.mustache +0 -8
- package/docs/webapi/waitForClickable.mustache +0 -11
- package/docs/webapi/waitForDetached.mustache +0 -10
- package/docs/webapi/waitForElement.mustache +0 -11
- package/docs/webapi/waitForEnabled.mustache +0 -6
- package/docs/webapi/waitForFunction.mustache +0 -17
- package/docs/webapi/waitForInvisible.mustache +0 -10
- package/docs/webapi/waitForNumberOfTabs.mustache +0 -9
- package/docs/webapi/waitForText.mustache +0 -13
- package/docs/webapi/waitForValue.mustache +0 -10
- package/docs/webapi/waitForVisible.mustache +0 -10
- package/docs/webapi/waitInUrl.mustache +0 -9
- package/docs/webapi/waitNumberOfVisibleElements.mustache +0 -10
- package/docs/webapi/waitToHide.mustache +0 -10
- package/docs/webapi/waitUrlEquals.mustache +0 -10
- 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/lib/css2xpath/js/css_to_xpath.js +0 -20
- package/lib/css2xpath/js/expression.js +0 -23
- package/lib/css2xpath/js/renderer.js +0 -239
package/lib/locator.js
CHANGED
|
@@ -162,22 +162,17 @@ class Locator {
|
|
|
162
162
|
* @returns {string}
|
|
163
163
|
*/
|
|
164
164
|
toXPath(pseudoSelector = '') {
|
|
165
|
+
const locator = `${this.value}${pseudoSelector}`;
|
|
165
166
|
const limitation = [':nth-of-type', ':first-of-type', ':last-of-type', ':nth-last-child', ':nth-last-of-type', ':checked', ':disabled', ':enabled', ':required', ':lang'];
|
|
166
167
|
|
|
167
|
-
if (
|
|
168
|
-
cssToXPath = require('
|
|
169
|
-
} else if (this.value.includes('-')) {
|
|
170
|
-
if (!limitation.some(item => this.value.includes(item))) {
|
|
171
|
-
cssToXPath = require('csstoxpath');
|
|
172
|
-
}
|
|
173
|
-
} else if (limitation.some(item => this.value.includes(item))) {
|
|
174
|
-
cssToXPath = require('./css2xpath/js/css_to_xpath');
|
|
168
|
+
if (limitation.some(item => locator.includes(item))) {
|
|
169
|
+
cssToXPath = require('css-to-xpath');
|
|
175
170
|
} else {
|
|
176
|
-
cssToXPath = require('
|
|
171
|
+
cssToXPath = require('csstoxpath');
|
|
177
172
|
}
|
|
178
173
|
|
|
179
174
|
if (this.isXPath()) return this.value;
|
|
180
|
-
if (this.isCSS()) return cssToXPath(
|
|
175
|
+
if (this.isCSS()) return cssToXPath(locator);
|
|
181
176
|
|
|
182
177
|
throw new Error('Can\'t be converted to XPath');
|
|
183
178
|
}
|
|
@@ -264,7 +259,7 @@ class Locator {
|
|
|
264
259
|
*/
|
|
265
260
|
withText(text) {
|
|
266
261
|
text = xpathLocator.literal(text);
|
|
267
|
-
const xpath = this.toXPath(
|
|
262
|
+
const xpath = sprintf('%s[%s]', this.toXPath(), `contains(., ${text})`);
|
|
268
263
|
return new Locator({ xpath });
|
|
269
264
|
}
|
|
270
265
|
|
|
@@ -275,7 +270,7 @@ class Locator {
|
|
|
275
270
|
*/
|
|
276
271
|
withTextEquals(text) {
|
|
277
272
|
text = xpathLocator.literal(text);
|
|
278
|
-
const xpath = this.toXPath(
|
|
273
|
+
const xpath = sprintf('%s[%s]', this.toXPath(), `.= ${text}`);
|
|
279
274
|
return new Locator({ xpath });
|
|
280
275
|
}
|
|
281
276
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "3.5.12-beta.
|
|
3
|
+
"version": "3.5.12-beta.3",
|
|
4
4
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"acceptance",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"bin",
|
|
26
|
-
"docs",
|
|
27
26
|
"lib",
|
|
28
27
|
"translations",
|
|
29
28
|
"typings/**/*.d.ts"
|
|
@@ -75,7 +74,6 @@
|
|
|
75
74
|
"acorn": "8.11.2",
|
|
76
75
|
"arrify": "2.0.1",
|
|
77
76
|
"axios": "1.6.3",
|
|
78
|
-
"bo-selector": "0.0.10",
|
|
79
77
|
"chai": "4.3.8",
|
|
80
78
|
"chai-deep-match": "1.2.1",
|
|
81
79
|
"chai-exclude": "2.1.0",
|
|
@@ -86,6 +84,7 @@
|
|
|
86
84
|
"chalk": "4.1.2",
|
|
87
85
|
"commander": "11.1.0",
|
|
88
86
|
"cross-spawn": "7.0.3",
|
|
87
|
+
"css-to-xpath": "0.1.0",
|
|
89
88
|
"csstoxpath": "1.6.0",
|
|
90
89
|
"devtools": "8.27.2",
|
|
91
90
|
"envinfo": "7.11.0",
|
|
@@ -110,8 +109,7 @@
|
|
|
110
109
|
"promise-retry": "1.1.1",
|
|
111
110
|
"resq": "1.11.0",
|
|
112
111
|
"sprintf-js": "1.1.1",
|
|
113
|
-
"uuid": "9.0"
|
|
114
|
-
"xpath-builder": "0.0.7"
|
|
112
|
+
"uuid": "9.0"
|
|
115
113
|
},
|
|
116
114
|
"optionalDependencies": {
|
|
117
115
|
"@codeceptjs/detox-helper": "1.0.2"
|
package/docs/advanced.md
DELETED
|
@@ -1,351 +0,0 @@
|
|
|
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
|
-
|
package/docs/ai.md
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
permalink: /ai
|
|
3
|
-
title: Testing with AI 🪄
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 🪄 Testing with AI
|
|
7
|
-
|
|
8
|
-
**CodeceptJS is the first open-source test automation framework with AI** features to improve the testing experience. CodeceptJS uses OpenAI GPT to auto-heal failing tests, assist in writing tests, and more...
|
|
9
|
-
|
|
10
|
-
Think of it as your testing co-pilot built into the testing framework
|
|
11
|
-
|
|
12
|
-
> 🪄 **AI features for testing are experimental**. AI works only for web based testing with Playwright, WebDriver, etc. Those features will be improved based on user's experience.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## How AI Improves Automated Testing
|
|
16
|
-
|
|
17
|
-
ChatGPT can write automated tests for you. What you need is just ask it "How to write CodeceptJS test" and it will generate the code that can be executed but not the actual code you need. ChatGPT misses the context, of your application.
|
|
18
|
-
|
|
19
|
-
CodeceptJS uses OpenAI API to send the prompt and share the HTML context of a page. So, it can ask: how to write a test for **this** page. GPT model knows how to write CodeceptJS code, how to build good-looking semantic locators and how to analyze HTML to match them. Even more, GPT suggestions can be tested in real-time in a browser, making a feedback loop.
|
|
20
|
-
|
|
21
|
-
CodeceptJS AI can do the following:
|
|
22
|
-
|
|
23
|
-
* 🏋️♀️ **assist writing tests** in `pause()` or interactive shell mode
|
|
24
|
-
* 🚑 **self-heal failing tests** (can be used on CI)
|
|
25
|
-
* 💬 send arbitrary prompts to GPT from any tested page attaching its HTML contents
|
|
26
|
-
|
|
27
|
-

|
|
28
|
-
|
|
29
|
-
### How it works
|
|
30
|
-
|
|
31
|
-
As we can't send a browser window with ChatGPT we are not be able to fully share the context. As only text information is accepted, we can send HTML of the currently tested page. GPT doesn't know what elements are hidden, or what elements are visible. It can operate only on the HTML provided.
|
|
32
|
-
|
|
33
|
-
GPT models have limits on information passed, and HTML pages can be huge. And some information may be irrelevant for testing. For instance, if you test a reading application, you won't probably need text contents of a book inside your HTML, as they won't be used in locators. That's why CodeceptJS send HTML with **all non-interactive HTML elements removed**. So, only links, buttons, fields, and all elements that are set as a link, button, etc will be used by GPT for analysis. In case you have clickable `<div>` but with no `role="button"` it will be ignored. Also, we minify HTML before sending.
|
|
34
|
-
|
|
35
|
-
Even though, the HTML is still quite big and may exceed the token limit. So we recommend using **gpt-3.5-turbo-16k** model, as it accepts 16K tokens (approx. 50K of HTML text), which should be enough for most web pages. It is possible to strictly limit the size of HTML to not exceed GPT tokens limit.
|
|
36
|
-
|
|
37
|
-
> ❗AI features require sending HTML contents to OpenAI. If you use it in enterprise, ensure that your company requirements match [OpenAI complience](https://openai.com/security). If you work on public web applications this should be ok, as HTML code is genrally available to all web application users.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
### Getting Started
|
|
41
|
-
|
|
42
|
-
[Install CodeceptJS 3.5](/installation):
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
npx create-codeceptjs .
|
|
46
|
-
```
|
|
47
|
-
[Obtain API token](https://platform.openai.com/account/api-keys) from OpenAI. Please check out [their pricing](https://openai.com/pricing) first, as unlike ChatGPT using OpenAI API requires a paid account.
|
|
48
|
-
|
|
49
|
-
Add `OPENAI_API_KEY` environment variable with a key when running codeceptjs:
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
OPENAI_API_KEY=sk-******** npx codeceptjs run
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
This will enable AI features in CodeceptJS.
|
|
56
|
-
|
|
57
|
-
> When running on CI set `OPENAI_API_KEY` as a secured environment variable
|
|
58
|
-
|
|
59
|
-
### Writing Tests with AI Copilot
|
|
60
|
-
|
|
61
|
-
If AI features are enabled when using [interactive pause](/basics/#debug) with `pause()` command inside tests:
|
|
62
|
-
|
|
63
|
-
For instance, let's create a test to try ai features via `gt` command:
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
npx codeceptjs gt
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Name a test and write the code. We will use `Scenario.only` instead of Scenario to execute only this exact test.
|
|
70
|
-
|
|
71
|
-
```js
|
|
72
|
-
Feature('ai');
|
|
73
|
-
|
|
74
|
-
Scenario.only('test ai features', ({ I }) => {
|
|
75
|
-
I.amOnPage('https://getbootstrap.com/docs/5.1/examples/checkout/')
|
|
76
|
-
pause();
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Now run the test in debug mode:
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
OPENAI_API_KEY=sk-******** npx codeceptjs run --debug
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
When pause mode started you can ask GPT to fill in the fields on this page. Use natural language to describe your request, and provide enough details that AI could operate with it. It is important to include at least a space char in your input, otherwise, CodeceptJS will consider the input to be JavaScript code.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```
|
|
90
|
-
I.fill checkout form with valid values without submitting it
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-

|
|
94
|
-
|
|
95
|
-
GPT will generate code and data and CodeceptJS will try to execute its code. If it succeeds, the code will be saved to history and you will be able to copy it to your test.
|
|
96
|
-
|
|
97
|
-

|
|
98
|
-
|
|
99
|
-
This AI copilot works best with long static forms. In the case of complex and dynamic single-page applications, it may not perform as well, as the form may not be present on HTML page yet. For instance, interacting with calendars or inputs with real-time validations (like credit cards) can not yet be performed by AI.
|
|
100
|
-
|
|
101
|
-
Please keep in mind that GPT can't react to page changes and operates with static text only. This is why it is not ready yet to write the test completely. However, if you are new to CodeceptJS and automated testing AI copilot may help you write tests more efficiently.
|
|
102
|
-
|
|
103
|
-
> 👶 Enable AI copilot for junior test automation engineers. It may help them to get started with CodeceptJS and to write good semantic locators.
|
|
104
|
-
|
|
105
|
-
### Self-Healing Tests
|
|
106
|
-
|
|
107
|
-
In large test suites, the cost of maintaining tests goes exponentially. That's why any effort that can improve the stability of tests pays itself. In CodeceptJS 3.5 we introduced a new [heal plugin](/plugins#heal) that will use AI to automatically fix a failing test.
|
|
108
|
-
|
|
109
|
-
Heal plugin can solve exactly one problem: if a locator of an element has changed, and an action can't be performed, **it matches a new locator, tries a command again, and continues executing a test**. For instance, if the "Sign in" button was renamed to "Login" or changed its class, it will detect a new locator of the button and will retry execution.
|
|
110
|
-
|
|
111
|
-
Heal actions **work only on actions like `click`, `fillField`**, etc, and won't work on assertions, waiters, grabbers, etc. Assertions can't be guessed by AI, the same way as grabbers, as this may lead to unpredictable results.
|
|
112
|
-
|
|
113
|
-
If Heal plugin successfully fixes the step, it will print a suggested change at the end of execution. Take it as actionable advice and use it to update the codebase. Heal plugin is supposed to be used on CI, and works automatically without human assistance.
|
|
114
|
-
|
|
115
|
-
To start, enable `heal` plugin in `codecept.conf.js` or `codecept.conf.ts`:
|
|
116
|
-
|
|
117
|
-
```js
|
|
118
|
-
plugins: {
|
|
119
|
-
heal: {
|
|
120
|
-
enabled: true
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
and run tests in AI mode with `OPENAI_API_KEY` provided:
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
OPENAI_API_KEY=sk-******** npx codeceptjs run
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-

|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### Arbitrary GPT Prompts
|
|
135
|
-
|
|
136
|
-
What if you want to take ChatGPT on the journey of test automation and ask it questions while browsing pages?
|
|
137
|
-
|
|
138
|
-
This is possible with the new `OpenAI` helper. Enable it in your config and it will automatically attach to Playwright, WebDriver, or another web helper you use. It includes the following methods:
|
|
139
|
-
|
|
140
|
-
* `askGptOnPage` - sends GPT prompt attaching the HTML of the page. Large pages will be split into chunks, according to `chunkSize` config. You will receive responses for all chunks.
|
|
141
|
-
* `askGptOnPageFragment` - sends GPT prompt attaching the HTML of the specific element. This method is recommended over `askGptOnPage` as you can reduce the amount of data to be processed.
|
|
142
|
-
* `askGptGeneralPrompt` - sends GPT prompt without HTML.
|
|
143
|
-
|
|
144
|
-
OpenAI helper won't remove non-interactive elements, so it is recommended to manually control the size of the sent HTML.
|
|
145
|
-
|
|
146
|
-
Here are some good use cases for this helper:
|
|
147
|
-
|
|
148
|
-
* get page summaries
|
|
149
|
-
* inside pause mode navigate through your application and ask to document pages
|
|
150
|
-
* etc...
|
|
151
|
-
|
|
152
|
-
```js
|
|
153
|
-
// use it inside test or inside interactive pause
|
|
154
|
-
// pretend you are technical writer asking for documentation
|
|
155
|
-
const pageDoc = await I.askGptOnPageFragment('Act as technical writer, describe what is this page for', '#container');
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
As of now, those use cases do not apply to test automation but maybe you can apply them to your testing setup.
|
|
159
|
-
|
|
160
|
-
## Configuration
|
|
161
|
-
|
|
162
|
-
AI features can be configured inside `codecept.conf` file under `ai` section:
|
|
163
|
-
|
|
164
|
-
```js
|
|
165
|
-
ai: {
|
|
166
|
-
model: 'gpt-3.5-turbo-16k',
|
|
167
|
-
temperature: 0.1,
|
|
168
|
-
html: // {}
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Available options are:
|
|
173
|
-
|
|
174
|
-
* `model` - [OpenAI model](https://platform.openai.com/docs/models), `gpt-3.5-turbo-16k` is recommended. You may switch to another GPT model, however, consider the speed of processing and size of the input. Models with less than 16K tokens won't be able to process complete HTML even reduced to interactive elements.
|
|
175
|
-
* `temperature` - [temperature](https://platform.openai.com/docs/api-reference/chat/create#chat/create-temperature) is a measure of randomness. Use the lowest value possible for test automation purposes.
|
|
176
|
-
* `html` - configures how HTML is processed before sending it to GPT. This section is highly important to tune to adapt to your application. For instance, the default strategy may remove some important elements, or contrary keep some elements that have no practical usage in test automation.
|
|
177
|
-
|
|
178
|
-
Here is the default config:
|
|
179
|
-
|
|
180
|
-
```js
|
|
181
|
-
ai: {
|
|
182
|
-
html: {
|
|
183
|
-
maxLength: 50000,
|
|
184
|
-
simplify: true,
|
|
185
|
-
minify: true,
|
|
186
|
-
interactiveElements: ['a', 'input', 'button', 'select', 'textarea', 'option'],
|
|
187
|
-
textElements: ['label', 'h1', 'h2'],
|
|
188
|
-
allowedAttrs: ['id', 'for', 'class', 'name', 'type', 'value', 'tabindex', 'aria-labelledby', 'aria-label', 'label', 'placeholder', 'title', 'alt', 'src', 'role'],
|
|
189
|
-
allowedRoles: ['button', 'checkbox', 'search', 'textbox', 'tab'],
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
* `maxLength`: the size of HTML to cut to not reach the token limit. 50K is the current default but you may try to increase it or even set it to null.
|
|
195
|
-
* `simplify`: should we process HTML before sending to GPT. This will remove all non-interactive elements from HTML.
|
|
196
|
-
* `minify`: shold HTML be additionally minified. This removed empty attributes, shortens notations, etc.
|
|
197
|
-
* `interactiveElements`: explicit list of all elements that are considered interactive.
|
|
198
|
-
* `textElements`: elements that contain text which can be used for test automation.
|
|
199
|
-
* `allowedAttrs`: explicit list of attributes that may be used to construct locators. If you use special `data-` attributes to enable locators, add them to the list.
|
|
200
|
-
* `allowedRoles`: list of roles that make standard elements interactive.
|
|
201
|
-
|
|
202
|
-
It is recommended to try HTML processing on one of your web pages before launching AI features of CodeceptJS.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
To do that open the common page of your application and using DevTools copy the outerHTML of `<html>` element. Don't use `Page Source` for that, as it may not include dynamically added HTML elements. Save this HTML into a file and create a NodeJS script:
|
|
206
|
-
|
|
207
|
-
```js
|
|
208
|
-
const { removeNonInteractiveElements } = require('codeceptjs/lib/html');
|
|
209
|
-
const fs = require('fs');
|
|
210
|
-
|
|
211
|
-
const htmlOpts = {
|
|
212
|
-
interactiveElements: ['a', 'input', 'button', 'select', 'textarea', 'label', 'option'],
|
|
213
|
-
allowedAttrs: ['id', 'for', 'class', 'name', 'type', 'value', 'aria-labelledby', 'aria-label', 'label', 'placeholder', 'title', 'alt', 'src', 'role'],
|
|
214
|
-
textElements: ['label', 'h1', 'h2'],
|
|
215
|
-
allowedRoles: ['button', 'checkbox', 'search', 'textbox', 'tab'],
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
html = fs.readFileSync('saved.html', 'utf8');
|
|
219
|
-
const result = removeNonInteractiveElements(html, htmlOpts);
|
|
220
|
-
|
|
221
|
-
console.log(result);
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
Tune the options until you are satisfied with the results and use this as `html` config for `ai` section inside `codecept.conf` file.
|
|
225
|
-
It is also recommended to check the source of [removeNonInteractiveElements](https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/html.js) and if needed propose improvements to it.
|
|
226
|
-
|
|
227
|
-
For instance, if you use `data-qa` attributes to specify locators and you want to include them in HTML, use the following config:
|
|
228
|
-
|
|
229
|
-
```js
|
|
230
|
-
{
|
|
231
|
-
// inside codecept.conf.js
|
|
232
|
-
ai: {
|
|
233
|
-
html: {
|
|
234
|
-
allowedAttrs: [
|
|
235
|
-
'data-qa', 'id', 'for', 'class', 'name', 'type', 'value', 'aria-labelledby', 'aria-label', 'label', 'placeholder', 'title', 'alt', 'src', 'role'
|
|
236
|
-
]
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## Debugging
|
|
243
|
-
|
|
244
|
-
To debug AI features run tests with `DEBUG="codeceptjs:ai"` flag. This will print all prompts and responses from OpenAI
|
|
245
|
-
|
|
246
|
-
```
|
|
247
|
-
DEBUG="codeceptjs:ai" OPENAI_API_KEY=sk-******** npx codeceptjs run
|
|
248
|
-
```
|