codeceptjs 2.6.7 → 2.6.11
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 +33 -6
- package/README.md +11 -11
- package/docs/advanced.md +21 -0
- package/docs/basics.md +6 -5
- package/docs/bdd.md +1 -2
- package/docs/books.md +1 -1
- package/docs/build/Appium.js +1 -2
- package/docs/build/FileSystem.js +3 -3
- package/docs/build/Mochawesome.js +1 -1
- package/docs/build/Nightmare.js +81 -5
- package/docs/build/Playwright.js +100 -17
- package/docs/build/Protractor.js +34 -2
- package/docs/build/Puppeteer.js +59 -2
- package/docs/build/TestCafe.js +23 -0
- package/docs/build/WebDriver.js +62 -16
- package/docs/changelog.md +152 -125
- package/docs/community-helpers.md +7 -3
- package/docs/configuration.md +1 -1
- package/docs/custom-helpers.md +2 -2
- package/docs/data.md +1 -1
- package/docs/detox.md +2 -2
- package/docs/email.md +1 -1
- package/docs/examples.md +12 -2
- package/docs/helpers/Appium.md +24 -5
- package/docs/helpers/Nightmare.md +42 -0
- package/docs/helpers/Playwright.md +41 -4
- package/docs/helpers/Protractor.md +14 -0
- package/docs/helpers/Puppeteer.md +38 -1
- package/docs/helpers/TestCafe.md +14 -0
- package/docs/helpers/WebDriver.md +24 -5
- package/docs/hooks.md +14 -14
- package/docs/locators.md +1 -1
- package/docs/playwright.md +13 -0
- package/docs/translation.md +21 -1
- package/docs/ui.md +2 -2
- package/docs/videos.md +4 -4
- package/docs/webapi/saveElementScreenshot.mustache +9 -0
- package/docs/webapi/type.mustache +11 -6
- package/docs/wiki/{Community-Helpers.md → Community-Helpers-&-Plugins.md} +6 -2
- package/docs/wiki/Examples.md +11 -1
- package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +68 -0
- package/docs/wiki/Home.md +9 -4
- package/docs/wiki/Release-Process.md +24 -0
- package/docs/wiki/Tests.md +1391 -0
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +153 -0
- package/docs/wiki/Videos.md +3 -3
- package/lib/actor.js +1 -1
- package/lib/assert/empty.js +1 -1
- package/lib/assert/equal.js +1 -1
- package/lib/assert/include.js +1 -1
- package/lib/assert/truth.js +1 -1
- package/lib/codecept.js +2 -3
- package/lib/command/configMigrate.js +3 -5
- package/lib/command/definitions.js +1 -2
- package/lib/command/dryRun.js +1 -2
- package/lib/command/gherkin/init.js +1 -1
- package/lib/command/gherkin/snippets.js +3 -3
- package/lib/command/gherkin/steps.js +2 -3
- package/lib/command/info.js +1 -2
- package/lib/command/init.js +2 -2
- package/lib/command/interactive.js +1 -2
- package/lib/command/list.js +3 -4
- package/lib/command/run-multiple.js +2 -3
- package/lib/command/run-rerun.js +2 -4
- package/lib/command/run.js +1 -2
- package/lib/container.js +2 -2
- package/lib/data/context.js +1 -1
- package/lib/event.js +1 -1
- package/lib/helper/Appium.js +1 -2
- package/lib/helper/FileSystem.js +3 -3
- package/lib/helper/Mochawesome.js +1 -1
- package/lib/helper/Nightmare.js +54 -5
- package/lib/helper/Playwright.js +75 -17
- package/lib/helper/Protractor.js +26 -2
- package/lib/helper/Puppeteer.js +34 -2
- package/lib/helper/TestCafe.js +15 -0
- package/lib/helper/WebDriver.js +43 -11
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- package/lib/hooks.js +1 -2
- package/lib/interfaces/gherkin.js +0 -1
- package/lib/listener/helpers.js +1 -2
- package/lib/listener/mocha.js +0 -1
- package/lib/locator.js +2 -2
- package/lib/pause.js +1 -1
- package/lib/plugin/allure.js +1 -1
- package/lib/plugin/autoDelay.js +3 -3
- package/lib/plugin/autoLogin.js +1 -1
- package/lib/plugin/screenshotOnFail.js +2 -1
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/recorder.js +1 -1
- package/lib/step.js +3 -0
- package/lib/ui.js +1 -0
- package/package.json +3 -2
- package/translations/fr-FR.js +63 -0
- package/translations/index.js +5 -4
- package/typings/types.d.ts +140 -8
- package/docs/wiki/Release-process.md +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
## 2.6.11
|
|
2
|
+
|
|
3
|
+
* [Playwright] Playwright 1.4 compatibility
|
|
4
|
+
* [Playwright] Added `ignoreHTTPSErrors` config option (default: false). See #2566 by gurjeetbains
|
|
5
|
+
* Added French translation by @vimar
|
|
6
|
+
* [WebDriver] Updated `dragSlider` to work in WebDriver W3C protocol. Fixes #2557 by suniljaiswal01
|
|
7
|
+
|
|
8
|
+
## 2.6.10
|
|
9
|
+
|
|
10
|
+
* Fixed saving options for suite via `Feature('title', {key: value})` by @Diokuz. See #2553 and [Docs](https://codecept.io/advanced/#dynamic-configuration)
|
|
11
|
+
|
|
12
|
+
## 2.6.9
|
|
13
|
+
|
|
14
|
+
* [Puppeteer][Playwright] SessionStorage is now cleared in after hook. See #2524
|
|
15
|
+
* When helper load failed the error stack is now logged by @SkReD. See #2541
|
|
16
|
+
* Small documentation fixes.
|
|
17
|
+
|
|
18
|
+
## 2.6.8
|
|
19
|
+
|
|
20
|
+
* [WebDriver][Protractor][Playwright][Puppeteer][Nightmare] `saveElementScreenshot` method added to make screenshot of an element. By @suniljaiswal01
|
|
21
|
+
* [Playwright][Puppeteer] Added `type` method to type a text using keyboard with an optional delay.
|
|
22
|
+
* [WebDriver] Added optional `delay` argument to `type` method to slow down typing.
|
|
23
|
+
* [Puppeteer] Fixed `amOnPage` freeze when `getPageTimeout` is 0"; set 30 sec as default timeout by @Vorobeyko.
|
|
24
|
+
* Fixed printing step with null argument in custom helper by @sjana-aj. See #2494
|
|
25
|
+
* Fix missing screenshot on failure when REST helper is in use #2513 by @PeterNgTr
|
|
26
|
+
* Improve error logging in the `screenshotOnFail` plugin #2512 by @pablopaul
|
|
27
|
+
|
|
1
28
|
## 2.6.7
|
|
2
29
|
|
|
3
30
|
* Add REST helper into `standardActingHelpers` array #2474 by @PeterNgTr
|
|
@@ -164,7 +191,7 @@ I.see('You are logged out');
|
|
|
164
191
|
* works with WebDriver helper
|
|
165
192
|
* Avoid failiure report on successful retry in worker by @koushikmohan1996
|
|
166
193
|
* Added translation ability to Scenario, Feature and other context methods by @koushikmohan1996
|
|
167
|
-
* 📢 Please help us translate context methods to your language! See [italian translation](https://github.com/
|
|
194
|
+
* 📢 Please help us translate context methods to your language! See [italian translation](https://github.com/codeceptjs/CodeceptJS/blob/master/translations/it-IT.js#L3) as an example and send [patches to vocabularies](https://github.com/codeceptjs/CodeceptJS/tree/master/translations).
|
|
168
195
|
* allurePlugin: Added `say` comments to allure reports by @PeterNgTr.
|
|
169
196
|
* Fixed no custom output folder created when executed with run-worker. Fix by @PeterNgTr
|
|
170
197
|
* [Puppeteer] Fixed error description for context element not found. See #2065. Fix by @PeterNgTr
|
|
@@ -249,7 +276,7 @@ I.click('$register_button');
|
|
|
249
276
|
Changed pressKey method to resolve issues and extend functionality.
|
|
250
277
|
* Did not properly recognize 'Meta' (or 'Command') as modifier key.
|
|
251
278
|
* Right modifier keys did not work in WebDriver using JsonWireProtocol.
|
|
252
|
-
* 'Shift' +
|
|
279
|
+
* 'Shift' + 'key' combination would not reflect actual keyboard behavior.
|
|
253
280
|
* Respect sequence with multiple modifier keys passed to pressKey.
|
|
254
281
|
* Added support to automatic change operation modifier key based on operating system.
|
|
255
282
|
* [Puppeteer][WebDriver] Added `pressKeyUp` and `pressKeyDown` to press and release modifier keys like `Control` or `Shift`. By @martomo.
|
|
@@ -369,7 +396,7 @@ I.mockRequest('POST', '/users', { user: { name: 'fake' }});
|
|
|
369
396
|
|
|
370
397
|
## 2.1.5
|
|
371
398
|
|
|
372
|
-
* **EXPERIMENTAL** [Wix Detox support](https://github.com/
|
|
399
|
+
* **EXPERIMENTAL** [Wix Detox support](https://github.com/codeceptjs/detox-helper) introduced as standalone helper. Provides a faster alternative to Appium for mobile testing.
|
|
373
400
|
* Saving successful commands inside interactive pause into `_output/cli-history` file. By @hubidu
|
|
374
401
|
* Fixed hanging error handler inside scenario. See #1721 by @haily-lgc.
|
|
375
402
|
* Fixed by @Vorobeyko: tests did not fail when an exception was raised in async bootstrap.
|
|
@@ -602,7 +629,7 @@ Use it with `FileSystem` helper to test availability of a file:
|
|
|
602
629
|
* **Using `codecept.conf.js` as default configuration format**
|
|
603
630
|
* Fixed "enametoolong" error when saving screenshots for data driven tests by @PeterNgTr
|
|
604
631
|
* Updated NodeJS to 10 in Docker image
|
|
605
|
-
* [Pupeteer] Add support to use WSEndpoint. Allows to execute tests remotely. [See #1350] by @gabrielcaires (https://github.com/
|
|
632
|
+
* [Pupeteer] Add support to use WSEndpoint. Allows to execute tests remotely. [See #1350] by @gabrielcaires (https://github.com/codeceptjs/CodeceptJS/pull/1350)
|
|
606
633
|
* In interactive shell [Enter] goes to next step. Improvement by @PeterNgTr.
|
|
607
634
|
* `I.say` accepts second parameter as color to print colorful comments. Improvement by @PeterNgTr.
|
|
608
635
|
|
|
@@ -1334,7 +1361,7 @@ codeceptjs run users_test.js -c tests
|
|
|
1334
1361
|
|
|
1335
1362
|
* Protractor ^5.0.0 support (while keeping ^4.0.9 compatibility)
|
|
1336
1363
|
* Fix 'fullTitle() is not a function' in exit.js by @hubidu. See #388.
|
|
1337
|
-
* [Nightmare] Fix for `waitTimeout` by @HughZurname. See #391. Resolves #236* Dockerized CodeceptJS setup by @artiomnist. [See reference](https://github.com/
|
|
1364
|
+
* [Nightmare] Fix for `waitTimeout` by @HughZurname. See #391. Resolves #236* Dockerized CodeceptJS setup by @artiomnist. [See reference](https://github.com/codeceptjs/CodeceptJS/blob/master/docker/README.md)
|
|
1338
1365
|
|
|
1339
1366
|
## 0.4.16
|
|
1340
1367
|
|
|
@@ -1433,7 +1460,7 @@ codeceptjs run -o '{ "bootstrap": "bootstrap.js"}'
|
|
|
1433
1460
|
codeceptjs run -o '{ "helpers": {"WebDriverIO": {"browser": "chrome"}}}'
|
|
1434
1461
|
```
|
|
1435
1462
|
|
|
1436
|
-
* Added [regression tests](https://github.com/
|
|
1463
|
+
* Added [regression tests](https://github.com/codeceptjs/CodeceptJS/tree/master/test/runner) for codeceptjs tests runner.
|
|
1437
1464
|
|
|
1438
1465
|
## 0.4.11
|
|
1439
1466
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# CodeceptJS
|
|
4
4
|
|
|
5
|
-
Reference: [Helpers API](https://github.com/
|
|
5
|
+
Reference: [Helpers API](https://github.com/codeceptjs/CodeceptJS/blob/master/docs) | [Demo](https://github.com/codeceptjs/codeceptjs-demo)
|
|
6
6
|
|
|
7
7
|
## Supercharged E2E Testing
|
|
8
8
|
|
|
@@ -27,13 +27,13 @@ CodeceptJS tests are:
|
|
|
27
27
|
|
|
28
28
|
CodeceptJS uses **Helper** modules to provide actions to `I` object. Currently CodeceptJS has these helpers:
|
|
29
29
|
|
|
30
|
-
* [**Puppeteer**](https://github.com/
|
|
31
|
-
* [**WebDriver**](https://github.com/
|
|
32
|
-
* [**Protractor**](https://github.com/
|
|
33
|
-
* [**TestCafe**](https://github.com/
|
|
34
|
-
* [**Nightmare**](https://github.com/
|
|
35
|
-
* [**Appium**](https://github.com/
|
|
36
|
-
* [**Detox**](https://github.com/
|
|
30
|
+
* [**Puppeteer**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Puppeteer.md) - uses Google Chrome's Puppeteer for fast headless testing.
|
|
31
|
+
* [**WebDriver**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) - uses [webdriverio](http://webdriver.io/) to run tests via WebDriver protocol.
|
|
32
|
+
* [**Protractor**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Protractor.md) - helper empowered by [Protractor](http://protractortest.org/) to run tests via WebDriver protocol.
|
|
33
|
+
* [**TestCafe**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/TestCafe.md) - cheap and fast cross-browser test automation.
|
|
34
|
+
* [**Nightmare**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Nightmare.md) - uses Electron and NightmareJS to run tests.
|
|
35
|
+
* [**Appium**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Appium.md) - for **mobile testing** with Appium
|
|
36
|
+
* [**Detox**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Detox.md) - This is a wrapper on top of Detox library, aimied to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially good for React Native apps.
|
|
37
37
|
|
|
38
38
|
And more to come...
|
|
39
39
|
|
|
@@ -113,7 +113,7 @@ Scenario('test some forms', (I) => {
|
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
All actions are performed by I object; assertions functions start with `see` function.
|
|
116
|
-
In this examples all methods of `I` are taken from WebDriver helper, see [reference](https://github.com/
|
|
116
|
+
In this examples all methods of `I` are taken from WebDriver helper, see [reference](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) to learn how to use them.
|
|
117
117
|
|
|
118
118
|
Let's execute this test with `run` command. Additional option `--steps` will show us the running process. We recommend use `--steps` or `--debug` during development.
|
|
119
119
|
|
|
@@ -268,8 +268,8 @@ When using typescript, replace `module.exports` with `export` for autocompletion
|
|
|
268
268
|
|
|
269
269
|
## Contributing
|
|
270
270
|
|
|
271
|
-
- ### [Contributing Guide](https://github.com/
|
|
272
|
-
- ### [Code of conduct](https://github.com/
|
|
271
|
+
- ### [Contributing Guide](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CONTRIBUTING.md)
|
|
272
|
+
- ### [Code of conduct](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CODE_OF_CONDUCT.md)
|
|
273
273
|
|
|
274
274
|
|
|
275
275
|
## Contributors
|
package/docs/advanced.md
CHANGED
|
@@ -159,6 +159,27 @@ Feature('My feature', {key: val});
|
|
|
159
159
|
Scenario('My scenario', {key: val}, (I) => {});
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
+
You can use this options for build your own [plugins](https://codecept.io/hooks/#plugins) with [event listners](https://codecept.io/hooks/#api). Example:
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
// for test
|
|
166
|
+
event.dispatcher.on(event.test.before, (test) => {
|
|
167
|
+
...
|
|
168
|
+
if (test.opts.key) {
|
|
169
|
+
...
|
|
170
|
+
}
|
|
171
|
+
...
|
|
172
|
+
});
|
|
173
|
+
// or for suite
|
|
174
|
+
event.dispatcher.on(event.suite.before, (suite) => {
|
|
175
|
+
...
|
|
176
|
+
if (suite.opts.key) {
|
|
177
|
+
...
|
|
178
|
+
}
|
|
179
|
+
...
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
162
183
|
### Timeout
|
|
163
184
|
|
|
164
185
|
By default there is no timeout for tests, however you can change this value for a specific suite:
|
package/docs/basics.md
CHANGED
|
@@ -213,7 +213,7 @@ I.fillField('password', secret('123456'));
|
|
|
213
213
|
|
|
214
214
|
### Assertions
|
|
215
215
|
|
|
216
|
-
In order to verify the expected behavior of a web application,
|
|
216
|
+
In order to verify the expected behavior of a web application, its content should be checked.
|
|
217
217
|
CodeceptJS provides built-in assertions for that. They start with a `see` (or `dontSee`) prefix.
|
|
218
218
|
|
|
219
219
|
The most general and common assertion is `see`, which checks visilibility of a text on a page:
|
|
@@ -296,7 +296,7 @@ Tests are written in a synchronous way. This improves the readability and mainta
|
|
|
296
296
|
While writing tests you should not think about promises, and instead should focus on the test scenario.
|
|
297
297
|
|
|
298
298
|
However, behind the scenes **all actions are wrapped in promises**, inside of the `I` object.
|
|
299
|
-
[Global promise](https://github.com/
|
|
299
|
+
[Global promise](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/recorder.js) chain is initialized before each test and all `I.*` calls will be appended to it, as well as setup and teardown.
|
|
300
300
|
|
|
301
301
|
> 📺 [Learn how CodeceptJS](https://www.youtube.com/watch?v=MDLLpHAwy_s) works with promises by watching video on YouTube
|
|
302
302
|
|
|
@@ -402,7 +402,7 @@ You can have multiple configuration files for a the same project, in this case y
|
|
|
402
402
|
npx codeceptjs run -c codecept.ci.conf.js
|
|
403
403
|
```
|
|
404
404
|
|
|
405
|
-
Tuning configuration for helpers like WebDriver, Puppeteer can be hard, as it requires good understanding of how these technologies work. Use the [`@codeceptjs/configure`](https://github.com/
|
|
405
|
+
Tuning configuration for helpers like WebDriver, Puppeteer can be hard, as it requires good understanding of how these technologies work. Use the [`@codeceptjs/configure`](https://github.com/codeceptjs/configure) package with common configuration recipes.
|
|
406
406
|
|
|
407
407
|
For instance, you can set the window size or toggle headless mode, no matter of which helpers are actually used.
|
|
408
408
|
|
|
@@ -419,7 +419,7 @@ exports.config = {
|
|
|
419
419
|
}
|
|
420
420
|
```
|
|
421
421
|
|
|
422
|
-
> ▶ See more [configuration recipes](https://github.com/
|
|
422
|
+
> ▶ See more [configuration recipes](https://github.com/codeceptjs/configure)
|
|
423
423
|
|
|
424
424
|
## Debug
|
|
425
425
|
|
|
@@ -616,7 +616,7 @@ AfterSuite((I) => {
|
|
|
616
616
|
});
|
|
617
617
|
```
|
|
618
618
|
|
|
619
|
-
[Here are some ideas](https://github.com/
|
|
619
|
+
[Here are some ideas](https://github.com/codeceptjs/CodeceptJS/pull/231#issuecomment-249554933) on where to use BeforeSuite hooks.
|
|
620
620
|
|
|
621
621
|
## Within
|
|
622
622
|
|
|
@@ -637,6 +637,7 @@ I.see('There were problems creating your account.');
|
|
|
637
637
|
```
|
|
638
638
|
|
|
639
639
|
> ⚠ `within` can cause problems when used incorrectly. If you see a weird behavior of a test try to refactor it to not use `within`. It is recommended to keep within for simplest cases when possible.
|
|
640
|
+
> Since `within` returns a Promise, it may be necessary to `await` the result even when you're not intending to use the return value.
|
|
640
641
|
|
|
641
642
|
`within` can also work with IFrames. A special `frame` locator is required to locate the iframe and get into its context.
|
|
642
643
|
|
package/docs/bdd.md
CHANGED
|
@@ -265,7 +265,7 @@ If we use hashes() with the previous exemple :
|
|
|
265
265
|
Given('I have products in my cart', (table) => { // eslint-disable-line
|
|
266
266
|
//parse the table by header
|
|
267
267
|
const tableByHeader = table.parse().hashes();
|
|
268
|
-
for (const row
|
|
268
|
+
for (const row of tableByHeader) {
|
|
269
269
|
|
|
270
270
|
// take values
|
|
271
271
|
const name = row.name;
|
|
@@ -416,4 +416,3 @@ To run only tests without features use `--tests` option:
|
|
|
416
416
|
```
|
|
417
417
|
npx codeceptjs run --tests
|
|
418
418
|
```
|
|
419
|
-
|
package/docs/books.md
CHANGED
|
@@ -7,7 +7,7 @@ editLink: false
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Books & Posts
|
|
10
|
-
> Add your own books or posts to our [Wiki Page](https://github.com/
|
|
10
|
+
> Add your own books or posts to our [Wiki Page](https://github.com/codeceptjs/CodeceptJS/wiki/Books-&-Posts)
|
|
11
11
|
### [Practical End 2 End Testing with CodeceptJS](https://leanpub.com/codeceptjs/)
|
|
12
12
|
|
|
13
13
|
A book by **Paul Vincent Beigang**
|
package/docs/build/Appium.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
let webdriverio;
|
|
2
2
|
let wdioV4;
|
|
3
|
-
let SCREEN_SIZE;
|
|
4
3
|
|
|
5
4
|
const fs = require('fs');
|
|
6
5
|
const requireg = require('requireg');
|
|
7
6
|
|
|
8
7
|
const Webdriver = require('./WebDriver');
|
|
9
8
|
const AssertionFailedError = require('../assert/error');
|
|
10
|
-
const truth = require('../assert/truth')
|
|
9
|
+
const { truth } = require('../assert/truth');
|
|
11
10
|
const recorder = require('../recorder');
|
|
12
11
|
const Locator = require('../locator');
|
|
13
12
|
const ConnectionRefused = require('./errors/ConnectionRefused');
|
package/docs/build/FileSystem.js
CHANGED
|
@@ -3,9 +3,9 @@ const path = require('path');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
5
|
const Helper = require('../helper');
|
|
6
|
-
const fileExists = require('../utils')
|
|
7
|
-
const fileIncludes = require('../assert/include')
|
|
8
|
-
const fileEquals = require('../assert/equal')
|
|
6
|
+
const { fileExists } = require('../utils');
|
|
7
|
+
const { fileIncludes } = require('../assert/include');
|
|
8
|
+
const { fileEquals } = require('../assert/equal');
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Helper for testing filesystem.
|
package/docs/build/Nightmare.js
CHANGED
|
@@ -3,11 +3,11 @@ const requireg = require('requireg');
|
|
|
3
3
|
const urlResolve = require('url').resolve;
|
|
4
4
|
|
|
5
5
|
const Helper = require('../helper');
|
|
6
|
-
const stringIncludes = require('../assert/include')
|
|
7
|
-
const urlEquals = require('../assert/equal')
|
|
8
|
-
const equals = require('../assert/equal')
|
|
9
|
-
const empty = require('../assert/empty')
|
|
10
|
-
const truth = require('../assert/truth')
|
|
6
|
+
const { includes: stringIncludes } = require('../assert/include');
|
|
7
|
+
const { urlEquals } = require('../assert/equal');
|
|
8
|
+
const { equals } = require('../assert/equal');
|
|
9
|
+
const { empty } = require('../assert/empty');
|
|
10
|
+
const { truth } = require('../assert/truth');
|
|
11
11
|
const Locator = require('../locator');
|
|
12
12
|
const ElementNotFound = require('./errors/ElementNotFound');
|
|
13
13
|
const {
|
|
@@ -1600,6 +1600,82 @@ class Nightmare extends Helper {
|
|
|
1600
1600
|
return this.browser.refresh();
|
|
1601
1601
|
}
|
|
1602
1602
|
|
|
1603
|
+
/**
|
|
1604
|
+
* Saves screenshot of the specified locator to ouput folder (set in codecept.json or codecept.conf.js).
|
|
1605
|
+
* Filename is relative to output folder.
|
|
1606
|
+
*
|
|
1607
|
+
* ```js
|
|
1608
|
+
* I.saveElementScreenshot(`#submit`,'debug.png');
|
|
1609
|
+
* ```
|
|
1610
|
+
*
|
|
1611
|
+
* @param {string|object} locator element located by CSS|XPath|strict locator.
|
|
1612
|
+
* @param {string} fileName file name to save.
|
|
1613
|
+
*
|
|
1614
|
+
*/
|
|
1615
|
+
async saveElementScreenshot(locator, fileName) {
|
|
1616
|
+
const outputFile = screenshotOutputFolder(fileName);
|
|
1617
|
+
|
|
1618
|
+
const rect = await this.grabElementBoundingRect(locator);
|
|
1619
|
+
|
|
1620
|
+
const button_clip = {
|
|
1621
|
+
x: Math.floor(rect.x),
|
|
1622
|
+
y: Math.floor(rect.y),
|
|
1623
|
+
width: Math.floor(rect.width),
|
|
1624
|
+
height: Math.floor(rect.height),
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1627
|
+
this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
|
|
1628
|
+
// take the screenshot
|
|
1629
|
+
await this.browser.screenshot(outputFile, button_clip);
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
/**
|
|
1633
|
+
* Grab the width, height, location of given locator.
|
|
1634
|
+
* Provide `width` or `height`as second param to get your desired prop.
|
|
1635
|
+
* Resumes test execution, so **should be used inside an async function with `await`** operator.
|
|
1636
|
+
*
|
|
1637
|
+
* Returns an object with `x`, `y`, `width`, `height` keys.
|
|
1638
|
+
*
|
|
1639
|
+
* ```js
|
|
1640
|
+
* const value = await I.grabElementBoundingRect('h3');
|
|
1641
|
+
* // value is like { x: 226.5, y: 89, width: 527, height: 220 }
|
|
1642
|
+
* ```
|
|
1643
|
+
*
|
|
1644
|
+
* To get only one metric use second parameter:
|
|
1645
|
+
*
|
|
1646
|
+
* ```js
|
|
1647
|
+
* const width = await I.grabElementBoundingRect('h3', 'width');
|
|
1648
|
+
* // width == 527
|
|
1649
|
+
* ```
|
|
1650
|
+
* @param {string|object} locator element located by CSS|XPath|strict locator.
|
|
1651
|
+
* @param {string} elementSize x, y, width or height of the given element.
|
|
1652
|
+
* @returns {object} Element bounding rectangle
|
|
1653
|
+
*/
|
|
1654
|
+
async grabElementBoundingRect(locator, prop) {
|
|
1655
|
+
locator = new Locator(locator, 'css');
|
|
1656
|
+
|
|
1657
|
+
const rect = await this.browser.evaluate(async (by, locator) => {
|
|
1658
|
+
// store the button in a variable
|
|
1659
|
+
|
|
1660
|
+
const build_cluster_btn = await window.codeceptjs.findElement(by, locator);
|
|
1661
|
+
|
|
1662
|
+
// use the getClientRects() function on the button to determine
|
|
1663
|
+
// the size and location
|
|
1664
|
+
const rect = build_cluster_btn.getBoundingClientRect();
|
|
1665
|
+
|
|
1666
|
+
// convert the rectangle to a clip object and return it
|
|
1667
|
+
return {
|
|
1668
|
+
x: rect.left,
|
|
1669
|
+
y: rect.top,
|
|
1670
|
+
width: rect.width,
|
|
1671
|
+
height: rect.height,
|
|
1672
|
+
};
|
|
1673
|
+
}, locator.type, locator.value);
|
|
1674
|
+
|
|
1675
|
+
if (prop) return rect[prop];
|
|
1676
|
+
return rect;
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1603
1679
|
/**
|
|
1604
1680
|
* Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
|
|
1605
1681
|
* Filename is relative to output folder.
|
package/docs/build/Playwright.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const requireg = require('requireg');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const fsExtra = require('fs-extra');
|
|
5
4
|
|
|
6
5
|
const Helper = require('../helper');
|
|
7
6
|
const Locator = require('../locator');
|
|
@@ -11,7 +10,7 @@ const { urlEquals } = require('../assert/equal');
|
|
|
11
10
|
const { equals } = require('../assert/equal');
|
|
12
11
|
const { empty } = require('../assert/empty');
|
|
13
12
|
const { truth } = require('../assert/truth');
|
|
14
|
-
|
|
13
|
+
|
|
15
14
|
const {
|
|
16
15
|
xpathLocator,
|
|
17
16
|
ucfirst,
|
|
@@ -160,7 +159,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
160
159
|
* }
|
|
161
160
|
* ```
|
|
162
161
|
*
|
|
163
|
-
* #### Example #6:
|
|
162
|
+
* #### Example #6: Launch tests emulating iPhone 6
|
|
164
163
|
*
|
|
165
164
|
*
|
|
166
165
|
*
|
|
@@ -234,6 +233,7 @@ class Playwright extends Helper {
|
|
|
234
233
|
keepBrowserState: false,
|
|
235
234
|
show: false,
|
|
236
235
|
defaultPopupAction: 'accept',
|
|
236
|
+
ignoreHTTPSErrors: false, // Adding it here o that context can be set up to ignore the SSL errors
|
|
237
237
|
};
|
|
238
238
|
|
|
239
239
|
config = Object.assign(defaults, config);
|
|
@@ -348,6 +348,9 @@ class Playwright extends Helper {
|
|
|
348
348
|
await this.executeScript('localStorage.clear();').catch((err) => {
|
|
349
349
|
if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
|
|
350
350
|
});
|
|
351
|
+
await this.executeScript('sessionStorage.clear();').catch((err) => {
|
|
352
|
+
if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
|
|
353
|
+
});
|
|
351
354
|
}
|
|
352
355
|
// await this.closeOtherTabs();
|
|
353
356
|
return this.browser;
|
|
@@ -546,7 +549,7 @@ class Playwright extends Helper {
|
|
|
546
549
|
this.browser.on('targetchanged', (target) => {
|
|
547
550
|
this.debugSection('Url', target.url());
|
|
548
551
|
});
|
|
549
|
-
this.browserContext = await this.browser.newContext({ acceptDownloads: true, ...this.options.emulate })
|
|
552
|
+
this.browserContext = await this.browser.newContext({ ignoreHTTPSErrors: this.options.ignoreHTTPSErrors, acceptDownloads: true, ...this.options.emulate });// Adding the HTTPSError ignore in the context so that we can ignore those errors
|
|
550
553
|
|
|
551
554
|
const existingPages = await this.browserContext.pages();
|
|
552
555
|
|
|
@@ -722,7 +725,7 @@ class Playwright extends Helper {
|
|
|
722
725
|
assertElementExists(els);
|
|
723
726
|
|
|
724
727
|
// Use manual mouse.move instead of .hover() so the offset can be added to the coordinates
|
|
725
|
-
const { x, y } = await els[0]
|
|
728
|
+
const { x, y } = await clickablePoint(els[0]);
|
|
726
729
|
await this.page.mouse.move(x + offsetX, y + offsetY);
|
|
727
730
|
return this._waitForAction();
|
|
728
731
|
}
|
|
@@ -810,7 +813,7 @@ class Playwright extends Helper {
|
|
|
810
813
|
const els = await this._locate(locator);
|
|
811
814
|
assertElementExists(els, locator, 'Element');
|
|
812
815
|
await els[0].scrollIntoViewIfNeeded();
|
|
813
|
-
const elementCoordinates = await els[0]
|
|
816
|
+
const elementCoordinates = await clickablePoint(els[0]);
|
|
814
817
|
await this.executeScript((offsetX, offsetY) => window.scrollBy(offsetX, offsetY), { offsetX: elementCoordinates.x + offsetX, offsetY: elementCoordinates.y + offsetY });
|
|
815
818
|
} else {
|
|
816
819
|
await this.executeScript(({ offsetX, offsetY }) => window.scrollTo(offsetX, offsetY), { offsetX, offsetY });
|
|
@@ -1432,7 +1435,7 @@ class Playwright extends Helper {
|
|
|
1432
1435
|
* @param {string|string[]} key key or array of keys to press.
|
|
1433
1436
|
*
|
|
1434
1437
|
*
|
|
1435
|
-
* _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/
|
|
1438
|
+
* _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/Puppeteer#1313](https://github.com/GoogleChrome/puppeteer/issues/1313)).
|
|
1436
1439
|
*/
|
|
1437
1440
|
async pressKey(key) {
|
|
1438
1441
|
const modifiers = [];
|
|
@@ -1459,6 +1462,37 @@ class Playwright extends Helper {
|
|
|
1459
1462
|
return this._waitForAction();
|
|
1460
1463
|
}
|
|
1461
1464
|
|
|
1465
|
+
/**
|
|
1466
|
+
* Types out the given text into an active field.
|
|
1467
|
+
* To slow down typing use a second parameter, to set interval between key presses.
|
|
1468
|
+
* _Note:_ Should be used when [`fillField`](#fillfield) is not an option.
|
|
1469
|
+
*
|
|
1470
|
+
* ```js
|
|
1471
|
+
* // passing in a string
|
|
1472
|
+
* I.type('Type this out.');
|
|
1473
|
+
*
|
|
1474
|
+
* // typing values with a 100ms interval
|
|
1475
|
+
* I.type('4141555311111111', 100);
|
|
1476
|
+
*
|
|
1477
|
+
* // passing in an array
|
|
1478
|
+
* I.type(['T', 'E', 'X', 'T']);
|
|
1479
|
+
* ```
|
|
1480
|
+
*
|
|
1481
|
+
* @param {string|string[]} key or array of keys to type.
|
|
1482
|
+
* @param {?number} [delay=null] (optional) delay in ms between key presses
|
|
1483
|
+
*
|
|
1484
|
+
*/
|
|
1485
|
+
async type(keys, delay = null) {
|
|
1486
|
+
if (!Array.isArray(keys)) {
|
|
1487
|
+
keys = keys.split('');
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
for (const key of keys) {
|
|
1491
|
+
await this.page.keyboard.press(key);
|
|
1492
|
+
if (delay) await this.wait(delay / 1000);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1462
1496
|
/**
|
|
1463
1497
|
* Fills a text field or textarea, after clearing its value, with the given string.
|
|
1464
1498
|
* Field is located by name, label, CSS, or XPath.
|
|
@@ -2176,8 +2210,8 @@ class Playwright extends Helper {
|
|
|
2176
2210
|
const src = await this._locate(locator);
|
|
2177
2211
|
assertElementExists(src, locator, 'Slider Element');
|
|
2178
2212
|
|
|
2179
|
-
// Note: Using private api
|
|
2180
|
-
const sliderSource = await src[0]
|
|
2213
|
+
// Note: Using clickablePoint private api because the .BoundingBox does not take into account iframe offsets!
|
|
2214
|
+
const sliderSource = await clickablePoint(src[0]);
|
|
2181
2215
|
|
|
2182
2216
|
// Drag start point
|
|
2183
2217
|
await this.page.mouse.move(sliderSource.x, sliderSource.y, { steps: 5 });
|
|
@@ -2216,6 +2250,29 @@ class Playwright extends Helper {
|
|
|
2216
2250
|
return array.length === 1 ? array[0] : array;
|
|
2217
2251
|
}
|
|
2218
2252
|
|
|
2253
|
+
/**
|
|
2254
|
+
* Saves screenshot of the specified locator to ouput folder (set in codecept.json or codecept.conf.js).
|
|
2255
|
+
* Filename is relative to output folder.
|
|
2256
|
+
*
|
|
2257
|
+
* ```js
|
|
2258
|
+
* I.saveElementScreenshot(`#submit`,'debug.png');
|
|
2259
|
+
* ```
|
|
2260
|
+
*
|
|
2261
|
+
* @param {string|object} locator element located by CSS|XPath|strict locator.
|
|
2262
|
+
* @param {string} fileName file name to save.
|
|
2263
|
+
*
|
|
2264
|
+
*/
|
|
2265
|
+
async saveElementScreenshot(locator, fileName) {
|
|
2266
|
+
const outputFile = screenshotOutputFolder(fileName);
|
|
2267
|
+
|
|
2268
|
+
const res = await this._locate(locator);
|
|
2269
|
+
assertElementExists(res, locator);
|
|
2270
|
+
if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`);
|
|
2271
|
+
const elem = res[0];
|
|
2272
|
+
this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
|
|
2273
|
+
return elem.screenshot({ path: outputFile, type: 'png' });
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2219
2276
|
/**
|
|
2220
2277
|
* Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
|
|
2221
2278
|
* Filename is relative to output folder.
|
|
@@ -2674,7 +2731,7 @@ class Playwright extends Helper {
|
|
|
2674
2731
|
/**
|
|
2675
2732
|
* Waits for navigation to finish. By default takes configured `waitForNavigation` option.
|
|
2676
2733
|
*
|
|
2677
|
-
* See [Pupeteer's reference](https://github.com/
|
|
2734
|
+
* See [Pupeteer's reference](https://github.com/microsoft/Playwright/blob/master/docs/api.md#pagewaitfornavigationoptions)
|
|
2678
2735
|
*
|
|
2679
2736
|
* @param {*} opts
|
|
2680
2737
|
*/
|
|
@@ -2835,7 +2892,14 @@ async function proceedClick(locator, context = null, options = {}) {
|
|
|
2835
2892
|
} else {
|
|
2836
2893
|
assertElementExists(els, locator, 'Clickable element');
|
|
2837
2894
|
}
|
|
2838
|
-
|
|
2895
|
+
/*
|
|
2896
|
+
using the force true options itself but instead dispatching a click
|
|
2897
|
+
*/
|
|
2898
|
+
if (options.force) {
|
|
2899
|
+
await els[0].dispatchEvent('click');
|
|
2900
|
+
} else {
|
|
2901
|
+
await els[0].click(options);
|
|
2902
|
+
}
|
|
2839
2903
|
const promises = [];
|
|
2840
2904
|
if (options.waitForNavigation) {
|
|
2841
2905
|
promises.push(this.waitForNavigation());
|
|
@@ -2957,9 +3021,9 @@ async function proceedDragAndDrop(sourceLocator, destinationLocator, options = {
|
|
|
2957
3021
|
const dst = await this._locate(destinationLocator);
|
|
2958
3022
|
assertElementExists(dst, destinationLocator, 'Destination Element');
|
|
2959
3023
|
|
|
2960
|
-
// Note: Using private api
|
|
2961
|
-
const dragSource = await src[0]
|
|
2962
|
-
const dragDestination = await dst[0]
|
|
3024
|
+
// Note: Using clickablePoint private api becaues the .BoundingBox does not take into account iframe offsets!
|
|
3025
|
+
const dragSource = await clickablePoint(src[0]);
|
|
3026
|
+
const dragDestination = await clickablePoint(dst[0]);
|
|
2963
3027
|
|
|
2964
3028
|
// Drag start point
|
|
2965
3029
|
await this.page.mouse.move(dragSource.x, dragSource.y, { steps: 5 });
|
|
@@ -3084,10 +3148,20 @@ function $XPath(element, selector) {
|
|
|
3084
3148
|
async function targetCreatedHandler(page) {
|
|
3085
3149
|
if (!page) return;
|
|
3086
3150
|
this.withinLocator = null;
|
|
3087
|
-
page.on('load', (
|
|
3151
|
+
page.on('load', () => {
|
|
3088
3152
|
page.$('body')
|
|
3089
3153
|
.catch(() => null)
|
|
3090
|
-
.then(context =>
|
|
3154
|
+
.then(async context => {
|
|
3155
|
+
if (this.context._type === 'Frame') {
|
|
3156
|
+
// we are inside iframe?
|
|
3157
|
+
const frameEl = await this.context.frameElement();
|
|
3158
|
+
this.context = await frameEl.contentFrame();
|
|
3159
|
+
return;
|
|
3160
|
+
}
|
|
3161
|
+
// if context element was in iframe - keep it
|
|
3162
|
+
// if (await this.context.ownerFrame()) return;
|
|
3163
|
+
this.context = context;
|
|
3164
|
+
});
|
|
3091
3165
|
});
|
|
3092
3166
|
page.on('console', (msg) => {
|
|
3093
3167
|
this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg._text || '') + msg.args().join(' '));
|
|
@@ -3106,7 +3180,7 @@ async function targetCreatedHandler(page) {
|
|
|
3106
3180
|
}
|
|
3107
3181
|
|
|
3108
3182
|
// List of key values to key definitions
|
|
3109
|
-
// https://github.com/
|
|
3183
|
+
// https://github.com/puppeteer/puppeteer/blob/v1.20.0/lib/USKeyboardLayout.js
|
|
3110
3184
|
const keyDefinitionMap = {
|
|
3111
3185
|
/* eslint-disable quote-props */
|
|
3112
3186
|
'0': 'Digit0',
|
|
@@ -3170,3 +3244,12 @@ function getNormalizedKey(key) {
|
|
|
3170
3244
|
}
|
|
3171
3245
|
return normalizedKey;
|
|
3172
3246
|
}
|
|
3247
|
+
|
|
3248
|
+
async function clickablePoint(el) {
|
|
3249
|
+
const rect = await el.boundingBox();
|
|
3250
|
+
if (!rect) throw new ElementNotFound(el);
|
|
3251
|
+
const {
|
|
3252
|
+
x, y, width, height,
|
|
3253
|
+
} = rect;
|
|
3254
|
+
return { x: x + width / 2, y: y + height / 2 };
|
|
3255
|
+
}
|