codeceptjs 3.3.3 → 3.3.5-beta.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 +38 -0
- package/docs/api.md +4 -0
- package/docs/basics.md +2 -0
- package/docs/bdd.md +12 -0
- package/docs/build/JSONResponse.js +44 -3
- package/docs/build/Playwright.js +63 -40
- package/docs/build/Puppeteer.js +54 -43
- package/docs/build/REST.js +23 -9
- package/docs/build/WebDriver.js +39 -30
- package/docs/community-helpers.md +1 -0
- package/docs/configuration.md +21 -18
- package/docs/helpers/Appium.md +0 -723
- package/docs/helpers/JSONResponse.md +24 -0
- package/docs/helpers/Playwright.md +276 -264
- package/docs/helpers/Puppeteer.md +230 -222
- package/docs/helpers/REST.md +21 -6
- package/docs/helpers/WebDriver.md +265 -259
- package/docs/plugins.md +41 -1
- package/docs/reports.md +11 -0
- package/docs/secrets.md +30 -0
- package/docs/wiki/.git/FETCH_HEAD +1 -0
- package/docs/wiki/.git/HEAD +1 -0
- package/docs/wiki/.git/ORIG_HEAD +1 -0
- package/docs/wiki/.git/config +11 -0
- package/docs/wiki/.git/description +1 -0
- package/docs/wiki/.git/hooks/applypatch-msg.sample +15 -0
- package/docs/wiki/.git/hooks/commit-msg.sample +24 -0
- package/docs/wiki/.git/hooks/fsmonitor-watchman.sample +173 -0
- package/docs/wiki/.git/hooks/post-update.sample +8 -0
- package/docs/wiki/.git/hooks/pre-applypatch.sample +14 -0
- package/docs/wiki/.git/hooks/pre-commit.sample +49 -0
- package/docs/wiki/.git/hooks/pre-merge-commit.sample +13 -0
- package/docs/wiki/.git/hooks/pre-push.sample +53 -0
- package/docs/wiki/.git/hooks/pre-rebase.sample +169 -0
- package/docs/wiki/.git/hooks/pre-receive.sample +24 -0
- package/docs/wiki/.git/hooks/prepare-commit-msg.sample +42 -0
- package/docs/wiki/.git/hooks/push-to-checkout.sample +78 -0
- package/docs/wiki/.git/hooks/update.sample +128 -0
- package/docs/wiki/.git/index +0 -0
- package/docs/wiki/.git/info/exclude +6 -0
- package/docs/wiki/.git/logs/HEAD +1 -0
- package/docs/wiki/.git/logs/refs/heads/master +1 -0
- package/docs/wiki/.git/logs/refs/remotes/origin/HEAD +1 -0
- package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.idx +0 -0
- package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.pack +0 -0
- package/docs/wiki/.git/packed-refs +2 -0
- package/docs/wiki/.git/refs/heads/master +1 -0
- package/docs/wiki/.git/refs/remotes/origin/HEAD +1 -0
- package/docs/wiki/Community-Helpers-&-Plugins.md +7 -3
- package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +29 -0
- package/docs/wiki/Examples.md +39 -48
- package/docs/wiki/Release-Process.md +8 -8
- package/docs/wiki/Tests.md +62 -60
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +2 -2
- package/lib/command/generate.js +3 -0
- package/lib/command/init.js +88 -41
- package/lib/command/interactive.js +1 -1
- package/lib/config.js +9 -0
- package/lib/helper/JSONResponse.js +44 -3
- package/lib/helper/Playwright.js +63 -40
- package/lib/helper/Puppeteer.js +54 -43
- package/lib/helper/REST.js +23 -9
- package/lib/helper/WebDriver.js +39 -30
- package/lib/interfaces/gherkin.js +1 -1
- package/lib/plugin/customLocator.js +50 -3
- package/lib/plugin/retryFailedStep.js +1 -1
- package/lib/plugin/retryTo.js +1 -8
- package/lib/secret.js +31 -1
- package/lib/step.js +22 -10
- package/lib/utils.js +1 -6
- package/package.json +4 -4
- package/typings/index.d.ts +158 -0
- package/typings/types.d.ts +367 -96
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
## 3.3.4
|
|
2
|
+
|
|
3
|
+
* Added support for masking fields in objects via `secret` function:
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
I.sendPostRequest('/auth', secret({ name: 'jon', password: '123456' }, 'password'));
|
|
7
|
+
```
|
|
8
|
+
* Added [a guide about using of `secret`](/secrets) function
|
|
9
|
+
* [Appium] Use `touchClick` when interacting with elements in iOS. See #3317 by @mikk150
|
|
10
|
+
* [Playwright] Added `cdpConnection` option to connect over CDP. See #3309 by @Hmihaly
|
|
11
|
+
* [customLocator plugin] Allowed to specify multiple attributes for custom locator. Thanks to @aruiz-caritsqa
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
plugins: {
|
|
15
|
+
customLocator: {
|
|
16
|
+
enabled: true,
|
|
17
|
+
prefix: '$',
|
|
18
|
+
attribute: ['data-qa', 'data-test'],
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
* [retryTo plugin] Fixed #3147 using `pollInterval` option. See #3351 by @cyonkee
|
|
23
|
+
* [Playwright] Fixed grabbing of browser console messages and window resize in new tab. Thanks to @mirao
|
|
24
|
+
* [REST] Added `prettyPrintJson` option to print JSON in nice way by @PeterNgTr
|
|
25
|
+
* [JSONResponse] Updated response validation to iterate over array items if response is array. Thanks to @PeterNgTr
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
// response.data == [
|
|
29
|
+
// { user: { name: 'jon', email: 'jon@doe.com' } },
|
|
30
|
+
// { user: { name: 'matt', email: 'matt@doe.com' } },
|
|
31
|
+
//]
|
|
32
|
+
|
|
33
|
+
I.seeResponseContainsKeys(['user']);
|
|
34
|
+
I.seeResponseContainsJson({ user: { email: 'jon@doe.com' } });
|
|
35
|
+
I.seeResponseContainsJson({ user: { email: 'matt@doe.com' } });
|
|
36
|
+
I.dontSeeResponseContainsJson({ user: 2 });
|
|
37
|
+
```
|
|
38
|
+
|
|
1
39
|
## 3.3.3
|
|
2
40
|
|
|
3
41
|
* Fixed `DataCloneError: () => could not be cloned` when running data tests in run-workers
|
package/docs/api.md
CHANGED
|
@@ -263,6 +263,8 @@ The most basic thing to check in response is existence of keys in JSON object. U
|
|
|
263
263
|
I.seeResponseContainsKeys(['name', 'email']);
|
|
264
264
|
```
|
|
265
265
|
|
|
266
|
+
> ℹ️ If response is an array, it will check that every element in array have provided keys
|
|
267
|
+
|
|
266
268
|
However, this is a very naive approach. It won't work for arrays or nested objects.
|
|
267
269
|
To check complex JSON structures `JSONResponse` helper uses [`joi`](https://joi.dev) library.
|
|
268
270
|
It has rich API to validate JSON by the schema defined using JavaScript.
|
|
@@ -296,6 +298,8 @@ I.seeResponseContainsJson({
|
|
|
296
298
|
})
|
|
297
299
|
```
|
|
298
300
|
|
|
301
|
+
> ℹ️ If response is an array, it will check that at least one element in array matches JSON
|
|
302
|
+
|
|
299
303
|
To perform arbitrary assertions on a response object use `seeResponseValidByCallback`.
|
|
300
304
|
It allows you to do any kind of assertions by using `expect` from [`chai`](https://www.chaijs.com) library.
|
|
301
305
|
|
package/docs/basics.md
CHANGED
|
@@ -212,6 +212,8 @@ To fill in sensitive data use the `secret` function, it won't expose actual valu
|
|
|
212
212
|
I.fillField('password', secret('123456'));
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
+
> ℹ️ Learn more about [masking secret](/secrets/) output
|
|
216
|
+
|
|
215
217
|
### Assertions
|
|
216
218
|
|
|
217
219
|
In order to verify the expected behavior of a web application, its content should be checked.
|
package/docs/bdd.md
CHANGED
|
@@ -356,6 +356,18 @@ In case scenarios represent the same logic but differ on data, we can use *Scena
|
|
|
356
356
|
| 50 | 45 |
|
|
357
357
|
```
|
|
358
358
|
|
|
359
|
+
It might be the case that the same column value needs to be utilized multiple times in the same step, that also can be possible with scenario outline.
|
|
360
|
+
|
|
361
|
+
```gherkin
|
|
362
|
+
Scenario Outline: check parameter substitution
|
|
363
|
+
Given I have a defined step
|
|
364
|
+
When I see "<text>" text and "<text>" is not "xyz"
|
|
365
|
+
Examples:
|
|
366
|
+
| text |
|
|
367
|
+
| Google |
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
|
|
359
371
|
### Long Strings
|
|
360
372
|
|
|
361
373
|
Text values inside a scenarios can be set inside a `"""` block:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
1
2
|
const chai = require('chai');
|
|
2
3
|
const joi = require('joi');
|
|
3
4
|
const chaiDeepMatch = require('chai-deep-match');
|
|
@@ -173,12 +174,30 @@ class JSONResponse extends Helper {
|
|
|
173
174
|
*
|
|
174
175
|
* I.seeResponseContainsJson({ user: { email: 'jon@doe.com' } });
|
|
175
176
|
* ```
|
|
177
|
+
* If an array is received, checks that at least one element contains JSON
|
|
178
|
+
* ```js
|
|
179
|
+
* // response.data == [{ user: { name: 'jon', email: 'jon@doe.com' } }]
|
|
180
|
+
*
|
|
181
|
+
* I.seeResponseContainsJson({ user: { email: 'jon@doe.com' } });
|
|
182
|
+
* ```
|
|
176
183
|
*
|
|
177
184
|
* @param {object} json
|
|
178
185
|
*/
|
|
179
186
|
seeResponseContainsJson(json = {}) {
|
|
180
187
|
this._checkResponseReady();
|
|
181
|
-
|
|
188
|
+
if (Array.isArray(this.response.data)) {
|
|
189
|
+
let fails = 0;
|
|
190
|
+
for (const el of this.response.data) {
|
|
191
|
+
try {
|
|
192
|
+
expect(el).to.deep.match(json);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
fails++;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
assert.ok(fails < this.response.data.length, `No elements in array matched ${JSON.stringify(json)}`);
|
|
198
|
+
} else {
|
|
199
|
+
expect(this.response.data).to.deep.match(json);
|
|
200
|
+
}
|
|
182
201
|
}
|
|
183
202
|
|
|
184
203
|
/**
|
|
@@ -189,12 +208,22 @@ class JSONResponse extends Helper {
|
|
|
189
208
|
*
|
|
190
209
|
* I.dontSeeResponseContainsJson({ user: 2 });
|
|
191
210
|
* ```
|
|
211
|
+
* If an array is received, checks that no element of array contains json:
|
|
212
|
+
* ```js
|
|
213
|
+
* // response.data == [{ user: 1 }, { user: 3 }]
|
|
214
|
+
*
|
|
215
|
+
* I.dontSeeResponseContainsJson({ user: 2 });
|
|
216
|
+
* ```
|
|
192
217
|
*
|
|
193
218
|
* @param {object} json
|
|
194
219
|
*/
|
|
195
220
|
dontSeeResponseContainsJson(json = {}) {
|
|
196
221
|
this._checkResponseReady();
|
|
197
|
-
|
|
222
|
+
if (Array.isArray(this.response.data)) {
|
|
223
|
+
this.response.data.forEach(data => expect(data).not.to.deep.match(json));
|
|
224
|
+
} else {
|
|
225
|
+
expect(this.response.data).not.to.deep.match(json);
|
|
226
|
+
}
|
|
198
227
|
}
|
|
199
228
|
|
|
200
229
|
/**
|
|
@@ -206,11 +235,23 @@ class JSONResponse extends Helper {
|
|
|
206
235
|
* I.seeResponseContainsKeys(['user']);
|
|
207
236
|
* ```
|
|
208
237
|
*
|
|
238
|
+
* If an array is received, check is performed for each element of array:
|
|
239
|
+
*
|
|
240
|
+
* ```js
|
|
241
|
+
* // response.data == [{ user: 'jon' }, { user: 'matt'}]
|
|
242
|
+
*
|
|
243
|
+
* I.seeResponseContainsKeys(['user']);
|
|
244
|
+
* ```
|
|
245
|
+
*
|
|
209
246
|
* @param {array} keys
|
|
210
247
|
*/
|
|
211
248
|
seeResponseContainsKeys(keys = []) {
|
|
212
249
|
this._checkResponseReady();
|
|
213
|
-
|
|
250
|
+
if (Array.isArray(this.response.data)) {
|
|
251
|
+
this.response.data.forEach(data => expect(data).to.include.keys(keys));
|
|
252
|
+
} else {
|
|
253
|
+
expect(this.response.data).to.include.keys(keys);
|
|
254
|
+
}
|
|
214
255
|
}
|
|
215
256
|
|
|
216
257
|
/**
|
package/docs/build/Playwright.js
CHANGED
|
@@ -44,6 +44,46 @@ const {
|
|
|
44
44
|
} = require('./extras/PlaywrightRestartOpts');
|
|
45
45
|
const { createValueEngine, createDisabledEngine } = require('./extras/PlaywrightPropEngine');
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* ## Configuration
|
|
49
|
+
*
|
|
50
|
+
* This helper should be configured in codecept.conf.js
|
|
51
|
+
*
|
|
52
|
+
* @typedef PlaywrightConfig
|
|
53
|
+
* @type {object}
|
|
54
|
+
* @prop {string} url - base url of website to be tested
|
|
55
|
+
* @prop {string} browser - a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
|
|
56
|
+
* @prop {boolean} [show=false] - show browser window.
|
|
57
|
+
* @prop {string|boolean} [restart=false] - restart strategy between tests. Possible values:
|
|
58
|
+
* * 'context' or **false** - restarts [browser context](https://playwright.dev/docs/api/class-browsercontext) but keeps running browser. Recommended by Playwright team to keep tests isolated.
|
|
59
|
+
* * 'browser' or **true** - closes browser and opens it again between tests.
|
|
60
|
+
* * 'session' or 'keep' - keeps browser context and session, but cleans up cookies and localStorage between tests. The fastest option when running tests in windowed mode. Works with `keepCookies` and `keepBrowserState` options. This behavior was default before CodeceptJS 3.1
|
|
61
|
+
* @prop {number} [timeout=1000] - - [timeout](https://playwright.dev/docs/api/class-page#page-set-default-timeout) in ms of all Playwright actions .
|
|
62
|
+
* @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
|
|
63
|
+
* @prop {any} [emulate] - browser in device emulation mode.
|
|
64
|
+
* @prop {boolean} [video=false] - enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
65
|
+
* @prop {boolean} [trace=false] - record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
|
|
66
|
+
* @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
|
|
67
|
+
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
68
|
+
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to 'session'.
|
|
69
|
+
* @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to 'session'.
|
|
70
|
+
* @prop {number} [waitForAction] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
71
|
+
* @prop {number} [waitForNavigation] - When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle`. Choose one of those options is possible. See [Playwright API](https://github.com/microsoft/playwright/blob/main/docs/api.md#pagewaitfornavigationoptions).
|
|
72
|
+
* @prop {number} [pressKeyDelay=10] - Delay between key presses in ms. Used when calling Playwrights page.type(...) in fillField/appendField
|
|
73
|
+
* @prop {number} [getPageTimeout] - config option to set maximum navigation time in milliseconds.
|
|
74
|
+
* @prop {number} [waitForTimeout] - default wait* timeout in ms. Default: 1000.
|
|
75
|
+
* @prop {object} [basicAuth] - the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
76
|
+
* @prop {string} [windowSize] - default window size. Set a dimension like `640x480`.
|
|
77
|
+
* @prop {string} [colorScheme] - default color scheme. Possible values: `dark` | `light` | `no-preference`.
|
|
78
|
+
* @prop {string} [userAgent] - user-agent string.
|
|
79
|
+
* @prop {string} [locale] - locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
|
|
80
|
+
* @prop {boolean} [manualStart] - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
|
|
81
|
+
* @prop {object} [chromium] - pass additional chromium options
|
|
82
|
+
* @prop {object} [electron] - (pass additional electron options
|
|
83
|
+
* @prop {any} [channel] - (While Playwright can operate against the stock Google Chrome and Microsoft Edge browsers available on the machine. In particular, current Playwright version will support Stable and Beta channels of these browsers. See [Google Chrome & Microsoft Edge](https://playwright.dev/docs/browsers/#google-chrome--microsoft-edge).
|
|
84
|
+
*/
|
|
85
|
+
const config = {};
|
|
86
|
+
|
|
47
87
|
/**
|
|
48
88
|
* Uses [Playwright](https://github.com/microsoft/playwright) library to run tests inside:
|
|
49
89
|
*
|
|
@@ -65,46 +105,14 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
65
105
|
*
|
|
66
106
|
* Using playwright-core package, will prevent the download of browser binaries and allow connecting to an existing browser installation or for connecting to a remote one.
|
|
67
107
|
*
|
|
68
|
-
* ## Configuration
|
|
69
108
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* * `url`: base url of website to be tested
|
|
73
|
-
* * `browser`: a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
|
|
74
|
-
* * `show`: (optional, default: false) - show browser window.
|
|
75
|
-
* * `restart`: (optional, default: false) - restart strategy between tests. Possible values:
|
|
76
|
-
* * 'context' or **false** - restarts [browser context](https://playwright.dev/docs/api/class-browsercontext) but keeps running browser. Recommended by Playwright team to keep tests isolated.
|
|
77
|
-
* * 'browser' or **true** - closes browser and opens it again between tests.
|
|
78
|
-
* * 'session' or 'keep' - keeps browser context and session, but cleans up cookies and localStorage between tests. The fastest option when running tests in windowed mode. Works with `keepCookies` and `keepBrowserState` options. This behavior was default before CodeceptJS 3.1
|
|
79
|
-
* * `timeout`: (optional, default: 1000) - [timeout](https://playwright.dev/docs/api/class-page#page-set-default-timeout) in ms of all Playwright actions .
|
|
80
|
-
* * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
|
|
81
|
-
* * `emulate`: (optional, default: {}) launch browser in device emulation mode.
|
|
82
|
-
* * `video`: (optional, default: false) enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
83
|
-
* * `trace`: (optional, default: false) record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
|
|
84
|
-
* * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
|
|
85
|
-
* * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
86
|
-
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to 'session'.
|
|
87
|
-
* * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` is set to 'session'.
|
|
88
|
-
* * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
89
|
-
* * `waitForNavigation`: (optional, default: 'load'). When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle`. Choose one of those options is possible. See [Playwright API](https://github.com/microsoft/playwright/blob/main/docs/api.md#pagewaitfornavigationoptions).
|
|
90
|
-
* * `pressKeyDelay`: (optional, default: '10'). Delay between key presses in ms. Used when calling Playwrights page.type(...) in fillField/appendField
|
|
91
|
-
* * `getPageTimeout` (optional, default: '0') config option to set maximum navigation time in milliseconds.
|
|
92
|
-
* * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
|
|
93
|
-
* * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
94
|
-
* * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
|
|
95
|
-
* * `colorScheme`: (optional) default color scheme. Possible values: `dark` | `light` | `no-preference`.
|
|
96
|
-
* * `userAgent`: (optional) user-agent string.
|
|
97
|
-
* * `locale`: (optional) locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
|
|
98
|
-
* * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
|
|
99
|
-
* * `chromium`: (optional) pass additional chromium options
|
|
100
|
-
* * `electron`: (optional) pass additional electron options
|
|
101
|
-
* * `channel`: (optional) While Playwright can operate against the stock Google Chrome and Microsoft Edge browsers available on the machine. In particular, current Playwright version will support Stable and Beta channels of these browsers. See [Google Chrome & Microsoft Edge](https://playwright.dev/docs/browsers/#google-chrome--microsoft-edge).
|
|
109
|
+
* <!-- configuration -->
|
|
102
110
|
*
|
|
103
111
|
* #### Video Recording Customization
|
|
104
112
|
*
|
|
105
113
|
* By default, video is saved to `output/video` dir. You can customize this path by passing `dir` option to `recordVideo` option.
|
|
106
114
|
*
|
|
107
|
-
*
|
|
115
|
+
* `video`: enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
108
116
|
* * `keepVideoForPassedTests`: - save videos for passed tests
|
|
109
117
|
* * `recordVideo`: [additional options for videos customization](https://playwright.dev/docs/next/api/class-browser#browser-new-context)
|
|
110
118
|
*
|
|
@@ -167,7 +175,8 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
167
175
|
* Playwright: {
|
|
168
176
|
* url: "http://localhost",
|
|
169
177
|
* chromium: {
|
|
170
|
-
* browserWSEndpoint: 'ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a'
|
|
178
|
+
* browserWSEndpoint: 'ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a',
|
|
179
|
+
* cdpConnection: false // default is false
|
|
171
180
|
* }
|
|
172
181
|
* }
|
|
173
182
|
* }
|
|
@@ -256,8 +265,6 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
256
265
|
* const { browserContext } = this.helpers.Playwright;
|
|
257
266
|
* await browserContext.cookies(); // get current browser context
|
|
258
267
|
* ```
|
|
259
|
-
*
|
|
260
|
-
* ## Methods
|
|
261
268
|
*/
|
|
262
269
|
class Playwright extends Helper {
|
|
263
270
|
constructor(config) {
|
|
@@ -272,6 +279,7 @@ class Playwright extends Helper {
|
|
|
272
279
|
this.sessionPages = {};
|
|
273
280
|
this.activeSessionName = '';
|
|
274
281
|
this.isElectron = false;
|
|
282
|
+
this.isCDPConnection = false;
|
|
275
283
|
this.electronSessions = [];
|
|
276
284
|
this.storageState = null;
|
|
277
285
|
|
|
@@ -347,6 +355,7 @@ class Playwright extends Helper {
|
|
|
347
355
|
this.isRemoteBrowser = !!this.playwrightOptions.browserWSEndpoint;
|
|
348
356
|
this.isElectron = this.options.browser === 'electron';
|
|
349
357
|
this.userDataDir = this.playwrightOptions.userDataDir;
|
|
358
|
+
this.isCDPConnection = this.playwrightOptions.cdpConnection;
|
|
350
359
|
popupStore.defaultAction = this.options.defaultPopupAction;
|
|
351
360
|
}
|
|
352
361
|
|
|
@@ -699,6 +708,15 @@ class Playwright extends Helper {
|
|
|
699
708
|
async _startBrowser() {
|
|
700
709
|
if (this.isElectron) {
|
|
701
710
|
this.browser = await playwright._electron.launch(this.playwrightOptions);
|
|
711
|
+
} else if (this.isRemoteBrowser && this.isCDPConnection) {
|
|
712
|
+
try {
|
|
713
|
+
this.browser = await playwright[this.options.browser].connectOverCDP(this.playwrightOptions);
|
|
714
|
+
} catch (err) {
|
|
715
|
+
if (err.toString().indexOf('ECONNREFUSED')) {
|
|
716
|
+
throw new RemoteBrowserConnectionRefused(err);
|
|
717
|
+
}
|
|
718
|
+
throw err;
|
|
719
|
+
}
|
|
702
720
|
} else if (this.isRemoteBrowser) {
|
|
703
721
|
try {
|
|
704
722
|
this.browser = await playwright[this.options.browser].connect(this.playwrightOptions);
|
|
@@ -1157,6 +1175,7 @@ class Playwright extends Helper {
|
|
|
1157
1175
|
if (!page) {
|
|
1158
1176
|
throw new Error(`There is no ability to switch to next tab with offset ${num}`);
|
|
1159
1177
|
}
|
|
1178
|
+
targetCreatedHandler.call(this, page);
|
|
1160
1179
|
await this._setPage(page);
|
|
1161
1180
|
return this._waitForAction();
|
|
1162
1181
|
}
|
|
@@ -1239,7 +1258,9 @@ class Playwright extends Helper {
|
|
|
1239
1258
|
if (this.isElectron) {
|
|
1240
1259
|
throw new Error('Cannot open new tabs inside an Electron container');
|
|
1241
1260
|
}
|
|
1242
|
-
|
|
1261
|
+
const page = await this.browserContext.newPage(options);
|
|
1262
|
+
targetCreatedHandler.call(this, page);
|
|
1263
|
+
await this._setPage(page);
|
|
1243
1264
|
return this._waitForAction();
|
|
1244
1265
|
}
|
|
1245
1266
|
|
|
@@ -2071,9 +2092,11 @@ class Playwright extends Helper {
|
|
|
2071
2092
|
* Get JS log from browser.
|
|
2072
2093
|
*
|
|
2073
2094
|
* ```js
|
|
2074
|
-
*
|
|
2075
|
-
*
|
|
2095
|
+
* const logs = await I.grabBrowserLogs();
|
|
2096
|
+
* const errors = logs.map(l => ({ type: l.type(), text: l.text() })).filter(l => l.type === 'error');
|
|
2097
|
+
* console.log(JSON.stringify(errors));
|
|
2076
2098
|
* ```
|
|
2099
|
+
* [Learn more about console messages](https://playwright.dev/docs/api/class-consolemessage)
|
|
2077
2100
|
* @return {Promise<any[]>}
|
|
2078
2101
|
*/
|
|
2079
2102
|
async grabBrowserLogs() {
|
package/docs/build/Puppeteer.js
CHANGED
|
@@ -39,6 +39,35 @@ let perfTiming;
|
|
|
39
39
|
const popupStore = new Popup();
|
|
40
40
|
const consoleLogStore = new Console();
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* ## Configuration
|
|
44
|
+
*
|
|
45
|
+
* This helper should be configured in codecept.conf.js
|
|
46
|
+
*
|
|
47
|
+
* @typedef PuppeteerConfig
|
|
48
|
+
* @type {object}
|
|
49
|
+
* @prop {string} url - base url of website to be tested
|
|
50
|
+
* @prop {object} [basicAuth] (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
51
|
+
* @prop {boolean} [show] - show Google Chrome window for debug.
|
|
52
|
+
* @prop {boolean} [restart=true] - restart browser between tests.
|
|
53
|
+
* @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
|
|
54
|
+
* @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
|
|
55
|
+
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
56
|
+
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to false.
|
|
57
|
+
* @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to false.
|
|
58
|
+
* @prop {number} [waitForAction=100] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
59
|
+
* @prop {string} [waitForNavigation=load] - when to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions). Array values are accepted as well.
|
|
60
|
+
* @prop {number} [pressKeyDelay=10] - delay between key presses in ms. Used when calling Puppeteers page.type(...) in fillField/appendField
|
|
61
|
+
* @prop {number} [getPageTimeout=30000] - config option to set maximum navigation time in milliseconds. If the timeout is set to 0, then timeout will be disabled.
|
|
62
|
+
* @prop {number} [waitForTimeout=1000] - default wait* timeout in ms.
|
|
63
|
+
* @prop {string} [windowSize] - default window size. Set a dimension in format WIDTHxHEIGHT like `640x480`.
|
|
64
|
+
* @prop {string} [userAgent] - user-agent string.
|
|
65
|
+
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
66
|
+
* @prop {string} [browser=chrome] - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
67
|
+
* @prop {object} [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
68
|
+
*/
|
|
69
|
+
const config = {};
|
|
70
|
+
|
|
42
71
|
/**
|
|
43
72
|
* Uses [Google Chrome's Puppeteer](https://github.com/GoogleChrome/puppeteer) library to run tests inside headless Chrome.
|
|
44
73
|
* Browser control is executed via DevTools Protocol (instead of Selenium).
|
|
@@ -56,30 +85,7 @@ const consoleLogStore = new Console();
|
|
|
56
85
|
*
|
|
57
86
|
* > Experimental Firefox support [can be activated](https://codecept.io/helpers/Puppeteer-firefox).
|
|
58
87
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* This helper should be configured in codecept.json or codecept.conf.js
|
|
62
|
-
*
|
|
63
|
-
* * `url`: base url of website to be tested
|
|
64
|
-
* * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
65
|
-
* * `show`: (optional, default: false) - show Google Chrome window for debug.
|
|
66
|
-
* * `restart`: (optional, default: true) - restart browser between tests.
|
|
67
|
-
* * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
|
|
68
|
-
* * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
|
|
69
|
-
* * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
70
|
-
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
|
|
71
|
-
* * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` is set to false.
|
|
72
|
-
* * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
73
|
-
* * `waitForNavigation`: (optional, default: 'load'). When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions). Array values are accepted as well.
|
|
74
|
-
* * `pressKeyDelay`: (optional, default: '10'). Delay between key presses in ms. Used when calling Puppeteers page.type(...) in fillField/appendField
|
|
75
|
-
* * `getPageTimeout` (optional, default: '30000') config option to set maximum navigation time in milliseconds. If the timeout is set to 0, then timeout will be disabled.
|
|
76
|
-
* * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
|
|
77
|
-
* * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
|
|
78
|
-
* * `userAgent`: (optional) user-agent string.
|
|
79
|
-
* * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
80
|
-
* * `browser`: (optional, default: chrome) - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
81
|
-
* * `chrome`: (optional) pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
82
|
-
*
|
|
88
|
+
* <!-- configuration -->
|
|
83
89
|
*
|
|
84
90
|
* #### Example #1: Wait for 0 network connections.
|
|
85
91
|
*
|
|
@@ -192,7 +198,6 @@ class Puppeteer extends Helper {
|
|
|
192
198
|
super(config);
|
|
193
199
|
|
|
194
200
|
puppeteer = requireWithFallback('puppeteer', 'puppeteer-core');
|
|
195
|
-
|
|
196
201
|
// set defaults
|
|
197
202
|
this.isRemoteBrowser = false;
|
|
198
203
|
this.isRunning = false;
|
|
@@ -372,22 +377,22 @@ class Puppeteer extends Helper {
|
|
|
372
377
|
}
|
|
373
378
|
|
|
374
379
|
/**
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
380
|
+
* Use Puppeteer API inside a test.
|
|
381
|
+
*
|
|
382
|
+
* First argument is a description of an action.
|
|
383
|
+
* Second argument is async function that gets this helper as parameter.
|
|
384
|
+
*
|
|
385
|
+
* { [`page`](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-page), [`browser`](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browser) } from Puppeteer API are available.
|
|
386
|
+
*
|
|
387
|
+
* ```js
|
|
388
|
+
* I.usePuppeteerTo('emulate offline mode', async ({ page }) {
|
|
389
|
+
* await page.setOfflineMode(true);
|
|
390
|
+
* });
|
|
391
|
+
* ```
|
|
392
|
+
*
|
|
393
|
+
* @param {string} description used to show in logs.
|
|
394
|
+
* @param {function} fn async function that is executed with Puppeteer as argument
|
|
395
|
+
*/
|
|
391
396
|
usePuppeteerTo(description, fn) {
|
|
392
397
|
return this._useTo(...arguments);
|
|
393
398
|
}
|
|
@@ -816,7 +821,8 @@ class Puppeteer extends Helper {
|
|
|
816
821
|
if (locator) {
|
|
817
822
|
const els = await this._locate(locator);
|
|
818
823
|
assertElementExists(els, locator, 'Element');
|
|
819
|
-
|
|
824
|
+
const el = els[0];
|
|
825
|
+
await el.evaluate((el) => el.scrollIntoView());
|
|
820
826
|
const elementCoordinates = await getClickablePoint(els[0]);
|
|
821
827
|
await this.executeScript((x, y) => window.scrollBy(x, y), elementCoordinates.x + offsetX, elementCoordinates.y + offsetY);
|
|
822
828
|
} else {
|
|
@@ -1268,7 +1274,12 @@ class Puppeteer extends Helper {
|
|
|
1268
1274
|
fs.mkdirSync(downloadPath, '0777');
|
|
1269
1275
|
}
|
|
1270
1276
|
fsExtra.emptyDirSync(downloadPath);
|
|
1271
|
-
|
|
1277
|
+
|
|
1278
|
+
try {
|
|
1279
|
+
return this.page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath });
|
|
1280
|
+
} catch (e) {
|
|
1281
|
+
return this.page._client().send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath });
|
|
1282
|
+
}
|
|
1272
1283
|
}
|
|
1273
1284
|
|
|
1274
1285
|
/**
|
package/docs/build/REST.js
CHANGED
|
@@ -2,18 +2,28 @@ const axios = require('axios').default;
|
|
|
2
2
|
const Secret = require('../secret');
|
|
3
3
|
|
|
4
4
|
const Helper = require('../helper');
|
|
5
|
+
const { beautify } = require('../utils');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ## Configuration
|
|
9
|
+
*
|
|
10
|
+
* @typedef RESTConfig
|
|
11
|
+
* @type {object}
|
|
12
|
+
* @prop {string} endpoint - API base URL
|
|
13
|
+
* @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs
|
|
14
|
+
* @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default
|
|
15
|
+
* @prop {object} [defaultHeaders] - a list of default headers
|
|
16
|
+
* @prop {function} [onRequest] - a async function which can update request object.
|
|
17
|
+
* @prop {function} [onResponse] - a async function which can update response object.
|
|
18
|
+
* @prop {number} [maxUploadFileSize] - set the max content file size in MB when performing api calls.
|
|
19
|
+
*/
|
|
20
|
+
const config = {};
|
|
5
21
|
|
|
6
22
|
/**
|
|
7
23
|
* REST helper allows to send additional requests to the REST API during acceptance tests.
|
|
8
24
|
* [Axios](https://github.com/axios/axios) library is used to perform requests.
|
|
9
25
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* * endpoint: API base URL
|
|
13
|
-
* * timeout: timeout for requests in milliseconds. 10000ms by default
|
|
14
|
-
* * defaultHeaders: a list of default headers
|
|
15
|
-
* * onRequest: a async function which can update request object.
|
|
16
|
-
* * maxUploadFileSize: set the max content file size in MB when performing api calls.
|
|
26
|
+
* <!-- configuration -->
|
|
17
27
|
*
|
|
18
28
|
* ## Example
|
|
19
29
|
*
|
|
@@ -22,6 +32,7 @@ const Helper = require('../helper');
|
|
|
22
32
|
* helpers: {
|
|
23
33
|
* REST: {
|
|
24
34
|
* endpoint: 'http://site.com/api',
|
|
35
|
+
* prettyPrintJson: true,
|
|
25
36
|
* onRequest: (request) => {
|
|
26
37
|
* request.headers.auth = '123';
|
|
27
38
|
* }
|
|
@@ -49,6 +60,9 @@ class REST extends Helper {
|
|
|
49
60
|
timeout: 10000,
|
|
50
61
|
defaultHeaders: {},
|
|
51
62
|
endpoint: '',
|
|
63
|
+
prettyPrintJson: false,
|
|
64
|
+
onRequest: null,
|
|
65
|
+
onResponse: null,
|
|
52
66
|
};
|
|
53
67
|
|
|
54
68
|
if (this.options.maxContentLength) {
|
|
@@ -137,7 +151,7 @@ class REST extends Helper {
|
|
|
137
151
|
await this.config.onRequest(request);
|
|
138
152
|
}
|
|
139
153
|
|
|
140
|
-
this.debugSection('Request', JSON.stringify(_debugRequest));
|
|
154
|
+
this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest));
|
|
141
155
|
|
|
142
156
|
let response;
|
|
143
157
|
try {
|
|
@@ -150,7 +164,7 @@ class REST extends Helper {
|
|
|
150
164
|
if (this.config.onResponse) {
|
|
151
165
|
await this.config.onResponse(response);
|
|
152
166
|
}
|
|
153
|
-
this.debugSection('Response', JSON.stringify(response.data));
|
|
167
|
+
this.options.prettyPrintJson ? this.debugSection('Response', beautify(JSON.stringify(response.data))) : this.debugSection('Response', JSON.stringify(response.data));
|
|
154
168
|
return response;
|
|
155
169
|
}
|
|
156
170
|
|