Inject Scripts into Tested Pages

TestCafe allows you to inject custom client scripts into pages visited during the tests. You can add scripts that mock browser API or provide helper functions.

Use test run options to add client scripts to all tests, or test API to add them to specific fixtures or tests.

Add Client Scripts to All Tests

Use either of the following options to inject scripts into pages visited during all the tests:

  • the --cs (--client-scripts) command line option

    testcafe chrome test.js --client-scripts mockDate.js,assets/react-helpers.js
    
  • the runner.clientScripts API method

    runner.clientScripts('mockDate.js', 'scripts/react-helpers.js');
    
  • the clientScripts configuration file property

    {
        "clientScripts": ["mockDate.js", "scripts/react-helpers.js"]
    }
    

Add Client Scripts to Specific Tests

Use the fixture.clientScripts and test.clientScripts methods to inject scripts into pages visited during a particular test or fixture.

fixture `My fixture`
    .page `http://example.com`
    .clientScripts('assets/jquery.js');
test
    ('My test', async t => { /* ... */ })
    .clientScripts({ module: 'async' });

Provide Scripts to Inject

You can pass the following arguments to specify the scripts to inject:

You can also inject scripts into specific pages and iframes.

Note that the API methods and configuration option support multiple arguments.

Inject a JavaScript File

Specify the JavaScript file path to inject the entire content of this file into the tested pages. You can pass a string or an object with the path property.

CLI

testcafe <browser> <tests> --cs <filePath>[,<filePath2>,...<filePathN>]

Programming interface

runner.clientScripts(filePath | { path: filePath })
runner.clientScripts(filePath | { path: filePath }, ...)
runner.clientScripts([ filePath | { path: filePath } ])

Configuration file

{
    "clientScripts": "<filePath>" | { "path": "<filePath>" }
}
{
    "clientScripts": [ "<filePath>" | { "path": "<filePath>" } ]
}

Test API

fixture.clientScripts(filePath | { path: filePath })
fixture.clientScripts(filePath | { path: filePath }, ...)
fixture.clientScripts([ filePath | { path: filePath } ])
test.clientScripts(filePath | { path: filePath })
test.clientScripts(filePath | { path: filePath }, ...)
test.clientScripts([ filePath | { path: filePath } ])
Argument Type Description
filePath, filePath2, filePathN String The path to the JavaScript file whose content should be injected.

Relative Paths

Relative paths resolve from the current working directory when you inject scripts in:

When you use test API methods, relative paths resolve from the test file location.

Examples

testcafe chrome my-tests --cs assets/jquery.js
runner.clientScripts('assets/jquery.js');
// or
runner.clientScripts({ path: 'assets/jquery.js' });
{
    "clientScripts": "assets/jquery.js",
    // or
    "clientScripts": { "path": "assets/jquery.js" }
}

You cannot combine the path, module and content properties in a single object. To inject multiple items, pass several arguments or an array.

Inject a Module

Specify the Node.js module's name to inject its content into the tested pages. Use an object with the module property.

Programming interface

runner.clientScripts( { module: moduleName } )
runner.clientScripts( { module: moduleName }, ... )
runner.clientScripts([ { module: moduleName } ])

Configuration file

{
    "clientScripts": { "module": "<moduleName>" }
}
{
    "clientScripts": [ { "module": "<moduleName>" } ]
}

Test API

fixture.clientScripts( { module: moduleName } )
fixture.clientScripts( { module: moduleName }, ... )
fixture.clientScripts([ { module: moduleName } ])
test.clientScripts( { module: moduleName } )
test.clientScripts( { module: moduleName }, ... )
test.clientScripts([ { module: moduleName } ])
Argument Type Description
moduleName String The module name.

TestCafe searches for the module's entry point with Node.js mechanisms and injects its content into the tested page.

Note that the browser must be able to execute the injected module. For example, modules that implement the UMD API can run in most modern browsers.

If the injected module has dependencies, you should ensure that:

  • The dependencies can be loaded as global variables.
  • These variables are initialized in the page code.

Examples

fixture `My fixture`
    .page `https://example.com`
    .clientScripts({ module: 'lodash' });
{
    "clientScripts": {
        "module": "lodash"
    }
}

You cannot combine the module, path and content properties in a single object. To inject multiple items, pass several arguments or an array.

Inject Script Code

You can provide the injected script as a string with JavaScript code. Pass an object with the content property to do this.

Programming interface

runner.clientScripts({ content: code })
runner.clientScripts({ content: code }, ...)
runner.clientScripts([ { content: code } ])

