Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:DevExpress Testcafe NativeAutomation ResourceInjector

From Leeroopedia
Knowledge Sources
Domains Browser Automation, Script Injection, CDP Integration
Last Updated 2026-02-12 12:00 GMT

Overview

ResourceInjector intercepts HTML document responses via the Chrome DevTools Protocol's Fetch domain and injects TestCafe's client-side scripts, stylesheets, and storage-restoration code into the page before the browser renders it.

Description

ResourceInjector is the central class responsible for transforming intercepted HTML responses so that every page loaded during a test run contains the TestCafe instrumentation layer. It works in concert with the NativeAutomationRequestPipeline, which provides the raw CDP RequestPausedEvent data.

Key responsibilities:

  • prepareInjectableResources assembles the full set of resources to inject: hammerhead injectable scripts, TestCafe UI scripts and styles, user-defined scripts, the task script (generated per test run), and embedded scripts for restoring localStorage/sessionStorage and the native automation context storage. All relative URLs are resolved via the hammerhead proxy.
  • processHTMLPageContent takes a paused Fetch response whose body contains HTML, calls injectResources (from hammerhead) to insert <script> and <link> tags, then fulfils the request back to the browser with the modified body. If no test run is active, it redirects to the idle page.
  • processAboutBlankPage handles about:blank navigations by injecting resources into an empty-page HTML template and setting the document content via Page.setDocumentContent.
  • getDocumentResourceInfo retrieves the response body for Document-type resources via Fetch.getResponseBody. It handles DNS resolution failures (NameNotResolved) by returning a structured error.
  • redirectToErrorPage sets a PageLoadError on the current test run and navigates the browser to the configured error page route.
  • processNonProxiedContent fulfils non-HTML intercepted requests without modification (pass-through).

Response headers listed in RESPONSE_REMOVED_HEADERS (cross-origin-embedder-policy, cross-origin-opener-policy, cross-origin-resource-policy) are stripped to prevent cross-origin isolation from blocking injected scripts.

Usage

Use ResourceInjector within the native automation request pipeline. It is instantiated once per pipeline with a TestRunBridge and its options are updated via setOptions. The pipeline calls its methods in response to CDP Fetch events for document resources.

Code Reference

Source Location

Signature

export interface ResourceInjectorOptions {
    specialServiceRoutes: SpecialServiceRoutes;
    developmentMode: boolean;
}

export default class ResourceInjector {
    private _options: ResourceInjectorOptions;
    private readonly _testRunBridge: TestRunBridge;

    public constructor (testRunBridge: TestRunBridge);

    public async redirectToErrorPage (
        client: ProtocolApi,
        err: Error,
        url: string,
    ): Promise<void>;

    public async getDocumentResourceInfo (
        event: RequestPausedEvent,
        client: ProtocolApi,
        contentType?: string,
    ): Promise<DocumentResourceInfo>;

    public async processAboutBlankPage (
        event: FrameNavigatedEvent,
        userScripts: string[],
        contextStorage: SessionStorageInfo | null,
        client: ProtocolApi,
    ): Promise<void>;

    public async processHTMLPageContent (
        fulfillRequestInfo: FulfillRequestRequest,
        injectableResourcesOptions: InjectableResourcesOptions,
        client: ProtocolApi,
        sessionId: SessionId,
        contentType?: string,
    ): Promise<void>;

    public async processNonProxiedContent (
        fulfillRequestInfo: FulfillRequestRequest,
        client: ProtocolApi,
        sessionId: SessionId,
    ): Promise<void>;

    public setOptions (options: ResourceInjectorOptions): void;
}

Import

import ResourceInjector from '../native-automation/resource-injector';

I/O Contract

Constructor

Parameter Type Description
testRunBridge TestRunBridge Bridge to the current test run providing task scripts, session IDs, injectable scripts/styles, and browser connection info

getDocumentResourceInfo

Parameter Type Description
event RequestPausedEvent CDP Fetch paused event for the intercepted request
client ProtocolApi CDP client to call Fetch.getResponseBody
contentType string (optional) Response content type for proper encoding
Return Type Description
Promise<DocumentResourceInfo> null, body: Buffer | null } -- the response body or an error

processHTMLPageContent

Parameter Type Description
fulfillRequestInfo FulfillRequestRequest CDP Fetch fulfil payload containing requestId, body, responseCode, responseHeaders
injectableResourcesOptions InjectableResourcesOptions Flags for isIframe, restoringStorages, contextStorage, userScripts, and url
client ProtocolApi CDP client for fulfilling the request
sessionId SessionId Current CDP session identifier
contentType string (optional) Content type for base64 encoding
Return Type Description
Promise<void> The intercepted HTML response is fulfilled with injected scripts/styles

ResourceInjectorOptions

Field Type Description
specialServiceRoutes SpecialServiceRoutes Contains errorPage1, errorPage2, openFileProtocolUrl, and idlePage URLs
developmentMode boolean When true, unminified asset paths are used

Usage Examples

import ResourceInjector from '../native-automation/resource-injector';

// Create the injector with a test-run bridge
const injector = new ResourceInjector(testRunBridge);

// Configure options for the current session
injector.setOptions({
    specialServiceRoutes: {
        errorPage1:          '/error-page-1',
        errorPage2:          '/error-page-2',
        openFileProtocolUrl: '/open-file',
        idlePage:            '/idle',
    },
    developmentMode: false,
});

// When a document request is paused, get its body
const docInfo = await injector.getDocumentResourceInfo(pausedEvent, cdpClient, 'text/html');

if (docInfo.error) {
    await injector.redirectToErrorPage(cdpClient, docInfo.error, pausedEvent.request.url);
}
else if (docInfo.body) {
    // Inject TestCafe scripts into the HTML and fulfil the response
    await injector.processHTMLPageContent(
        {
            requestId:       pausedEvent.requestId,
            responseCode:    pausedEvent.responseStatusCode,
            responseHeaders: pausedEvent.responseHeaders,
            body:            docInfo.body.toString(),
        },
        { isIframe: false, userScripts: [], contextStorage: null },
        cdpClient,
        sessionId,
        'text/html',
    );
}

// Handle about:blank pages
await injector.processAboutBlankPage(frameNavigatedEvent, [], null, cdpClient);

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment