codeceptjs 2.4.3 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -0
- package/README.md +32 -7
- package/bin/codecept.js +3 -0
- package/docs/basics.md +11 -5
- package/docs/bdd.md +4 -4
- package/docs/build/MockRequest.js +3 -0
- package/docs/build/Nightmare.js +10 -2
- package/docs/build/Playwright.js +3187 -0
- package/docs/build/Protractor.js +16 -2
- package/docs/build/Puppeteer.js +126 -19
- package/docs/build/REST.js +3 -1
- package/docs/build/TestCafe.js +11 -3
- package/docs/build/WebDriver.js +361 -28
- package/docs/changelog.md +116 -0
- package/docs/configuration.md +2 -2
- package/docs/custom-helpers.md +55 -10
- package/docs/helpers/Appium.md +81 -1
- package/docs/helpers/MockRequest.md +281 -38
- package/docs/helpers/Nightmare.md +10 -2
- package/docs/helpers/Playwright.md +1770 -0
- package/docs/helpers/Protractor.md +15 -3
- package/docs/helpers/Puppeteer-firefox.md +32 -1
- package/docs/helpers/Puppeteer.md +126 -76
- package/docs/helpers/TestCafe.md +10 -2
- package/docs/helpers/WebDriver.md +208 -118
- package/docs/locators.md +2 -0
- package/docs/playwright.md +306 -0
- package/docs/plugins.md +103 -0
- package/docs/reports.md +12 -0
- package/docs/shadow.md +68 -0
- package/docs/visual.md +0 -73
- package/docs/webapi/forceClick.mustache +27 -0
- package/docs/webapi/seeInPopup.mustache +7 -0
- package/docs/webapi/setCookie.mustache +10 -2
- package/docs/webapi/type.mustache +12 -0
- package/docs/webdriver.md +7 -3
- package/lib/codecept.js +1 -1
- package/lib/command/definitions.js +2 -2
- package/lib/command/generate.js +4 -4
- package/lib/command/gherkin/snippets.js +4 -4
- package/lib/command/init.js +1 -1
- package/lib/command/interactive.js +3 -0
- package/lib/command/run-multiple.js +2 -2
- package/lib/command/run-rerun.js +2 -0
- package/lib/command/run-workers.js +22 -8
- package/lib/command/run.js +2 -0
- package/lib/command/workers/runTests.js +1 -0
- package/lib/container.js +1 -1
- package/lib/event.js +2 -0
- package/lib/helper/MockRequest.js +3 -0
- package/lib/helper/Playwright.js +2422 -0
- package/lib/helper/Protractor.js +1 -2
- package/lib/helper/Puppeteer.js +84 -19
- package/lib/helper/REST.js +3 -1
- package/lib/helper/TestCafe.js +1 -1
- package/lib/helper/WebDriver.js +313 -26
- package/lib/helper/extras/PlaywrightPropEngine.js +53 -0
- package/lib/helper/scripts/isElementClickable.js +54 -14
- package/lib/interfaces/gherkin.js +1 -1
- package/lib/listener/helpers.js +3 -0
- package/lib/locator.js +5 -0
- package/lib/mochaFactory.js +12 -10
- package/lib/plugin/allure.js +8 -1
- package/lib/plugin/autoDelay.js +1 -8
- package/lib/plugin/commentStep.js +133 -0
- package/lib/plugin/screenshotOnFail.js +3 -10
- package/lib/plugin/selenoid.js +2 -2
- package/lib/plugin/standardActingHelpers.js +13 -0
- package/lib/plugin/stepByStepReport.js +1 -8
- package/lib/plugin/wdio.js +10 -1
- package/lib/reporter/cli.js +30 -1
- package/lib/session.js +7 -4
- package/package.json +13 -10
- package/typings/Mocha.d.ts +567 -16
- package/typings/index.d.ts +9 -5
- package/typings/types.d.ts +1634 -74
package/docs/locators.md
CHANGED
|
@@ -12,6 +12,8 @@ CodeceptJS provides flexible strategies for locating elements:
|
|
|
12
12
|
* [Locator Builder](#locator-builder)
|
|
13
13
|
* [ID locators](#id-locators): by CSS id or by accessibility id
|
|
14
14
|
* [Custom Locator Strategies](#custom-locators): by data attributes or whatever you prefer.
|
|
15
|
+
* [Shadow DOM](/shadow): to access shadow dom elements
|
|
16
|
+
* [React](/react): to access React elements by component names and props
|
|
15
17
|
|
|
16
18
|
Most methods in CodeceptJS use locators which can be either a string or an object.
|
|
17
19
|
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /playwright
|
|
3
|
+
title: Testing with Playwright
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Testing with Playwright <Badge text="Since 2.5" type="warning"/>
|
|
7
|
+
|
|
8
|
+
Playwright is a Node library to automate the [Chromium](https://www.chromium.org/Home), [WebKit](https://webkit.org/) and [Firefox](https://www.mozilla.org/en-US/firefox/new/) browsers with a single API. It enables **cross-browser** web automation that is **ever-green**, **capable**, **reliable** and **fast**.
|
|
9
|
+
|
|
10
|
+
Playwright was built similarly to [Puppeteer](https://github.com/puppeteer/puppeteer), using its API and so is very different in usage. However, Playwright has cross browser support with better design for test automaiton.
|
|
11
|
+
|
|
12
|
+
Take a look at a sample test:
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
I.amOnPage('https://github.com');
|
|
16
|
+
I.click('Sign in', '//html/body/div[1]/header');
|
|
17
|
+
I.see('Sign in to GitHub', 'h1');
|
|
18
|
+
I.fillField('Username or email address', 'something@totest.com');
|
|
19
|
+
I.fillField('Password', '123456');
|
|
20
|
+
I.click('Sign in');
|
|
21
|
+
I.see('Incorrect username or password.', '.flash-error');
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
It's readable and simple and working using Playwright API!
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
To start you need CodeceptJS with Playwright packages installed
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install codeceptjs playwright@^0.12.1 --save
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or see [alternative installation options](http://codecept.io/installation/)
|
|
35
|
+
|
|
36
|
+
> If you already have CodeceptJS project, just install `playwright` package and enable a helper it in config.
|
|
37
|
+
|
|
38
|
+
And a basic project initialized
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
npx codeceptjs init
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
You will be asked for a Helper to use, you should select Playwright and provide url of a website you are testing.
|
|
45
|
+
|
|
46
|
+
## Configuring
|
|
47
|
+
|
|
48
|
+
Make sure `Playwright` helper is enabled in `codecept.conf.js` config:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
{ // ..
|
|
52
|
+
helpers: {
|
|
53
|
+
Playwright: {
|
|
54
|
+
url: "http://localhost",
|
|
55
|
+
show: true,
|
|
56
|
+
browser: 'chromium'
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// ..
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> Turn off the `show` option if you want to run test in headless mode.
|
|
64
|
+
> If you don't specify the browser here, `chromium` will be used. Possible browsers are: `chromium`, `firefox` and `webkit`
|
|
65
|
+
|
|
66
|
+
Playwright uses different strategies to detect if a page is loaded. In configuration use `waitForNavigation` option for that:
|
|
67
|
+
|
|
68
|
+
When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either:
|
|
69
|
+
- `load` - consider navigation to be finished when the load event is fired.
|
|
70
|
+
- `domcontentloaded` - consider navigation to be finished when the DOMContentLoaded event is fired.
|
|
71
|
+
- `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least 500 ms.
|
|
72
|
+
- `networkidle2` - consider navigation to be finished when there are no more than 2 network connections for at least 500 ms.
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
helpers: {
|
|
76
|
+
Playwright: {
|
|
77
|
+
url: "http://localhost",
|
|
78
|
+
show: true,
|
|
79
|
+
browser: 'chromium',
|
|
80
|
+
waitForNavigation: "networkidle0"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
When a test runs faster than application it is recommended to increase `waitForAction` config value.
|
|
86
|
+
It will wait for a small amount of time (100ms) by default after each user action is taken.
|
|
87
|
+
|
|
88
|
+
> ▶ More options are listed in [helper reference](http://codecept.io/helpers/Playwright/).
|
|
89
|
+
|
|
90
|
+
## Writing Tests
|
|
91
|
+
|
|
92
|
+
Additional CodeceptJS tests should be created with `gt` command:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
npx codeceptjs gt
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
As an example we will use `ToDoMvc` app for testing.
|
|
99
|
+
|
|
100
|
+
### Actions
|
|
101
|
+
|
|
102
|
+
Tests consist with a scenario of user's action taken on a page. The most widely used ones are:
|
|
103
|
+
|
|
104
|
+
* `amOnPage` - to open a webpage (accepts relative or absolute url)
|
|
105
|
+
* `click` - to locate a button or link and click on it
|
|
106
|
+
* `fillField` - to enter a text inside a field
|
|
107
|
+
* `selectOption`, `checkOption` - to interact with a form
|
|
108
|
+
* `wait*` to wait for some parts of page to be fully rendered (important for testing SPA)
|
|
109
|
+
* `grab*` to get values from page sources
|
|
110
|
+
* `see`, `dontSee` - to check for a text on a page
|
|
111
|
+
* `seeElement`, `dontSeeElement` - to check for elements on a page
|
|
112
|
+
|
|
113
|
+
> ℹ All actions are listed in [Playwright helper reference](http://codecept.io/helpers/Playwright/).*
|
|
114
|
+
|
|
115
|
+
All actions which interact with elements can use **[CSS or XPath locators](https://codecept.io/locators/#css-and-xpath)**. Actions like `click` or `fillField` can locate elements by their name or value on a page:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
// search for link or button
|
|
119
|
+
I.click('Login');
|
|
120
|
+
// locate field by its label
|
|
121
|
+
I.fillField('Name', 'Miles');
|
|
122
|
+
// we can use input name
|
|
123
|
+
I.fillField('user[email]','miles@davis.com');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
You can also specify the exact locator type with strict locators:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
I.click({css: 'button.red'});
|
|
130
|
+
I.fillField({name: 'user[email]'},'miles@davis.com');
|
|
131
|
+
I.seeElement({xpath: '//body/header'});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Interactive Pause
|
|
135
|
+
|
|
136
|
+
It's easy to start writing a test if you use [interactive pause](/basics#debug). Just open a web page and pause execution.
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
Feature('Sample Test');
|
|
140
|
+
|
|
141
|
+
Scenario('open my website', (I) => {
|
|
142
|
+
I.amOnPage('http://todomvc.com/examples/react/');
|
|
143
|
+
pause();
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
This is just enough to run a test, open a browser, and think what to do next to write a test case.
|
|
148
|
+
|
|
149
|
+
When you execute such test with `codeceptjs run` command you may see the browser is started
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
npx codeceptjs run --steps
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
After a page is opened a full control of a browser is given to a terminal. Type in different commands such as `click`, `see`, `fillField` to write the test. A successful commands will be saved to `./output/cli-history` file and can be copied into a test.
|
|
156
|
+
|
|
157
|
+
A complete ToDo-MVC test may look like:
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
Feature('ToDo');
|
|
161
|
+
|
|
162
|
+
Scenario('create todo item', (I) => {
|
|
163
|
+
I.amOnPage('http://todomvc.com/examples/react/');
|
|
164
|
+
I.dontSeeElement('.todo-count');
|
|
165
|
+
I.fillField('What needs to be done?', 'Write a guide');
|
|
166
|
+
I.pressKey('Enter');
|
|
167
|
+
I.see('Write a guide', '.todo-list');
|
|
168
|
+
I.see('1 item left', '.todo-count');
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Grabbers
|
|
173
|
+
|
|
174
|
+
If you need to get element's value inside a test you can use `grab*` methods. They should be used with `await` operator inside `async` function:
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
const assert = require('assert');
|
|
178
|
+
Scenario('get value of current tasks', async (I) => {
|
|
179
|
+
I.createTodo('do 1');
|
|
180
|
+
I.createTodo('do 2');
|
|
181
|
+
let numTodos = await I.grabTextFrom('.todo-count strong');
|
|
182
|
+
assert.equal(2, numTodos);
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Within
|
|
187
|
+
|
|
188
|
+
In case some actions should be taken inside one element (a container or modal window or iframe) you can use `within` block to narrow the scope.
|
|
189
|
+
Please take a note that you can't use within inside another within in Playwright helper:
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
within('.todoapp', () => {
|
|
193
|
+
I.createTodo('my new item');
|
|
194
|
+
I.see('1 item left', '.todo-count');
|
|
195
|
+
I.click('.todo-list input.toggle');
|
|
196
|
+
});
|
|
197
|
+
I.see('0 items left', '.todo-count');
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
> [▶ Learn more about basic commands](/basics#writing-tests)
|
|
201
|
+
|
|
202
|
+
CodeceptJS allows you to implement custom actions like `I.createTodo` or use **PageObjects**. Learn how to improve your tests in [PageObjects](http://codecept.io/pageobjects/) guide.
|
|
203
|
+
|
|
204
|
+
## Multi Session Testing
|
|
205
|
+
|
|
206
|
+
TO launch additional browser context (or incognito window) use `session` command.
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
Scenario('I try to open this site as anonymous user', () => {
|
|
210
|
+
I.amOnPage('/');
|
|
211
|
+
I.dontSee('Agree to cookies');
|
|
212
|
+
session('anonymous user', () => {
|
|
213
|
+
I.amOnPage('/');
|
|
214
|
+
I.see('Agree to cookies');
|
|
215
|
+
});
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
> ℹ Learn more about [multi-session testing](/basics/#multiple-sessions)
|
|
220
|
+
|
|
221
|
+
## Device Emulation
|
|
222
|
+
|
|
223
|
+
Playwright can emulate browsers of mobile devices. Instead of paying for expensive devices for mobile tests you can adjust Playwright settings so it could emulate mobile browsers on iPhone, Samsung Galaxy, etc.
|
|
224
|
+
|
|
225
|
+
Device emulation can be enabled in CodeceptJS globally in a config or per session.
|
|
226
|
+
|
|
227
|
+
Playwright contains a [list of predefined devices](https://github.com/Microsoft/playwright/blob/master/src/deviceDescriptors.ts) to emulate, for instance this is how you can enable iPhone 6 emulation for all tests:
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
const { devices } = require('playwright');
|
|
231
|
+
|
|
232
|
+
helpers: {
|
|
233
|
+
Playwright: {
|
|
234
|
+
// regular config goes here
|
|
235
|
+
emulate: devices['iPhone 6'],
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
To adjust browser settings you can pass [custom options](https://github.com/microsoft/playwright/blob/v0.12.1/docs/api.md#browsernewcontextoptions)
|
|
240
|
+
|
|
241
|
+
```js
|
|
242
|
+
helpers: {
|
|
243
|
+
Playwright: {
|
|
244
|
+
// regular config goes here
|
|
245
|
+
// put on mobile device
|
|
246
|
+
emulate: { isMobile: true, deviceScaleFactor: 2 }
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
To enable device emulation for a specific test, create an additional browser session and pass in config as a second parameter:
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
const { devices } = require('playwright');
|
|
255
|
+
|
|
256
|
+
Scenario('website looks nice on iPhone', () => {
|
|
257
|
+
session('mobile user', devices['iPhone 6'], () => {
|
|
258
|
+
I.amOnPage('/');
|
|
259
|
+
I.see('Hello, iPhone user!')
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Extending
|
|
265
|
+
|
|
266
|
+
Playwright has a very [rich and flexible API](https://github.com/microsoft/playwright/blob/v0.12.1/docs/api.md). Sure, you can extend your test suites to use the methods listed there. CodeceptJS already prepares some objects for you and you can use them from your you helpers.
|
|
267
|
+
|
|
268
|
+
Start with creating an `MyPlaywright` helper using `generate:helper` or `gh` command:
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
npx codeceptjs gh
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Then inside a Helper you can access `Playwright` helper of CodeceptJS.
|
|
275
|
+
Let's say you want to create `I.grabDimensionsOfCurrentPage` action. In this case you need to call `evaluate` method of `page` object
|
|
276
|
+
|
|
277
|
+
```js
|
|
278
|
+
// inside a MyPlaywright helper
|
|
279
|
+
async grabDimensionsOfCurrentPage() {
|
|
280
|
+
const { page } = this.helpers.Playwright;
|
|
281
|
+
await page.goto('https://www.example.com/');
|
|
282
|
+
return page.evaluate(() => {
|
|
283
|
+
return {
|
|
284
|
+
width: document.documentElement.clientWidth,
|
|
285
|
+
height: document.documentElement.clientHeight,
|
|
286
|
+
deviceScaleFactor: window.devicePixelRatio
|
|
287
|
+
}
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
The same way you can also access `browser` object to implement more actions or handle events. For instance, you want to set the permissions, you can approach it with:
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
// inside a MyPlaywright helper
|
|
296
|
+
async setPermissions() {
|
|
297
|
+
const { browser } = this.helpers.Playwright;
|
|
298
|
+
const context = browser.defaultContext()
|
|
299
|
+
return context.setPermissions('https://html5demos.com', ['geolocation']);
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
> [▶ Learn more about BrowserContext](https://github.com/microsoft/playwright/blob/v0.12.1/docs/api.md#class-browsercontext)
|
|
304
|
+
|
|
305
|
+
> [▶ Learn more about Helpers](http://codecept.io/helpers/)
|
|
306
|
+
|
package/docs/plugins.md
CHANGED
|
@@ -305,6 +305,109 @@ Scenario('login', async (I, login) => {
|
|
|
305
305
|
|
|
306
306
|
- `config`
|
|
307
307
|
|
|
308
|
+
## commentStep
|
|
309
|
+
|
|
310
|
+
Add descriptive nested steps for your tests:
|
|
311
|
+
|
|
312
|
+
```js
|
|
313
|
+
Scenario('project update test', async (I) => {
|
|
314
|
+
__`Given`;
|
|
315
|
+
const projectId = await I.have('project');
|
|
316
|
+
|
|
317
|
+
__`When`;
|
|
318
|
+
projectPage.update(projectId, { title: 'new title' });
|
|
319
|
+
|
|
320
|
+
__`Then`;
|
|
321
|
+
projectPage.open(projectId);
|
|
322
|
+
I.see('new title', 'h1');
|
|
323
|
+
})
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Steps prefixed with `__` will be printed as nested steps in `--steps` output:
|
|
327
|
+
|
|
328
|
+
Given
|
|
329
|
+
I have "project"
|
|
330
|
+
When
|
|
331
|
+
projectPage update
|
|
332
|
+
Then
|
|
333
|
+
projectPage open
|
|
334
|
+
I see "new title", "h1"
|
|
335
|
+
|
|
336
|
+
Also those steps will be exported to allure reports.
|
|
337
|
+
|
|
338
|
+
This plugin can be used
|
|
339
|
+
|
|
340
|
+
### Config
|
|
341
|
+
|
|
342
|
+
- `enabled` - (default: false) enable a plugin
|
|
343
|
+
- `regusterGlobal` - (default: false) register `__` template literal function globally. You can override function global name by providing a name as a value.
|
|
344
|
+
|
|
345
|
+
### Examples
|
|
346
|
+
|
|
347
|
+
Registering `__` globally:
|
|
348
|
+
|
|
349
|
+
```js
|
|
350
|
+
plugins: {
|
|
351
|
+
commentStep: {
|
|
352
|
+
enabled: true,
|
|
353
|
+
registerGlobal: true
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Registering `Step` globally:
|
|
359
|
+
|
|
360
|
+
```js
|
|
361
|
+
plugins: {
|
|
362
|
+
commentStep: {
|
|
363
|
+
enabled: true,
|
|
364
|
+
registerGlobal: 'Step'
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Using only local function names:
|
|
370
|
+
|
|
371
|
+
```js
|
|
372
|
+
plugins: {
|
|
373
|
+
commentStep: {
|
|
374
|
+
enabled: true
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Then inside a test import a comment function from a plugin.
|
|
380
|
+
For instance, you can prepare Given/When/Then functions to use them inside tests:
|
|
381
|
+
|
|
382
|
+
```js
|
|
383
|
+
// inside a test
|
|
384
|
+
const step = codeceptjs.container.plugins('commentStep');
|
|
385
|
+
|
|
386
|
+
const Given = () => step`Given`;
|
|
387
|
+
const When = () => step`When`;
|
|
388
|
+
const Then = () => step`Then`;
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Scenario('project update test', async (I) => {
|
|
392
|
+
Given();
|
|
393
|
+
const projectId = await I.have('project');
|
|
394
|
+
|
|
395
|
+
When();
|
|
396
|
+
projectPage.update(projectId, { title: 'new title' });
|
|
397
|
+
|
|
398
|
+
Then();
|
|
399
|
+
projectPage.open(projectId);
|
|
400
|
+
I.see('new title', 'h1');
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Parameters
|
|
408
|
+
|
|
409
|
+
- `config`
|
|
410
|
+
|
|
308
411
|
## customLocator
|
|
309
412
|
|
|
310
413
|
Creates a [custom locator][3] by using special attributes in HTML.
|
package/docs/reports.md
CHANGED
|
@@ -199,6 +199,18 @@ Allure reports can also be generated for `dry-run` command. So you can get the f
|
|
|
199
199
|
npx codeceptjs dry-run --debug -p allure
|
|
200
200
|
```
|
|
201
201
|
|
|
202
|
+
## ReportPortal
|
|
203
|
+
|
|
204
|
+
Allure is a great reportin tool, however, if you are running tests on different machines it is hard to merge its XML result files to build a proper report. So, for enterprise grade reporting we recommend using [ReportPortal](https://reportportal.io).
|
|
205
|
+
|
|
206
|
+

|
|
207
|
+
|
|
208
|
+
[ReportPortal](https://reportportal.io) is open-source self-hosted service for aggregating test execution reports.
|
|
209
|
+
Think of it as Kibana but for test reports.
|
|
210
|
+
|
|
211
|
+
Use official [CodeceptJS Agent for ReportPortal](https://github.com/reportportal/agent-js-codecept/) to start publishing your test results.
|
|
212
|
+
|
|
213
|
+
|
|
202
214
|
## XML
|
|
203
215
|
|
|
204
216
|
Use default xunit reporter of Mocha to print xml reports. Provide `--reporter xunit` to get the report to screen.
|
package/docs/shadow.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /shadow
|
|
3
|
+
title: Locating Shadow Dom Elements
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Locating Shadow Dom Elements
|
|
7
|
+
|
|
8
|
+
> ℹ Shadow DOM locators is supported only in WebDriver helper
|
|
9
|
+
|
|
10
|
+
Shadow DOM is one of the key browser features that make up web components. Web components are a really great way to build reusable elements, and are able to scale all the way up to complete web applications. Style encapsulation, the feature that gives shadow DOM it's power, has been a bit of a pain when it comes to E2E or UI testing. Things just got a little easier though, as CodeceptJS introduced built-in support for shadow DOM via locators of type `shadow`. Let's dig into what they're all about.
|
|
11
|
+
|
|
12
|
+
Generated HTML code may often look like this (ref: [Salesforce's Lighting Web Components](https://github.com/salesforce/lwc)):
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
<body>
|
|
16
|
+
<my-app>
|
|
17
|
+
<recipe-hello>
|
|
18
|
+
<button>Click Me!</button>
|
|
19
|
+
</recipe-hello>
|
|
20
|
+
<recipe-hello-binding>
|
|
21
|
+
<ui-input>
|
|
22
|
+
<input type="text" class="input">
|
|
23
|
+
</ui-input>
|
|
24
|
+
</recipe-hello-binding>
|
|
25
|
+
</my-app>
|
|
26
|
+
</body>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This uses custom elements, `my-app`, `recipe-hello`, `recipe-hello-binding` and `ui-input`. It's quite common that clickable elements are not actual `a` or `button` elements but custom elements. This way `I.click('Click Me!');` won't work, as well as `fillField('.input', 'value)`. Finding a correct locator for such cases turns to be almost impossible until `shadow` element support is added to CodeceptJS.
|
|
30
|
+
|
|
31
|
+
## Locate Shadow Dom
|
|
32
|
+
|
|
33
|
+
For Web Components or [Salesforce's Lighting Web Components](https://github.com/salesforce/lwc) with Shadow DOM's, a special `shadow` locator is available. It allows to select an element by its shadow dom sequences and sequences are defined as an Array of `elements`. Elements defined in the array of `elements` must be in the ordered the shadow elements appear in the DOM.
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
{ shadow: ['my-app', 'recipe-hello', 'button'] }
|
|
37
|
+
{ shadow: ['my-app', 'recipe-hello-binding', 'ui-input', 'input.input'] }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
In WebDriver, you can use shadow locators in any method where locator is required.
|
|
41
|
+
|
|
42
|
+
For example, to fill value in `input` field or to click the `Click Me!` button, in above HTML code:
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
I.fillField({ shadow: ['my-app', 'recipe-hello-binding', 'ui-input', 'input.input'] }, 'value');
|
|
46
|
+
I.click({ shadow: ['my-app', 'recipe-hello', 'button'] });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Example
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
Feature('Shadow Dom Locators');
|
|
53
|
+
|
|
54
|
+
Scenario('should fill input field within shadow elements', I => {
|
|
55
|
+
|
|
56
|
+
// navigate to LWC webpage containing shadow dom
|
|
57
|
+
I.amOnPage('https://recipes.lwc.dev/');
|
|
58
|
+
|
|
59
|
+
// click Click Me! button
|
|
60
|
+
I.click({ shadow: ['my-app', 'recipe-hello', 'button'] });
|
|
61
|
+
|
|
62
|
+
// fill the input field
|
|
63
|
+
I.fillField({ shadow: ['my-app', 'recipe-hello-binding', 'ui-input', 'input.input'] }, 'value');
|
|
64
|
+
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
```
|
package/docs/visual.md
CHANGED
|
@@ -112,79 +112,6 @@ MisMatch Percentage Calculated is 2.85
|
|
|
112
112
|
1) `seeVisualDiff` which can be used to compare two images and calculate the misMatch percentage.
|
|
113
113
|
2) `seeVisualDiffForElement` which can be used to compare elements on the two images and calculate misMatch percentage.
|
|
114
114
|
|
|
115
|
-
## Using Visual Knight
|
|
116
|
-
|
|
117
|
-
Visual Knight is a SaaS product which strongly supports CodeceptJS with multiple use cases. It provides an user interface to handle mismatches, statistics and more. It was designed to support Designer, Product Owner and other roles which are not familiar with coding and all this tools. All captured images are saved in a secure cloud system to not mess up your git repository.
|
|
118
|
-
|
|
119
|
-
### Setup
|
|
120
|
-
|
|
121
|
-
Create an account at [Visual Knight](https://www.visual-knight.io) and install the npm package
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
npm install @visual-knight/codeceptjs -D
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Configuring
|
|
128
|
-
|
|
129
|
-
```json
|
|
130
|
-
{
|
|
131
|
-
"helpers": {
|
|
132
|
-
"VisualKnight": {
|
|
133
|
-
"require": "@visual-knight/codeceptjs",
|
|
134
|
-
"key": "YOUR_API_KEY",
|
|
135
|
-
"project": "YOUR_PROJECT_ID OR PROJECT_NAME"
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Usage
|
|
142
|
-
|
|
143
|
-
```javascript
|
|
144
|
-
/**
|
|
145
|
-
* @param testName {string} Is provided to visual knight (must be unique)
|
|
146
|
-
* @param options {ScreenshotOptions} Contains additional settings
|
|
147
|
-
*/
|
|
148
|
-
I.compareFullpageScreenshot(testName, options)
|
|
149
|
-
/**
|
|
150
|
-
* @param testName {string} Is provided to visual knight (must be unique)
|
|
151
|
-
* @param options {ScreenshotOptions} Contains additional settings
|
|
152
|
-
*/
|
|
153
|
-
I.compareViewportScreenshot(testName, options)
|
|
154
|
-
/**
|
|
155
|
-
* @param cssSelector {string} Is provided to visual knight
|
|
156
|
-
* @param testName {string} Is provided to visual knight (must be unique)
|
|
157
|
-
* @param options {ScreenshotOptions} Contains additional settings
|
|
158
|
-
*/
|
|
159
|
-
I.compareElementScreenshot(cssSelector, testName, options)
|
|
160
|
-
|
|
161
|
-
/*
|
|
162
|
-
ScreenshotOptions {
|
|
163
|
-
hide?: string[] // Array of css selectors which gets hidden by "opacity: 0",
|
|
164
|
-
remove?: string[] // Array of css selectors which gets hidden by "display: none",
|
|
165
|
-
additional?: object // Data is saved as relation to the variation. (Future: can be used for filtering)
|
|
166
|
-
}
|
|
167
|
-
*/
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
> You can find the latest documentation here [CodeceptJS helper page](https://doc.visual-knight.io/adapters/codeceptjs)
|
|
171
|
-
|
|
172
|
-
### Example
|
|
173
|
-
|
|
174
|
-
Lets consider visual testing for [CodeceptJS Home](http://codecept.io)
|
|
175
|
-
|
|
176
|
-
```js
|
|
177
|
-
Feature('To test screen comparison with Visual Knight Example test');
|
|
178
|
-
|
|
179
|
-
Scenario('Compare CodeceptIO Home Page @visual-test', async (I, adminPage) => {
|
|
180
|
-
I.amOnPage("/");
|
|
181
|
-
I.compareFullpageScreenshot("CodeceptIO Home Page")
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Depending of your configuration this test will fail if no baseline exists and log the link to the image to accept or automatically accept the first run as baseline.
|
|
186
|
-
> You can accept the first image as baseline automatically via ```autoBaseline: true``` _default is false_
|
|
187
|
-
|
|
188
115
|
## Using Applitools
|
|
189
116
|
|
|
190
117
|
Applitools helps Test Automation engineers, DevOps, and FrontEnd Developers continuously test and validate visually perfect mobile, web, and native apps. Now it can be used with CodeceptJS.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Perform an emulated click on a link or a button, given by a locator.
|
|
2
|
+
Unlike normal click instead of sending native event, emulates a click with JavaScript.
|
|
3
|
+
This works on hidden, animated or inactive elements as well.
|
|
4
|
+
|
|
5
|
+
If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
|
|
6
|
+
For buttons, the "value" attribute, "name" attribute, and inner text are searched. For links, the link text is searched.
|
|
7
|
+
For images, the "alt" attribute and inner text of any parent links are searched.
|
|
8
|
+
|
|
9
|
+
The second parameter is a context (CSS or XPath locator) to narrow the search.
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
// simple link
|
|
13
|
+
I.forceClick('Logout');
|
|
14
|
+
// button of form
|
|
15
|
+
I.forceClick('Submit');
|
|
16
|
+
// CSS button
|
|
17
|
+
I.forceClick('#form input[type=submit]');
|
|
18
|
+
// XPath
|
|
19
|
+
I.forceClick('//form/*[@type=submit]');
|
|
20
|
+
// link in context
|
|
21
|
+
I.forceClick('Logout', '#nav');
|
|
22
|
+
// using strict locator
|
|
23
|
+
I.forceClick({css: 'nav a.login'});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
@param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
|
|
27
|
+
@param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
Sets
|
|
1
|
+
Sets cookie(s).
|
|
2
|
+
|
|
3
|
+
Can be a single cookie object or an array of cookies:
|
|
2
4
|
|
|
3
5
|
```js
|
|
4
6
|
I.setCookie({name: 'auth', value: true});
|
|
7
|
+
|
|
8
|
+
// as array
|
|
9
|
+
I.setCookie([
|
|
10
|
+
{name: 'auth', value: true},
|
|
11
|
+
{name: 'agree', value: true}
|
|
12
|
+
]);
|
|
5
13
|
```
|
|
6
14
|
|
|
7
|
-
@param {object} cookie a cookie object.
|
|
15
|
+
@param {object|array} cookie a cookie object or array of cookie objects.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
Types out the given string or the array of keys provided.
|
|
3
|
+
_Note:_ Should only be used when using [`fillField`](#fillfield) is not an option.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
// When passing in a string
|
|
7
|
+
I.type('Type this out.');
|
|
8
|
+
// When passing in an array
|
|
9
|
+
I.type(['T', 'E', 'X', 'T']);
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
@param {string|string[]} key or array of keys to type.
|