Test Actions

Article Summary

TestCafe includes a comprehensive set of test action methods.

Test actions look like this:

await t.click('#button');

Test actions interact with the page and the browser. The t.request action allows you to send HTTP requests and perform API tests.

Test actions are methods of the TestController object. You can invoke test actions in any function that has access to the TestController, such as the test body, test hooks, and Role definitions.

Table of contents

List of actions

The following test actions interact with the page:

The following test actions interact with the browser:

The following test action issues HTTP requests:

The following test action pauses the test:

The following test action interrupts the test and opens the TestCafe debugger panel:

The following test action passes data to the reporter plugin:

TestCafe users can define custom test action methods. Read the Custom actions guide for more information.

How Test Actions Work

Test actions are methods of the test controller object. Test actions are infinitely chainable. Action targets are subject to interaction requirements.

Action Chaining

You can invoke the test controller object for every action or assertion, like so:

await t.click('#id1') //actions
await t.typeText('.input-field-1')
await t.click('#submit')

await t.expect(Selector('#result').textContent).eql('expected text');//assertion

Some people find this syntax more intuitive when they both write and debug tests. Other people prefer to chain method calls and minimize code:

await t
    .click('#id1') //actions
    .typeText('.input-field-1')
    .click('#submit')

    .expect(Selector('#result').textContent).eql('expected text');//assertion

You can chain all test controller methods that don’t return a value, including custom test actions. Add blank lines between logical parts of the action chain to improve readability.

You cannot chain the following methods (TestCafe v1.20.0):

Interaction Requirements

TestCafe imposes a number of requirements on page action targets to keep action simulation realistic.

The action target must meet the following requirements:

Important

If the target resides outside the viewport, TestCafe scrolls it into view.

Visibility Criteria

The element is visible if:

  • The value of the element’s display property is not none
  • The value of the element’s visibility property is not hidden
  • The element has a non-zero width and height

Elements that meet the visibility criteria above may still be invisible to the user. The following factors do not influence the element’s visibility status:

  • The element’s z-index
  • The element’s opacity
  • The element’s position on the page

Additional requirement for t.typeText

The t.typeText action can only interact with focused elements. If the target element doesn’t have focus, TestCafe automatically clicks it. If the element doesn’t gain :focus after the click, the action fails.

Touch Devices

On touch devices, TestCafe emulates touch events instead of mouse events.

Mouse event Corresponding touch event
mousemove (when you hover or drag) touchmove (when you drag)
mousedown touchstart
mouseup touchend

Page Actions

Click

The following three methods click page elements:

Example

import { Selector } from 'testcafe';

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Click test', async t => {
    const selectBasedOnText = Selector('label').withText('I have tried TestCafe');

    await t
        .click(selectBasedOnText);
});

Press Key

The Press Key action presses a key or key combination.

Example

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Press Key test', async t => {
    await t
        .click('#tried-test-cafe')
        // pressing 'Space' imitates clicking the checkbox again
        .pressKey('space');
});

Type Text

The Type Text action types a string into an element. The action can target input fields, textarea elements, and elements with the contenteditable attribute. The action target is subject to additional interaction requirements.

Example

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Type Text test', async t => {
    await t
        .typeText('#developer-name', 'John Doe');
});

Select Text

The Select Text action selects text box content. The action can only target input fields, textarea elements, and elements with the contenteditable attribute.

Example

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Select Text test', async t => {
    await t
        .typeText('#developer-name', 'John Doe')
        .selectText('#developer-name')
        .pressKey('delete');
});

Hover

The Hover action hovers the mouse pointer over page elements.

Example

fixture`Interact With the Page`
    .page`https://js.devexpress.com`;

test('Hover test', async t => {
    await t
        .hover('.map-container');
});

Scroll

Important

TestCafe automatically scrolls valid off-screen action targets into view. There is usually no need to use the scroll action.

The Scroll method scrolls the target element (or the document body) to the specified position.

Drag Elements

The following two methods drag elements around the page:

These methods emulate user interaction with draggable elements. Do not use them to select text and perform other complex browser actions.

Example

import { Selector } from 'testcafe';

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Drag test', async t => {
    const triedCheckbox = Selector('label').withText('I have tried TestCafe');

    await t
        .click(triedCheckbox)
        .drag('#slider', 360, 0, { offsetX: 10, offsetY: 10 });
});

Upload Files

The following two methods interact with file upload input elements:

File Upload Guide

  1. Use the t.setFilesToUpload action to populate a file type input.
  2. If your application uploads files as soon as you populate the field, you don’t need to take any further action. Otherwise, start the upload manually (for example, click the submit button).
  3. Use the t.clearUpload action to clear the list of files to upload.

Read the Test File Upload article for more details.

Example

fixture`Interact With the Page`
    .page`https://js.devexpress.com/Demos/WidgetsGallery/Demo/FileUploader/FileSelection/jQuery/Light/`;

test('Upload Files test', async t => {
    await t
        .switchToIframe('.demo-frame')
        .setFilesToUpload('.dx-fileuploader-input', [
            // substitute the following string with the path to a local file or multiple files you want to upload
            'src/file.txt',
        ]);
});

Work With Iframes

TestCafe intentionally limits its browsing context. When you first load the page, you only gain access to the main window.

Use the switchToIframe method to access an <iframe>. Use the switchToMainWindow method to switch back to the main window.

Example

fixture`Interact With the Page`
    .page`https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/Overview/jQuery/Light/`;

test('Working With iframe test', async t => {
    await t
        .switchToIframe('.demo-frame')
        .click('.dx-datagrid-group-panel')
        .switchToMainWindow();
});

Browser Actions

