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
- How test actions work
- Page actions
- Browser actions
- API Testing
- Role activation
- Cookie management
- Test interruption
- Pass data to the reporter
- Scroll elements into view
- Debug test actions
List of actions
The following test actions interact with the page:
The following test actions interact with the browser:
- Navigate to a URL
- Take Screenshots
- Handle Native Dialogs
- Resize Windows
- Manage Multiple Browser Windows
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:
- The target is the root page element or its descendant.
- The target is located in the active browser window or the active
<iframe>
. - The target meets the visibility criteria.
- Another element does not overlap the target as to prevent user interaction (See Treatment of Overlapping DOM Elements).
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 notnone
- The value of the element’s
visibility
property is nothidden
- The element has a non-zero
width
andheight
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
- Use the t.setFilesToUpload action to populate a
file
type input. - 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).
- 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
Navigate to a URL
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.
- t.resizeWindow resizes the window to match the
height
andwidth
parameters. - t.resizeWindowToFitDevice resizes the window to match the resolution of a mobile device.
- t.maximizeWindow maximizes the browser window. To enter full-screen mode, use the
--start-fullscreen
CLI flag.
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();
});
Cookie management
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.