-
Notifications
You must be signed in to change notification settings - Fork 674
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[docs] Describe request hooks (#2309)
* Describe request hooks * Address Helen's remarks * Revert an example * Specify the body type - Buffer * Change structure and address remarks * Add real-life examples * Update TOC * Fix broken links * Update README.md * Update README.md * Update README.md * Update attaching-hooks-to-tests-and-fixtures.md * Update creating-a-custom-http-request-hook.md * Update logging-http-requests.md * Update mocking-http-responses.md * Update specifying-which-requests-are-handled-by-the-hook.md * fix Mikhail's remark * fix Mikhail's remarks * attaching hooks - fix Mikhail's remarks * specifying-which-requests-are-handled -Fix remarks * creating-a-custom-http-request-hook - Fix remarks * logging-http-requests -- fix Mikhail's remark * remove Mocking from header * Remove Mocking from header * creating-a-custom-http-request-hook Fix remarks * mocking-http-responses Fix Mikhail's remarks * formatting added * remove trailing-spaces * Remove trailing spaces * mocking-http-responses.md Fix Mikhail's remarks * Remove trailing spaces * return previous permalink for Readme.md * return previous permalink for request hooks main topic * fix broken link
- Loading branch information
1 parent
ec23eb2
commit ac06c5d
Showing
10 changed files
with
747 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
...rticles/documentation/test-api/intercepting-and-mocking-http-requests/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
--- | ||
layout: docs | ||
title: Intercepting HTTP Requests | ||
permalink: /documentation/test-api/intercepting-and-mocking-http-requests/ | ||
checked: true | ||
--- | ||
# Intercepting HTTP Requests | ||
|
||
This section describes how to handle HTTP requests in your tests. TestCafe allows you to log them and mock the responses out of the box. You can also create a custom HTTP request hook, which allows you, for instance, to emulate authentications like **Kerberos** or **Client Certificate Authentication**. | ||
|
||
* [Logging HTTP Requests](logging-http-requests.md) | ||
* [Mocking HTTP Responses](mocking-http-responses.md) | ||
* [Creating a Custom HTTP Request Hook](creating-a-custom-http-request-hook.md) | ||
* [Specifying Which Requests are Handled by the Hook](specifying-which-requests-are-handled-by-the-hook.md) | ||
* [Attaching Hooks to Tests and Fixtures](attaching-hooks-to-tests-and-fixtures.md) | ||
|
||
## Logging HTTP Requests | ||
|
||
You can use the request logger to record HTTP requests the tested web app sends and responses it receives. For instance, you may want to make sure that the data from a remote service is correct. In this example, the test checks the DevExpress grid control's data. | ||
|
||
```js | ||
import { Selector, RequestLogger } from 'testcafe'; | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
|
||
const url = 'https://demos.devexpress.com/ASPxGridViewDemos/Exporting/Exporting.aspx'; | ||
|
||
const logger = RequestLogger({ url, method: 'post' }, { | ||
logResponseHeaders: true, | ||
logResponseBody: true | ||
}); | ||
|
||
fixture `Export` | ||
.page(url) | ||
.requestHooks(logger); | ||
|
||
test('export to csv', async t => { | ||
const exportToCSVButton = Selector('span').withText('Export to CSV'); | ||
|
||
await t | ||
.click(exportToCSVButton) | ||
.expect(logger.contains(r => r.response.statusCode === 200)).ok(); | ||
|
||
// After clicking 'Export', the response comes as a gziped CSV. | ||
// The browser unpacks the archive and gives you the file that was inside. | ||
// The test receives the archive as is. | ||
const filePath = path.join(__dirname, 'exported-grid.zip'); | ||
|
||
console.log(filePath); | ||
console.log(logger.requests[0].response.headers); | ||
|
||
fs.writeFileSync(filePath, logger.requests[0].response.body); | ||
|
||
// Here you can use 3rd party modules to | ||
// unpack the archive, parse CSV and check the data. | ||
// Or you can just manually verify the file. | ||
}); | ||
``` | ||
|
||
See [Logging HTTP Requests](logging-http-requests.md) for more information. | ||
|
||
## Mocking HTTP Responses | ||
|
||
Use TestCafe request mocker to substitute infrastructure that is difficult to deploy or that you do not want to use when testing. This can be a third-party service that charges you per pageview or an analytics service that should not log page views tests generate. | ||
|
||
```js | ||
import { Selector, RequestMock } from 'testcafe'; | ||
|
||
// A URL to which Google Analytics sends data. | ||
const collectDataGoogleAnalyticsRegExp = new RegExp('https://www.google-analytics.com/collect'); | ||
|
||
// Technically, Google Analytics sends an XHR request for a GIF image. | ||
// So, we prepare a mocked response with binary data. | ||
const mockedResponse = Buffer.from([0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01]); | ||
|
||
const mock = RequestMock() | ||
.onRequestTo(collectDataGoogleAnalyticsRegExp) | ||
|
||
// We respond to Analytics requests with the prepared data | ||
// represented as a GIF image and change the status code to 202. | ||
.respond(mockedResponse, 202, { | ||
'content-length': mockedResponse.length, | ||
'content-type': 'image/gif' | ||
}); | ||
|
||
fixture `Fixture` | ||
.page('https://devexpress.github.io/testcafe/') | ||
.requestHooks(mock); | ||
|
||
test('basic', async t => { | ||
await t | ||
.setTestSpeed(0.01) | ||
.click('.get-started-button') | ||
|
||
// During the pause, you can open DevTools and | ||
// find the request sent to Analytics | ||
// and the mocked response received. | ||
.wait(100000); | ||
}); | ||
``` | ||
|
||
See [Mocking HTTP Responses](mocking-http-responses.md) for more information. | ||
|
||
## Creating a Custom HTTP Request Hook | ||
|
||
You can create your own request hook to handle HTTP requests. | ||
|
||
The example below shows a custom hook that adds the `Authorization` header for [JWT](https://tools.ietf.org/html/rfc7519) bearer authorization. | ||
|
||
```js | ||
import { Selector, RequestHook } from 'testcafe'; | ||
|
||
class JwtBearerAuthorization extends RequestHook { | ||
constructor () { | ||
// No URL filtering applied to this hook | ||
// so it will be used for all requests. | ||
super(); | ||
} | ||
|
||
onRequest (e) { | ||
e.requestOptions.headers['Authorization'] = 'generate token here'; | ||
} | ||
} | ||
|
||
const jwtBearerAuthorization = new JwtBearerAuthorization(); | ||
|
||
fixture `Fixture` | ||
.page('<website URL>') | ||
.requestHooks(jwtBearerAuthorization); | ||
|
||
test('basic', async t => { | ||
/* some actions */ | ||
}); | ||
``` | ||
|
||
See [Creating a Custom HTTP Request Hook](creating-a-custom-http-request-hook.md) for more information. |
54 changes: 54 additions & 0 deletions
54
...intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
layout: docs | ||
title: Attaching Hooks to Tests and Fixtures | ||
permalink: /documentation/test-api/intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.html | ||
checked: false | ||
--- | ||
# Attaching Hooks to Tests and Fixtures | ||
|
||
To attach a hook to a test or fixture, use the `fixture.requestHooks` and `test.requestHooks` methods. A hook attached to a fixture handles requests from all tests in the fixture. | ||
|
||
```text | ||
fixture.requestHooks(...hook) | ||
test.requestHooks(...hook) | ||
``` | ||
|
||
You can also attach and detach hooks during test run using the `t.addRequestHooks` and `t.removeRequestHooks` methods. | ||
|
||
```text | ||
t.addRequestHooks(...hook) | ||
t.removeRequestHooks(...hooks) | ||
``` | ||
|
||
Parameter | Type | Description | ||
--------- | ---- | ------------ | ||
`hook` | RequestHook subclass | A `RequestLogger`, `RequestMock` or custom user-defined hook. | ||
|
||
The `fixture.requestHooks`, `test.requestHooks` `t.addRequestHooks` and `t.removeRequestHooks` methods use the rest operator which allows you to pass multiple hooks as parameters or arrays of hooks. | ||
|
||
```js | ||
import { RequestLogger, RequestMock } from 'testcafe'; | ||
|
||
const logger = RequestLogger('http://example.com'); | ||
const mock = RequestMock() | ||
.onRequestTo('http://external-service.com/api/') | ||
.respond({ data: 'value' }); | ||
|
||
fixture `My fixture` | ||
.page('http://example.com') | ||
.requestHooks(logger); | ||
|
||
test | ||
.requestHooks(mock) | ||
('My test', async t => { | ||
await t | ||
.click('#send-logged-request') | ||
.expect(logger.count(() => true)).eql(1) | ||
.removeRequestHooks(logger) | ||
.click('#send-unlogged-request') | ||
.expect(logger.count(() => true)).eql(1) | ||
.addRequestHooks(logger) | ||
.click('#send-logged-request') | ||
.expect(logger.count(() => true)).eql(2); | ||
}) | ||
``` |
Oops, something went wrong.