Configuration file

{
    "clientScripts": { "content": "<code>" }
}
{
    "clientScripts": [ { "content": "<code>" } ]
}

Test API

fixture.clientScripts({ content: code })
fixture.clientScripts({ content: code }, ...)
fixture.clientScripts([ { content: code } ])
test.clientScripts({ content: code })
test.clientScripts({ content: code }, ...)
test.clientScripts([ { content: code } ])
Argument Type Description
code String JavaScript code that should be injected.

Examples

const mockDate = `
    Date.prototype.getTime = function () {
        return 42;
    };
`;

test
    ('My test', async t => { /* ... */ })
    .clientScripts({ content: mockDate });
{
    "clientScripts": {
        "content": "Date.prototype.getTime = () => 42;"
    }
}

You cannot combine the content, path and module properties in a single object. To inject multiple items, pass several arguments or an array.

Provide Scripts for Specific Pages

You can also specify pages into which a script should be injected.

This is helpful when you need to mock browser API on particular pages and use the default behavior everywhere else.

To specify target pages for a script, add the page property to the object you pass to clientScripts.

Programming interface

runner.clientScripts({
    page: url,
    path: filePath | module: moduleName | content: code
})

runner.clientScripts({
    page: url,
    path: filePath | module: moduleName | content: code
}, ...)

runner.clientScripts([
    {
        page: url,
        path: filePath | module: moduleName | content: code
    }
])

Configuration file

{
    "clientScripts": {
        "page": "<url>",
        "path": "<filePath>" | "module": "<moduleName>" | "content": "<code>"
    }
}
{
    "clientScripts": [
        {
            "page": "<url>",
            "path": "<filePath>" | "module": "<moduleName>" | "content": "<code>"
        }
    ]
}

Test API

fixture.clientScripts({
    page: url,
    path: filePath | module: moduleName | content: code
})

fixture.clientScripts({
    page: url,
    path: filePath | module: moduleName | content: code
}, ...)

fixture.clientScripts([
    {
        page: url,
        path: filePath | module: moduleName | content: code
    }
])
test.clientScripts({
    page: url,
    path: filePath | module: moduleName | content: code
})

test.clientScripts({
    page: url,
    path: filePath | module: moduleName | content: code
}, ...)

test.clientScripts([
    {
        page: url,
        path: filePath | module: moduleName | content: code
    }
])
Property Type Description
url String | RegExp Specify a page URL to add scripts to a single page, or a regular expression to add scripts to pages whose URLs match this expression. Regular expressions are not supported in the clientScripts configuration file property.

Examples

runner.clientScripts({
    page: /\/user\/profile\//,
    path: 'dist/jquery.js'
});
{
    "clientScripts": {
        "page": "https://myapp.com/page/",
        "content": "Geolocation.prototype.getCurrentPosition = () => new Positon(0, 0);"
    }
}

If the target page redirects to a different URL, ensure that the page property matches the destination URL. Otherwise, scripts are not injected.

Inject Scripts Into Iframes

To inject a script into an iframe, specify the iframe URL in the page property.

runner.clientScripts({
    path: 'scripts/helpers.js',
    page: 'https://example.com/iframe/'
}));

Specify Multiple Scripts

You can pass multiple arguments or an array to the clientScripts methods:

fixture `My fixture`
    .page `https://example.com`
    .clientScripts('scripts/react-helpers.js', { content: 'Date.prototype.getTime = () => 42;' });
runner.clientScripts(['scripts/react-helpers.js', 'dist/jquery.js']);

The clientScripts configuration file property can also take arrays:

{
    "clientScripts": ["vue-helpers.js", {
        "page": "https://mycorp.com/login/",
        "module": "lodash"
    }]
}

The --cs (--client-scripts) command line option supports multiple arguments as well:

testcafe chrome test.js --client-scripts mockDate.js,assets/react-helpers.js

Note that the page, content and module properties cannot take arrays. To inject multiple scripts into the same page, pass one argument for each script.

const scripts = ['test1.js', 'test2.js', 'test3.js'];

runner.clientScripts(scripts.map(script => {
    path: script,
    page: 'http://example.com'
}));

Access DOM in the Injected Scripts

TestCafe injects scripts into the head tag, which means they are executed before DOM is loaded.

To access DOM in these scripts, wait until the DOMContentLoaded event fires:

const scriptContent = `
window.addEventListener('DOMContentLoaded', function () {
    document.body.style.backgroundColor = 'green';
});
`;

fixture `My fixture`
    .clientScripts({ content: scriptContent });