The Navigate action opens a new URL in the current window.

Example

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Navigate To URL test', async t => {
    await t
        .navigateTo('https://github.com/DevExpress/testcafe');
});

Take Screenshots

The following two actions take screenshots:

Example

fixture`Interact With the Page`
    .page`https://js.devexpress.com`;

test('Take Screenshot test', async t => {
    await t
        .takeScreenshot()
        .takeElementScreenshot('.map-container');
});

Handle Native Dialogs

Important

Read the authentication guide for information on how to handle native authentication prompts.

Use the t.setNativeDialogHandler method to dismiss or interact with native browser dialogs from that point forward. If a native dialog appears before you call this method, the test fails with an error.

TestCafe can interact with the following native dialog types:

Use the t.getNativeDialogHistory method to retrieve native dialog data (type, content, and URL).

Resize Windows

Three TestController methods resize browser windows. Before you add these methods to your test suite, make sure that your testing environment meets the necessary requirements.

Browser windows retain their size in between tests and fixtures. You can use hooks to reset window size before or after test entities.

Requirements

You cannot resize the windows of remote browsers.

  • Mac testing environments are compatible with window resizing actions out of the box.
  • Windows testing environments require .NET 4.0 or newer.
  • Linux testing environments require an ICCCM/EWMH-compliant window manager.

Example

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Resize Window test', async t => {
    await t
        .resizeWindowToFitDevice('iphonexr')
        .maximizeWindow();
});

Manage Multiple Browser Windows

TestCafe v1.10.1 introduced the ability to run multi-window tests in select browsers. Read the Multiple Windows Guide for more information.

API testing

Request

The Request action executes an HTTP request and returns the server’s response.

const responseBody = await t.request(`http://localhost:3000/helloworld`).body;
t.expect(responseBody).contains('Hello World') // true

Read the API Testing Guide for a full overview of the framework’s API testing capabilities.

Role activation

Roles allow you to authenticate users with a single line of code. Read the Authentication and Roles guide for more information.

useRole

The t.useRole action activates a Role.

Example

import * as path from 'path';

const loginUrl = path.join(__dirname, './pages/login-page.html');

import { Role, Selector } from 'testcafe';

const registeredUser = Role(loginUrl, async t => {
    await t
        .typeText('#login', 'User1')
        .typeText('#password', 'pa$$w0rd')
        .click('#sign-in');
});

fixture`TestController.useRole`
    .page`./pages/index.html`;

test('Check avatar after login', async t => {
    await t
        .useRole(registeredUser)
        .expect(Selector('#avatar').visible).ok();
});

The following three methods manage page cookies:

deleteCookies

The t.deleteCookies method deletes cookies.

Example

fixture`[API] Delete Cookies`
    .page('https://devexpress.github.io/testcafe/example/');

test('Should delete the cookie with the specified name', async t => {
    await t.setCookies({ name: 'apiCookie1', value: 'value1' });
    await t.expect((await t.getCookies()).length).eql(1);

    await t.deleteCookies('apiCookie1');
    await t.expect((await t.getCookies()).length).eql(0);
});

getCookies

The t.getCookies method retrieves page cookies.

Note

The order of cookies in the array depends on circumstances beyond the framework’s control. Do not expect cookie order to persist between test runs. Reference cookies by name, and not by their array index.

Example

fixture`[API] Get Cookies`
    .page('https://devexpress.github.io/testcafe/example/');

test('Should retrieve a cookie by name', async t => {
    //set a cookie for the Example page
    await t.setCookies({ name: 'apiCookie1', value: 'value1' });

    //retrieve the named cookie from any of the tested pages
    const cookies = await t.getCookies('apiCookie1');
    const { name, value } = cookies[0];

    await t
        .expect(name).eql('apiCookie1')
        .expect(value).eql('value1');
});

setCookies

The t.setCookies method sets page cookies.

Example

fixture`[API] Set Cookies`
    .page('https://devexpress.github.io/testcafe/example/');

test('Should set cookies by name and value', async t => {
    await t.setCookies({ apiCookie1: 'value1' }, 'http://localhost');

    const cookies = await t.getCookies();

    const { name, value, domain, path } = cookies[0];

    await t
        .expect(name).eql('apiCookie1')
        .expect(value).eql('value1')
        .expect(domain).eql('localhost')
        .expect(path).eql('/');
});

Test interruption

Debug

The t.debug method indefinitely pauses the test to allow the use of browser developer tools. To continue the test, press the appropriate button on the TestCafe debugger panel.

Example

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Test with debug action', async t => {
    await t
        .navigateTo('https://js.devexpress.com')
        .debug()
        .hover('.map-container');
});

Wait

The Wait action pauses the test.

Warning

Do not use the wait action to wait for an element to appear. See Built-In Wait Mechanisms.

Example

fixture`Interact With the Page`
    .page`https://js.devexpress.com`;

test('Wait test', async t => {
    await t
        .hover('.map-container')
        .wait(1000);
});

Pass Data to the Reporter

Report

The Report action passes data to the reporter plugin.

Scroll elements into view

TestCafe scrolls to reach items that are on the page but outside the user’s viewport.

You can use any action (for example, hover) to scroll towards the desired part of the page.

If you specifically need to scroll the page without any action, use the scroll action.

import { ClientFunction } from 'testcafe';

const scrollBy = ClientFunction(() => {
    window.scrollBy(0, 1000);
});

fixture`Interact With the Page`
    .page`https://devexpress.github.io/testcafe/example/`;

test('Scroll an Element into View', async () => {
    await scrollBy();
});

Debug test actions

A badly written Element Selector query may lead to test action failure. Read the Debug Tests guide for more information.