Intercept HTTP Requests

When you interact with a web page, the page issues HTTP requests. Additionally, you can execute arbitrary HTTP requests with the request method.

TestCafe allows you intercept these requests with request hooks.

You can attach request hooks to specific tests and fixtures or define them globally.

Log HTTP Requests

Use the request logger to record outgoing HTTP requests and inspect responses to these requests. For instance, you may want to make sure that the data from a remote service is correct.

Use the RequestLogger constructor to create a request logger.

import { RequestLogger } from 'testcafe';

const simpleLogger = RequestLogger('');
const headerLogger = RequestLogger(/testcafe/, {
    logRequestHeaders: true,
    logResponseHeaders: true

Attach the logger to a specific test / fixture or enable it globally.

The RequestLogger logs the following data about outgoing requests:

  • The request’s target URL
  • The request’s HTTP method
  • The status code of the response
  • The request sender’s user agent string

Use the following RequestLogger methods to inspect this data:

Member Description
requests Returns an array of logged requests
contains Succeeds if the logger contains a matching request
count Returns the number of matching requests
clear Clears all logged requests


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

const url = '';

const logger = RequestLogger({ url, method: 'post' }, {
    logResponseHeaders: true,
    logResponseBody:    true

fixture `Export`

test('export to csv', async t => {
    const exportToCSVButton = Selector('span').withText('Export to CSV');

    await t
        // When you click 'Export', your browser downloads a compressed CSV file (*.gzip).
        .expect(logger.contains(r => r.response.statusCode === 200)).ok();

    const filePath = path.join(__dirname, '');
    // Locates the file on the disk


    fs.writeFileSync(filePath, logger.requests[0].response.body);

    // Use 3rd party modules to unpack the archive,
    // parse the CSV and check the data.
    // Alternatively, verify the file manually.

Mock HTTP Requests

Use the request mocker to intercept your application’s HTTP requests and respond to them with dummy data. This is useful when some parts of your website’s infrastructure are difficult to deploy or costly to use.

Imagine that your application sends data to a third-party traffic analysis service. You do not want your functional tests to impact your website’s analytics. Add a request mocker to intercept requests to that service, and emulate the response as needed.

Use the RequestMock constructor to create a request mocker.

var mock = RequestMock();

Append the onRequestTo and respond methods to the RequestMock constructor:

var mock = RequestMock()

The onRequestTo method specifies which requests to intercept. The respond specifies how TestCafe should respond to the intercepted request.

If you need to mock multiple requests, you can chain these methods repeatedly:

var mock = RequestMock()

To enable this request hook, attach it to a test/fixture or define it globally.


import { Selector, RequestMock } from 'testcafe';

// Google Analytics API endpoint
const collectDataGoogleAnalyticsRegExp = new RegExp('');

// Binary image data for the mocked response
const mockedResponse = Buffer.from([0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01]);

const mock = RequestMock()
    // This hook fires when the application sends a request to the Google Analytics API endpoint
    .respond(mockedResponse, 202, {
        'content-length': mockedResponse.length,
        'content-type': 'image/gif'
    // TestCafe intercepts the request and responds with the dummy data above (status code: 202). 

fixture `Fixture`

test('basic', async t => {
    await t
        // The debug action pauses the test.
        // Open your browser's Developer Tools to inspect the request and the response.

Create a Custom Request Hook

Create custom request hooks to perform other actions with HTTP requests.

  1. Create a new class that inherits from the RequestHook class.
  2. Override the onRequest method to handle the request before it is sent.
  3. Override the onResponse method to handle the response after it is received.
import { RequestHook } from 'testcafe';

export class MyRequestHook extends RequestHook {
    constructor (requestFilterRules, responseEventConfigureOpts) {
        super(requestFilterRules, responseEventConfigureOpts);
        // ...
    async onRequest (event) {
        // ...
    async onResponse (event) {
        // ...
  1. Create an instance of your new hook. Attach it to a test/fixture or define it globally.
import { MyRequestHook } from './my-request-hook';

const customHook = new MyRequestHook(/https?:\/\/;

fixture `My fixture`

test('My test', async t => {
        // test actions


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.

    onRequest (e) {
        e.requestOptions.headers['Authorization'] = 'generate token here';

    onResponse (e) {
        // This method must also be overridden,
        // but you can leave it blank.

const jwtBearerAuthorization = new JwtBearerAuthorization();

fixture `Fixture`
    .page('<website URL>')

test('basic', async t => {
    /* some actions */

Attach Hooks to Tests and Fixtures

Attach a hook to a test or fixture to handle HTTP requests within these entities.

import { RequestLogger, RequestMock } from 'testcafe';

const logger = RequestLogger('');
const mock   = RequestMock()
    .respond({ data: 'value' });

fixture `My fixture`

    ('My test', async t => {
    await t
         .expect(logger.count(() => true)).eql(1)
         .expect(logger.count(() => true)).eql(1)
         .expect(logger.count(() => true)).eql(2);

Define Global Hooks in the Configuration File

You may need to attach the same hook to multiple tests or fixtures. To avoid code duplication, you can define a global hook in the JavaScript configuration file.

The following code shows an example that defines a global RequestMock. Note that test code doesn’t require an explicit hook declaration. The configuration file attaches the hook to the test.

const { RequestMock } = require('testcafe');
const mock = RequestMock()
        name:     'John Hearts',
        position: 'CTO',
    }, 200, { 'access-control-allow-origin': '*' })
    .respond(null, 404);

module.exports = {
    hooks: {
        request: mock,
fixture `RequestMock`

test('Should mock requests', async t => {
    const user = await t
    .eval(() => fetch('')
    .then(res => res.json()));

    await t
        .expect(user).eql({ name: 'John Hearts', position: 'CTO' })

The hook declaration may require an extra step. In the example above, the test does not need to read any data from the RequestMock object. The situation changes if the hook is a RequestLogger or a custom RequestMock. Tests may need to obtain the hook object’s data in such cases.

The following example demonstrates how you can declare a global RequestLogger. The test needs to access the logger object in order to read and validate its data. To enable such access, define an extra file: “logger.js”. This file defines the hook object and supplies it to both the test and the configuration file.

const { RequestLogger } = require('testcafe');
module.exports = new RequestLogger();
const logger = require('./logger');

module.exports = {
    hooks: {
        request: logger,
const { logger } = './logger';


test('Check request', async t => {
    await t
    .expect(logger.contains(record => record.response.statusCode === 200)).ok()

Request Hook Conflicts

If a single request is subject to multiple request hooks, TestCafe executes the hooks in the following order:

  • Global hook
  • Fixture hook
  • Test hook