Skip to content

Commit 74a73e0

Browse files
authored
feat: mock route for ppt (#4262)
1 parent 6175f8f commit 74a73e0

File tree

6 files changed

+148
-73
lines changed

6 files changed

+148
-73
lines changed

docs/helpers/Playwright.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,7 @@ This method allows intercepting and mocking requests & responses. [Learn more ab
15051505
#### Parameters
15061506

15071507
- `url` **([string][9] | [RegExp][11])?** URL, regex or pattern for to match URL
1508-
- `handler` **[function][21]?** a function to process reques
1508+
- `handler` **[function][21]?** a function to process request
15091509

15101510
### mockTraffic
15111511

@@ -2230,7 +2230,7 @@ If no handler is passed, all mock requests for the rote are disabled.
22302230
#### Parameters
22312231

22322232
- `url` **([string][9] | [RegExp][11])?** URL, regex or pattern for to match URL
2233-
- `handler` **[function][21]?** a function to process reques
2233+
- `handler` **[function][21]?** a function to process request
22342234

22352235
### stopRecordingTraffic
22362236

docs/helpers/Puppeteer.md

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,26 @@ Type: [object][4]
3939

4040
- `url` **[string][6]** base url of website to be tested
4141
- `basicAuth` **[object][4]?** (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
42-
- `show` **[boolean][20]?** show Google Chrome window for debug.
43-
- `restart` **[boolean][20]?** restart browser between tests.
44-
- `disableScreenshots` **[boolean][20]?** don't save screenshot on failure.
45-
- `fullPageScreenshots` **[boolean][20]?** make full page screenshots on failure.
46-
- `uniqueScreenshotNames` **[boolean][20]?** option to prevent screenshot override if you have scenarios with the same name in different suites.
47-
- `trace` **[boolean][20]?** record [tracing information][24] with screenshots.
48-
- `keepTraceForPassedTests` **[boolean][20]?** save trace for passed tests.
49-
- `keepBrowserState` **[boolean][20]?** keep browser state between tests when `restart` is set to false.
50-
- `keepCookies` **[boolean][20]?** keep cookies between tests when `restart` is set to false.
42+
- `show` **[boolean][22]?** show Google Chrome window for debug.
43+
- `restart` **[boolean][22]?** restart browser between tests.
44+
- `disableScreenshots` **[boolean][22]?** don't save screenshot on failure.
45+
- `fullPageScreenshots` **[boolean][22]?** make full page screenshots on failure.
46+
- `uniqueScreenshotNames` **[boolean][22]?** option to prevent screenshot override if you have scenarios with the same name in different suites.
47+
- `trace` **[boolean][22]?** record [tracing information][26] with screenshots.
48+
- `keepTraceForPassedTests` **[boolean][22]?** save trace for passed tests.
49+
- `keepBrowserState` **[boolean][22]?** keep browser state between tests when `restart` is set to false.
50+
- `keepCookies` **[boolean][22]?** keep cookies between tests when `restart` is set to false.
5151
- `waitForAction` **[number][10]?** how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
52-
- `waitForNavigation` **[string][6]?** when to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API][23]. Array values are accepted as well.
52+
- `waitForNavigation` **[string][6]?** when to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API][25]. Array values are accepted as well.
5353
- `pressKeyDelay` **[number][10]?** delay between key presses in ms. Used when calling Puppeteers page.type(...) in fillField/appendField
5454
- `getPageTimeout` **[number][10]?** config option to set maximum navigation time in milliseconds. If the timeout is set to 0, then timeout will be disabled.
5555
- `waitForTimeout` **[number][10]?** default wait* timeout in ms.
5656
- `windowSize` **[string][6]?** default window size. Set a dimension in format WIDTHxHEIGHT like `640x480`.
5757
- `userAgent` **[string][6]?** user-agent string.
58-
- `manualStart` **[boolean][20]?** do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
58+
- `manualStart` **[boolean][22]?** do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
5959
- `browser` **[string][6]?** can be changed to `firefox` when using [puppeteer-firefox][2].
60-
- `chrome` **[object][4]?** pass additional [Puppeteer run options][25].
61-
- `highlightElement` **[boolean][20]?** highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
60+
- `chrome` **[object][4]?** pass additional [Puppeteer run options][27].
61+
- `highlightElement` **[boolean][22]?** highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
6262

6363

6464

@@ -1255,6 +1255,21 @@ I.seeFile('avatar.jpg');
12551255
12561256
- `downloadPath` **[string][6]** change this parameter to set another directory for saving
12571257
1258+
### mockRoute
1259+
1260+
Mocks network request using [`Request Interception`][17]
1261+
1262+
```js
1263+
I.mockRoute(/(.png$)|(.jpg$)/, route => route.abort());
1264+
```
1265+
1266+
This method allows intercepting and mocking requests & responses. [Learn more about it][17]
1267+
1268+
#### Parameters
1269+
1270+
- `url` **([string][6] | [RegExp][18])?** URL, regex or pattern for to match URL
1271+
- `handler` **[function][12]?** a function to process request
1272+
12581273
### moveCursorTo
12591274
12601275
Moves cursor to element matched by locator.
@@ -1287,11 +1302,11 @@ I.openNewTab();
12871302
12881303
### pressKey
12891304
1290-
_Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/puppeteer#1313][17]).
1305+
_Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/puppeteer#1313][19]).
12911306
12921307
Presses a key in the browser (on a focused element).
12931308
1294-
_Hint:_ For populating text field or textarea, it is recommended to use [`fillField`][18].
1309+
_Hint:_ For populating text field or textarea, it is recommended to use [`fillField`][20].
12951310
12961311
```js
12971312
I.pressKey('Backspace');
@@ -1358,7 +1373,7 @@ Returns **void** automatically synchronized promise through #recorder
13581373
13591374
Presses a key in the browser and leaves it in a down state.
13601375
1361-
To make combinations with modifier key and user operation (e.g. `'Control'` + [`click`][19]).
1376+
To make combinations with modifier key and user operation (e.g. `'Control'` + [`click`][21]).
13621377
13631378
```js
13641379
I.pressKeyDown('Control');
@@ -1376,7 +1391,7 @@ Returns **void** automatically synchronized promise through #recorder
13761391
13771392
Releases a key in the browser which was previously set to a down state.
13781393
1379-
To make combinations with modifier key and user operation (e.g. `'Control'` + [`click`][19]).
1394+
To make combinations with modifier key and user operation (e.g. `'Control'` + [`click`][21]).
13801395
13811396
```js
13821397
I.pressKeyDown('Control');
@@ -1470,7 +1485,7 @@ I.saveScreenshot('debug.png', true) //resizes to available scrollHeight and scro
14701485
#### Parameters
14711486
14721487
- `fileName` **[string][6]** file name to save.
1473-
- `fullPage` **[boolean][20]** (optional, `false` by default) flag to enable fullscreen screenshot mode.
1488+
- `fullPage` **[boolean][22]** (optional, `false` by default) flag to enable fullscreen screenshot mode.
14741489
14751490
Returns **void** automatically synchronized promise through #recorder
14761491
@@ -1862,6 +1877,18 @@ I.setPuppeteerRequestHeaders({
18621877
18631878
- `customHeaders` **[object][4]** headers to set
18641879
1880+
### stopMockingRoute
1881+
1882+
Stops network mocking created by `mockRoute`.
1883+
1884+
```js
1885+
I.stopMockingRoute(/(.png$)|(.jpg$)/);
1886+
```
1887+
1888+
#### Parameters
1889+
1890+
- `url` **([string][6] | [RegExp][18])?** URL, regex or pattern for to match URL
1891+
18651892
### switchTo
18661893
18671894
Switches frame or in case of null locator reverts to parent.
@@ -1907,7 +1934,7 @@ I.switchToPreviousTab(2);
19071934
19081935
Types out the given text into an active field.
19091936
To slow down typing use a second parameter, to set interval between key presses.
1910-
_Note:_ Should be used when [`fillField`][18] is not an option.
1937+
_Note:_ Should be used when [`fillField`][20] is not an option.
19111938
19121939
```js
19131940
// passing in a string
@@ -1958,7 +1985,7 @@ Use Puppeteer API inside a test.
19581985
First argument is a description of an action.
19591986
Second argument is async function that gets this helper as parameter.
19601987
1961-
{ [`page`][21], [`browser`][22] } from Puppeteer API are available.
1988+
{ [`page`][23], [`browser`][24] } from Puppeteer API are available.
19621989
19631990
```js
19641991
I.usePuppeteerTo('emulate offline mode', async ({ page }) {
@@ -2110,7 +2137,7 @@ Returns **void** automatically synchronized promise through #recorder
21102137
21112138
Waits for navigation to finish. By default, takes configured `waitForNavigation` option.
21122139
2113-
See [Puppeteer's reference][23]
2140+
See [Puppeteer's reference][25]
21142141
21152142
#### Parameters
21162143
@@ -2313,20 +2340,24 @@ Returns **void** automatically synchronized promise through #recorder
23132340
23142341
[16]: https://codecept.io/helpers/FileSystem
23152342
2316-
[17]: https://github.com/GoogleChrome/puppeteer/issues/1313
2343+
[17]: https://pptr.dev/next/guides/request-interception
2344+
2345+
[18]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RegExp
2346+
2347+
[19]: https://github.com/GoogleChrome/puppeteer/issues/1313
23172348
2318-
[18]: #fillfield
2349+
[20]: #fillfield
23192350
2320-
[19]: #click
2351+
[21]: #click
23212352
2322-
[20]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
2353+
[22]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
23232354
2324-
[21]: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-page
2355+
[23]: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-page
23252356
2326-
[22]: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browser
2357+
[24]: https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browser
23272358
2328-
[23]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions
2359+
[25]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions
23292360
2330-
[24]: https://pptr.dev/api/puppeteer.tracing
2361+
[26]: https://pptr.dev/api/puppeteer.tracing
23312362
2332-
[25]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions
2363+
[27]: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions

docs/puppeteer.md

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -216,52 +216,28 @@ await eachElement(
216216

217217
> ℹ Learn more about [eachElement plugin](/plugins/#eachelement)
218218
219-
## Mocking Requests
219+
## Mocking Network Requests <Badge text="Since 3.5.16" type="warning"/>
220220

221-
Web application sends various requests to local services (Rest API, GraphQL) or to 3rd party services (CDNS, Google Analytics, etc).
222-
When you run tests with Puppeteer you can control those requests by mocking them. For instance, you can speed up your tests by blocking trackers, Google Analytics, and other services you don't control.
223-
224-
Also you can replace real request with a one explicitly defined. This is useful when you want to isolate application testing from a backend. For instance, if you don't want to save data to database, and you know the request which performs save, you can mock the request, so application will treat this as valid response, but no data will be actually saved.
225-
226-
To mock requests enable additional helper [MockRequest](/helpers/MockRequest) (which is based on Polly.js).
221+
Network requests & responses can be mocked and modified. Use `mockRoute` which strictly follows [Puppeteer's `setRequestInterception` API](https://pptr.dev/next/api/puppeteer.page.setrequestinterception).
227222

228223
```js
229-
helpers: {
230-
Puppeteer: {
231-
// regular Puppeteer config here
232-
},
233-
MockRequest: {}
234-
}
235-
```
236-
237-
And install additional packages:
238-
239-
```
240-
npm i @pollyjs/core @pollyjs/adapter-puppeteer --save-dev
241-
```
242-
243-
After an installation function `mockRequest` will be added to `I` object. You can use it to explicitly define which requests to block and which response they should return instead:
244-
245-
```js
246-
// block all Google Analytics calls
247-
I.mockRequest('/google-analytics/*path', 200);
248-
// return an empty successful response
249-
I.mockRequest('GET', '/api/users', 200);
250-
// block post requests to /api/users and return predefined object
251-
I.mockRequest('POST', '/api/users', { user: 'davert' });
252-
// return error request with body
253-
I.mockRequest('GET', '/api/users/1', 404, { error: 'User not found' });
254-
```
255-
256-
> See [`mockRequest` API](/helpers/MockRequest#mockrequest)
224+
I.mockRoute('https://reqres.in/api/comments/1', request => {
225+
request.respond({
226+
status: 200,
227+
headers: { 'Access-Control-Allow-Origin': '*' },
228+
contentType: 'application/json',
229+
body: '{"name": "this was mocked" }',
230+
});
231+
})
257232

258-
To see `mockRequest` method in intellisense auto completion don't forget to run `codeceptjs def` command:
233+
I.mockRoute('**/*.{png,jpg,jpeg}', route => route.abort());
259234

260-
```
261-
npx codeceptjs def
235+
// To disable mocking for a route call `stopMockingRoute`
236+
// for previously mocked URL
237+
I.stopMockingRoute('**/*.{png,jpg,jpeg}'
262238
```
263239
264-
Mocking rules will be kept while a test is running. To stop mocking use `I.stopMocking()` command
240+
To master request intercepting [use `HTTPRequest` object](https://pptr.dev/next/api/puppeteer.httprequest) object passed into mock request handler.
265241
266242
267243
## Accessing Puppeteer API

lib/helper/Playwright.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,7 +2957,7 @@ class Playwright extends Helper {
29572957
* This method allows intercepting and mocking requests & responses. [Learn more about it](https://playwright.dev/docs/network#handle-requests)
29582958
*
29592959
* @param {string|RegExp} [url] URL, regex or pattern for to match URL
2960-
* @param {function} [handler] a function to process reques
2960+
* @param {function} [handler] a function to process request
29612961
*/
29622962
async mockRoute(url, handler) {
29632963
return this.browserContext.route(...arguments);
@@ -2973,7 +2973,7 @@ class Playwright extends Helper {
29732973
* If no handler is passed, all mock requests for the rote are disabled.
29742974
*
29752975
* @param {string|RegExp} [url] URL, regex or pattern for to match URL
2976-
* @param {function} [handler] a function to process reques
2976+
* @param {function} [handler] a function to process request
29772977
*/
29782978
async stopMockingRoute(url, handler) {
29792979
return this.browserContext.unroute(...arguments);

lib/helper/Puppeteer.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,6 +2459,54 @@ class Puppeteer extends Helper {
24592459
if (prop) return rect[prop];
24602460
return rect;
24612461
}
2462+
2463+
/**
2464+
* Mocks network request using [`Request Interception`](https://pptr.dev/next/guides/request-interception)
2465+
*
2466+
* ```js
2467+
* I.mockRoute(/(\.png$)|(\.jpg$)/, route => route.abort());
2468+
* ```
2469+
* This method allows intercepting and mocking requests & responses. [Learn more about it](https://pptr.dev/next/guides/request-interception)
2470+
*
2471+
* @param {string|RegExp} [url] URL, regex or pattern for to match URL
2472+
* @param {function} [handler] a function to process request
2473+
*/
2474+
async mockRoute(url, handler) {
2475+
await this.page.setRequestInterception(true);
2476+
2477+
this.page.on('request', interceptedRequest => {
2478+
if (interceptedRequest.url().match(url)) {
2479+
// @ts-ignore
2480+
handler(interceptedRequest);
2481+
} else {
2482+
interceptedRequest.continue();
2483+
}
2484+
});
2485+
}
2486+
2487+
/**
2488+
* Stops network mocking created by `mockRoute`.
2489+
*
2490+
* ```js
2491+
* I.stopMockingRoute(/(\.png$)|(\.jpg$)/);
2492+
* ```
2493+
*
2494+
* @param {string|RegExp} [url] URL, regex or pattern for to match URL
2495+
*/
2496+
async stopMockingRoute(url) {
2497+
await this.page.setRequestInterception(true);
2498+
2499+
this.page.off('request');
2500+
2501+
// Resume normal request handling for the given URL
2502+
this.page.on('request', interceptedRequest => {
2503+
if (interceptedRequest.url().includes(url)) {
2504+
interceptedRequest.continue();
2505+
} else {
2506+
interceptedRequest.continue();
2507+
}
2508+
});
2509+
}
24622510
}
24632511

24642512
module.exports = Puppeteer;

test/helper/Puppeteer_test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,26 @@ describe('Puppeteer', function () {
951951
assert.equal('TestEd Beta 2.0', title);
952952
});
953953
});
954+
955+
describe('#mockRoute, #stopMockingRoute', () => {
956+
it('should mock a route', async () => {
957+
await I.amOnPage('/form/fetch_call');
958+
await I.mockRoute('https://reqres.in/api/comments/1', request => {
959+
request.respond({
960+
status: 200,
961+
headers: { 'Access-Control-Allow-Origin': '*' },
962+
contentType: 'application/json',
963+
body: '{"name": "this was mocked" }',
964+
});
965+
});
966+
await I.click('GET COMMENTS');
967+
await I.see('this was mocked');
968+
await I.stopMockingRoute('https://reqres.in/api/comments/1');
969+
await I.click('GET COMMENTS');
970+
await I.see('data');
971+
await I.dontSee('this was mocked');
972+
});
973+
});
954974
});
955975

956976
let remoteBrowser;

0 commit comments

Comments
 (0)