Skip to content

Commit 4534152

Browse files
authored
Puppeteer fixes (codeceptjs#1136)
* improved bdd chapter, acceptance and changedlog * fixed puppeteer
1 parent 368abac commit 4534152

File tree

4 files changed

+73
-43
lines changed

4 files changed

+73
-43
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.3.1
2+
3+
* [Puppeteer] Fixed process hanging for 30 seconds. Page loading timeout default via `getPageTimeout` set 0 seconds.
4+
* [Puppeteer] Improved displaying client-side console messages in debug mode.
5+
* [Puppeteer] Fixed closing sessions in `restart:false` mode for multi-session mode.
6+
17
## 1.3.0
28

39
* **Cucumber-style BDD Introduced [Gherkin support](https://codecept.io/bdd). Thanks to [David Vins](https://github.com/dvins) and [Omedym](https://www.omedym.com) for sponsoring this feature**.
@@ -30,6 +36,8 @@ Run it with `--features --steps` flag:
3036
codeceptjs run --steps --features
3137
```
3238

39+
---
40+
3341
* **Brekaing Chnage** `run` command now uses relative path + test name to run exactly one test file.
3442

3543
Previous behavior (removed):
@@ -43,6 +51,7 @@ codeceptjs run tests/basic_test.js
4351
```
4452
This change allows using auto-completion when running a specific test.
4553

54+
---
4655

4756
* Nested steps output enabled for page objects.
4857
* to see high-level steps only run tests with `--steps` flag.

docs/basics.md

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -217,37 +217,9 @@ Scenario("Stop me faster", {timeout: 1000}, (I) => {});
217217
Scenario("Don't stop me", {timeout: 0}, (I) => {});
218218
```
219219

220-
### Retries
220+
## Retries
221221

222-
#### Retry Feature
223-
224-
Browser tests can be very fragile and some time you need to re run the few times just to make them pass.
225-
This can be done with `retries` option added to `Feature` declaration.
226-
227-
CodeceptJS implements retries the same way [Mocha do](https://mochajs.org#retry-tests);
228-
You can set number of a retries for a feature:
229-
230-
```js
231-
Feature('Complex JS Stuff').retry(3);
232-
```
233-
234-
Every Scenario inside this feature will be rerun 3 times.
235-
You can make an exception for a specific scenario by passing `retries` option to a Scenario.
236-
237-
#### Retry Scenario
238-
239-
```js
240-
Scenario('Really complex', (I) => {
241-
// test goes here
242-
}).retry(2);
243-
244-
// alternative
245-
Scenario('Really complex', { retries: 2 }, (I) => {});
246-
```
247-
248-
This scenario will be restarted two times on a failure
249-
250-
#### Retry Step
222+
### Retry Step
251223

252224
If you have a step which often fails you can retry execution for this single step.
253225
Use `retry()` function before an action to ask CodeceptJS to retry this step on failure:
@@ -281,6 +253,36 @@ I.retry({
281253

282254
Pass a function to `when` option to retry only when error matches the expected one.
283255

256+
257+
### Retry Scenario
258+
259+
When you need to rerun scenarios few times just add `retries` option added to `Scenario` declaration.
260+
261+
CodeceptJS implements retries the same way [Mocha do](https://mochajs.org#retry-tests);
262+
You can set number of a retries for a feature:
263+
264+
```js
265+
Scenario('Really complex', (I) => {
266+
// test goes here
267+
}).retry(2);
268+
269+
// alternative
270+
Scenario('Really complex', { retries: 2 }, (I) => {});
271+
```
272+
273+
This scenario will be restarted two times on a failure.
274+
275+
### Retry Feature
276+
277+
To set this option for all scenarios in a file, add retry to a feature:
278+
279+
```js
280+
Feature('Complex JS Stuff').retry(3);
281+
```
282+
283+
Every Scenario inside this feature will be rerun 3 times.
284+
You can make an exception for a specific scenario by passing `retries` option to a Scenario.
285+
284286
---
285287

286288
### done()

docs/bdd.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ Every step in this scenario requires a code which defines it.
7171

7272
## Gherkin
7373

74-
Let's learn some more about Gherkin format and then we will see how to execute it with CodeceptJS. We can enable Gherkin for current project by running `gherkin:init` command:
74+
Let's learn some more about Gherkin format and then we will see how to execute it with CodeceptJS. We can enable Gherkin for current project by running `gherkin:init` command on **already initialized project**:
7575

7676
```
7777
codeceptjs gherkin:init
7878
```
7979

80-
It will add `gherkin` section to config. It will also prepare directories for features and step definition. And it will create the first feature file for you.
80+
It will add `gherkin` section to the current config. It will also prepare directories for features and step definition. And it will create the first feature file for you.
8181

8282
### Features
8383

lib/helper/Puppeteer.js

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ const { empty } = require('../assert/empty');
99
const { truth } = require('../assert/truth');
1010
const {
1111
xpathLocator,
12+
ucfirst,
1213
fileExists,
1314
clearString,
14-
decodeUrl,
1515
chunkArray,
1616
convertCssPropertiesToCamelCase,
1717
} = require('../utils');
@@ -49,8 +49,8 @@ const consoleLogStore = new Console();
4949
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
5050
* * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` is set to false.
5151
* * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
52-
* * `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)
53-
* * `getPageTimeout` (optional, default: '30000') config option to set maximum navigation time in milliseconds. Default is 30 seconds. Pass 0 to disable timeout.
52+
* * `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.
53+
* * `getPageTimeout` (optional, default: '0') config option to set maximum navigation time in milliseconds.
5454
* * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
5555
* * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
5656
* * `userAgent`: (optional) user-agent string.
@@ -63,7 +63,7 @@ const consoleLogStore = new Console();
6363
* }
6464
* ```
6565
*
66-
* #### Sample Config
66+
* #### Example #1: Wait for 0 network connections.
6767
*
6868
* ```json
6969
* {
@@ -78,7 +78,22 @@ const consoleLogStore = new Console();
7878
* }
7979
* ```
8080
*
81-
* #### Sample Config
81+
* #### Example #2: Wait for DOMContentLoaded event and 0 netowrk connections
82+
*
83+
* ```json
84+
* {
85+
* "helpers": {
86+
* "Puppeteer" : {
87+
* "url": "http://localhost",
88+
* "restart": false,
89+
* "waitForNavigation": "networkidle0",
90+
* "waitForAction": 500
91+
* }
92+
* }
93+
* }
94+
* ```
95+
*
96+
* #### Example #3: Debug in window mode
8297
*
8398
* ```json
8499
* {
@@ -124,7 +139,7 @@ class Puppeteer extends Helper {
124139
disableScreenshots: false,
125140
uniqueScreenshotNames: false,
126141
manualStart: false,
127-
getPageTimeout: 30000,
142+
getPageTimeout: 0,
128143
waitForNavigation: 'load',
129144
restart: true,
130145
keepCookies: false,
@@ -179,6 +194,12 @@ class Puppeteer extends Helper {
179194

180195
async _after() {
181196
if (!this.isRunning) return;
197+
198+
// close other sessions
199+
const contexts = this.browser.browserContexts();
200+
contexts.shift();
201+
await Promise.all(contexts.map(c => c.close()));
202+
182203
if (this.options.restart) {
183204
this.isRunning = false;
184205
return this._stopBrowser();
@@ -194,9 +215,6 @@ class Puppeteer extends Helper {
194215
if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
195216
});
196217
await this.closeOtherTabs();
197-
const contexts = this.browser.browserContexts();
198-
contexts.shift();
199-
await Promise.all(contexts.map(c => c.close()));
200218
return this.browser;
201219
}
202220

@@ -301,6 +319,7 @@ class Puppeteer extends Helper {
301319
this._addPopupListener(page);
302320
this.page = page;
303321
if (!page) return;
322+
page.setDefaultNavigationTimeout(this.options.getPageTimeout);
304323
this.context = await page.$('body');
305324
await page.bringToFront();
306325
}
@@ -441,7 +460,7 @@ class Puppeteer extends Helper {
441460
if (url.indexOf('http') !== 0) {
442461
url = this.options.url + url;
443462
}
444-
await this.page.goto(url, { timeout: this.options.getPageTimeout, waitUntil: this.options.waitForNavigation });
463+
await this.page.goto(url, { waitUntil: this.options.waitForNavigation });
445464
return this._waitForAction();
446465
}
447466

@@ -2002,7 +2021,7 @@ function targetCreatedHandler(page) {
20022021
this.withinLocator = null;
20032022
page.on('load', frame => this.context = page.$('body'));
20042023
page.on('console', (msg) => {
2005-
this.debugSection(msg.type(), msg.args().join(' '));
2024+
this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg._text || '') + msg.args().join(' '));
20062025
consoleLogStore.add(msg);
20072026
});
20082027
}

0 commit comments

Comments
 (0)