Implementation:DevExpress Testcafe RequestLogger
| Knowledge Sources | |
|---|---|
| Domains | Testing, Network Interception, Logging |
| Principle | Request logging/recording |
| Last Updated | 2026-02-12 12:00 GMT |
Overview
RequestLogger is a concrete request hook that records HTTP requests and responses matching specified filter rules, providing an API to query, filter, and clear logged entries during test execution.
Description
The file src/api/request-hooks/request-logger.ts defines the internal class RequestLoggerImplementation (which extends RequestHook) and exports a factory function createRequestLogger. The logger captures request metadata (URL, method, timestamp, user agent) and optionally headers and body content for both requests and responses, controlled by a set of boolean log options.
Internally, logged requests are stored in a dictionary keyed by a composite sessionId:requestId string. Each entry is a LoggedRequest object containing a request part (populated in onRequest) and an optional response part (populated in onResponse). The logger is test-run aware: when accessed from within a test context, it automatically filters results to only those belonging to the current test run.
The public API exposes:
requests-- a getter property returning all logged entries (filtered by current test run if applicable).contains(predicate)-- returns aReExecutablePromiseresolving totrueif any completed request matches the predicate.count(predicate)-- returns aReExecutablePromiseresolving to the count of completed requests matching the predicate.clear()-- removes logged entries (scoped to the current test run if applicable, otherwise clears all).
The class enforces consistency by throwing an APIError if stringifyRequestBody is true but logRequestBody is false (and similarly for response body).
Usage
Use RequestLogger when you need to assert on network activity during a test -- for example, verifying that a particular API endpoint was called, checking request payloads, or validating response status codes. Create an instance via the RequestLogger factory, attach it with .requestHooks(), and query its requests property or use contains/count in assertions.
Code Reference
Source Location
- Repository: DevExpress_Testcafe
- File: src/api/request-hooks/request-logger.ts
- Lines: 1-178
Signature
class RequestLoggerImplementation extends RequestHook {
private readonly _options: RequestHookLogOptions;
private _internalRequests: Dictionary<LoggedRequest>;
public constructor (
requestFilterRuleInit?: RequestFilterRuleInit | RequestFilterRuleInit[],
options?: RequestHookLogOptionsInit
);
public async onRequest (event: RequestEvent): Promise<void>;
public async onResponse (event: ResponseEvent): Promise<void>;
public contains (predicate: (request: LoggedRequest) => boolean): ReExecutablePromise;
public count (predicate: (request: LoggedRequest) => boolean): ReExecutablePromise;
public clear (): void;
public get requests (): LoggedRequest[];
}
// Factory export
export default function createRequestLogger (
requestFilterRuleInit: RequestFilterRuleInit | RequestFilterRuleInit[] | undefined,
logOptions: RequestHookLogOptionsInit
): RequestLoggerImplementation;
Import
import createRequestLogger from './request-logger';
// or from the public API:
// import { RequestLogger } from 'testcafe';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| requestFilterRuleInit | RequestFilterRuleInit[] | No | Filter rules specifying which URLs/requests to log. Defaults to RequestFilterRule.ANY.
|
| options | RequestHookLogOptionsInit |
No | Partial options controlling what to log. All default to false.
|
RequestHookLogOptions fields:
| Name | Type | Default | Description |
|---|---|---|---|
| logRequestHeaders | boolean |
false |
Whether to capture request headers. |
| logRequestBody | boolean |
false |
Whether to capture the request body. |
| stringifyRequestBody | boolean |
false |
Whether to convert the request body buffer to a string. Requires logRequestBody: true.
|
| logResponseHeaders | boolean |
false |
Whether to capture response headers. |
| logResponseBody | boolean |
false |
Whether to capture the response body. |
| stringifyResponseBody | boolean |
false |
Whether to convert the response body buffer to a string. Requires logResponseBody: true.
|
Outputs
| Name | Type | Description |
|---|---|---|
| requests | LoggedRequest[] |
Array of all logged request/response pairs (filtered to current test run when available). |
| contains(predicate) | ReExecutablePromise<boolean> |
Resolves to true if any completed request matches.
|
| count(predicate) | ReExecutablePromise<number> |
Resolves to the number of completed requests matching the predicate. |
LoggedRequest structure:
| Name | Type | Description |
|---|---|---|
| id | string |
The request ID from the hammerhead proxy. |
| testRunId | string |
The session/test-run ID. |
| userAgent | string |
Parsed pretty-printed user agent string. |
| request | LoggedRequestPart |
Object containing timestamp, url, method, and optionally headers and body.
|
| response | undefined | Object containing statusCode, timestamp, and optionally headers and body. Undefined until the response arrives.
|
Usage Examples
import { RequestLogger } from 'testcafe';
const logger = RequestLogger(/api\/users/, {
logRequestHeaders: true,
logResponseBody: true,
stringifyResponseBody: true,
});
fixture `User API Tests`
.page `https://example.com`
.requestHooks(logger);
test('should call the users endpoint', async t => {
// ... trigger some action that calls /api/users ...
// Assert that at least one matching request was made
await t.expect(logger.contains(r => r.response.statusCode === 200)).ok();
// Check the count of requests
await t.expect(logger.count(r => r.request.method === 'GET')).eql(1);
// Access all logged requests
const allRequests = logger.requests;
console.log(`Total logged requests: ${allRequests.length}`);
// Clear logged entries for the current test run
logger.clear();
});
Related Pages
Note: This is an orphan Implementation — request logging/recording is an internal API with no dedicated Principle page.