Skip to content

Commit

Permalink
Add real-life examples
Browse files Browse the repository at this point in the history
  • Loading branch information
VasilyStrelyaev committed May 4, 2018
1 parent accf85d commit 0118cd1
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ checked: false
---
# Intercepting and Mocking HTTP Requests

This topic describes how you can 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 Kerberos or client certificate authentication.
This section describes how you can 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 Kerberos or client certificate authentication.

* [Logging HTTP Requests](logging-http-requests.md)
* [Mocking HTTP Responses](mocking-http-responses.md)
Expand All @@ -16,44 +16,86 @@ This topic describes how you can handle HTTP requests in your tests. TestCafe al

## Logging HTTP Requests

If you need to record the HTTP requests sent and responses received by the tested web app, use the request logger. For instance, you may want to make sure that every resource on the page loads successfully, i.e. no request ends with `404` status code.
If you need to record HTTP requests the tested web app sends and responses it receives, use the request logger. For instance, you may want to make sure that data that come from a remote service are correct. In this example, the test checks DevExpress grid control export.

```js
import { Selector, RequestLogger } from 'testcafe';
import fs from 'fs';
import path from 'path';

const logger = RequestLogger();
const url = 'https://demos.devexpress.com/ASPxGridViewDemos/Exporting/Exporting.aspx';

fixture `Fixture`
.page('https://devexpress.github.io/testcafe/example')
const logger = RequestLogger({ url, method: 'post' }, {
logResponseHeaders: true,
logResponseBody: true
});

fixture `Export`
.page(url)
.requestHooks(logger);

test('test', async t => {
// NOTE: do some test actions or wait for window.load event
await t.expect(logger.count(r => r.response.statusCode === 404)).eql(0);
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.
});
```

For more information, see [Logging HTTP Requests](logging-http-requests.md).

## Mocking HTTP Responses

Use TestCafe request mocker to substitute for infrastructure that is difficult to deploy or that you don't wish to use when testing. This can be a 3rd party service that charges you per pageview. Or just an analytics service, which is not meant to collect pageviews generated by tests.
Use TestCafe request mocker to substitute for infrastructure that is difficult to deploy or that you don't wish to use when testing. This can be a third-party service that charges you per pageview. Or just an analytics service, which is not meant to collect pageviews generated by tests.

```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('http://<site.url>/collect-analytics')
.respond({ status: 'complete' }, 200);
.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('http://<site.url>/');
.page('https://devexpress.github.io/testcafe/')
.requestHooks(mock);

test('test', async t => {
test('basic', async t => {
await t
.typeText('.username', '<username>')
.typeText('.password', '<password>')
.click('.loginBtn');
.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);
});
```

Expand All @@ -63,8 +105,32 @@ For more information, see [Mocking HTTP Responses](mocking-http-responses.md).

If you need to handle HTTP requests in a custom way, you can create your own request hook.

The example below shows a custom hook that adds the `Authorization` header for JWT 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 */
});
```

For more information, see [Creating a Custom HTTP Request Hook](creating-a-custom-http-request-hook.md).
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ var mock = RequestMock()
'server': 'nginx/1.10.3'
})
.onRequestTo(/*...*/)
.respond(Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])) // a response with binary data
.onRequestTo(/*...*/)
.respond((req, res) => { // a custom response
res.headers['x-calculated-header'] = 'calculated-value';
res.statusCode = '200';
Expand Down

0 comments on commit 0118cd1

Please sign in to comment.