Skip to content

Commit

Permalink
[docs] Describe request hooks (#2309)
Browse files Browse the repository at this point in the history
* 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
VasilyStrelyaev authored and MargaritaLoseva committed May 14, 2018
1 parent ec23eb2 commit ac06c5d
Show file tree
Hide file tree
Showing 10 changed files with 747 additions and 3 deletions.
8 changes: 7 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Documentation

> This is a development version of the documentation. The functionality described here may not be included in the current release version. Unreleased functionality may change or be dropped before the next release. Documentation for the release version is available at the [TestCafe website](https://devexpress.github.io/testcafe/documentation/getting-started/).
> This is the documentation's development version. The functionality described here may not be included in the current release version. Unreleased functionality may change or be dropped before the next release. The release version's documentation is available on the [TestCafe website](https://devexpress.github.io/testcafe/documentation/getting-started/).
* [GETTING STARTED](articles/documentation/getting-started/README.md)
* [USING TESTCAFE](articles/documentation/using-testcafe/README.md)
Expand Down Expand Up @@ -60,6 +60,12 @@
* [Assertion API](articles/documentation/test-api/assertions/assertion-api.md)
* [Obtaining Data from the Client](articles/documentation/test-api/obtaining-data-from-the-client/README.md)
* [Examples of Using Client Functions](articles/documentation/test-api/obtaining-data-from-the-client/examples-of-using-client-functions.md)
* [Intercepting HTTP Requests](articles/documentation/test-api/intercepting-and-mocking-http-requests/README.md)
* [Logging HTTP Requests](articles/documentation/test-api/intercepting-and-mocking-http-requests/logging-http-requests.md)
* [Mocking HTTP Responses](articles/documentation/test-api/intercepting-and-mocking-http-requests/mocking-http-responses.md)
* [Creating a Custom HTTP Request Hook](articles/documentation/test-api/intercepting-and-mocking-http-requests/creating-a-custom-http-request-hook.md)
* [Specifying Which Requests are Handled by the Hook](articles/documentation/test-api/intercepting-and-mocking-http-requests/specifying-which-requests-are-handled-by-the-hook.md)
* [Attaching Hooks to Tests and Fixtures](articles/documentation/test-api/intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.md)
* [Waiting for Page Elements to Appear](articles/documentation/test-api/waiting-for-page-elements-to-appear.md)
* [Authentication](articles/documentation/test-api/authentication/README.md)
* [User Roles](articles/documentation/test-api/authentication/user-roles.md)
Expand Down
4 changes: 2 additions & 2 deletions docs/articles/documentation/test-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ checked: true
---
# Test API

TestCafe allows you to write tests using both JavaScript and TypeScript.
For more information about writing tests in TypeScript, see [TypeScript Support](typescript-support.md).
TestCafe allows you to write tests using JavaScript and TypeScript (see [TypeScript Support](typescript-support.md) for more information about writing tests in TypeScript).

The following topics demonstrate how to organize test code:

Expand All @@ -20,6 +19,7 @@ The following topics describe the API used to manipulate the webpage and check i
* [Selecting Page Elements](selecting-page-elements/README.md)
* [Assertions](assertions/README.md)
* [Obtaining Data From the Client](obtaining-data-from-the-client/README.md)
* [Intercepting HTTP Requests](intercepting-and-mocking-http-requests/README.md)
* [Waiting for Page Elements to Appear](waiting-for-page-elements-to-appear.md)
* [Authentication](authentication/README.md)
* [Pausing the Test](pausing-the-test.md)
Expand Down
12 changes: 12 additions & 0 deletions docs/articles/documentation/test-api/a-z-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@ This topic lists test API members in alphabetical order.
* [httpAuth](authentication/http-authentication.md)
* [only](test-code-structure.md#skipping-tests)
* [page](test-code-structure.md#specifying-the-start-webpage)
* [requestHooks](intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.md)
* [skip](test-code-structure.md#skipping-tests)
* [RequestLogger](intercepting-and-mocking-http-requests/logging-http-requests.md)
* [contains](intercepting-and-mocking-http-requests/logging-http-requests.md#logger-methods)
* [count](intercepting-and-mocking-http-requests/logging-http-requests.md#logger-methods)
* [clear](intercepting-and-mocking-http-requests/logging-http-requests.md#logger-methods)
* [requests](intercepting-and-mocking-http-requests/logging-http-requests.md#logger-properties)
* [RequestMock](intercepting-and-mocking-http-requests/mocking-http-responses.md)
* [onRequestTo](intercepting-and-mocking-http-requests/mocking-http-responses.md#the-onrequestto-method)
* [respond](intercepting-and-mocking-http-requests/mocking-http-responses.md#the-respond-method)
* [Role](authentication/user-roles.md)
* [anonymous](authentication/user-roles.md#anonymous-role)
* [Selector](selecting-page-elements/selectors/creating-selectors.md)
Expand Down Expand Up @@ -47,8 +56,10 @@ This topic lists test API members in alphabetical order.
* [httpAuth](authentication/http-authentication.md)
* [only](test-code-structure.md#skipping-tests)
* [page](test-code-structure.md#specifying-the-start-webpage)
* [requestHooks](intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.md)
* [skip](test-code-structure.md#skipping-tests)
* [Test Controller](test-code-structure.md#test-controller)
* [addRequestHooks](intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.md)
* [clearUpload](actions/upload.md#clear-file-upload-input)
* [click](actions/click.md)
* [ctx](test-code-structure.md#sharing-variables-between-test-hooks-and-test-code)
Expand Down Expand Up @@ -81,6 +92,7 @@ This topic lists test API members in alphabetical order.
* [maximizeWindow](actions/resize-window.md#maximizing-the-window)
* [navigate](actions/navigate.md)
* [pressKey](actions/press-key.md)
* [removeRequestHooks](intercepting-and-mocking-http-requests/attaching-hooks-to-tests-and-fixtures.md)
* [resizeWindow](actions/resize-window.md#setting-the-window-size)
* [resizeWindowToFitDevice](actions/resize-window.md#fitting-the-window-into-a-particular-device)
* [rightClick](actions/right-click.md)
Expand Down
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.
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);
})
```
Loading

0 comments on commit ac06c5d

Please sign in to comment.