Implementation:DevExpress Testcafe TestController Actions
| Knowledge Sources | |
|---|---|
| Domains | Testing, Web_Automation |
| Last Updated | 2026-02-12 04:00 GMT |
Overview
Concrete implementation of test actions in TestCafe through the `TestController` class, providing a comprehensive API for simulating user interactions and browser operations.
Description
The `TestController` class (accessed via the `t` parameter in test functions) provides methods for all test actions. Each method enqueues a command to be executed in the browser context, with automatic waiting for elements to become actionable. Methods return the TestController instance, enabling fluent chaining of operations. The controller manages test execution state, handles asynchronous operations, and provides the `expect()` method for creating assertions.
Usage
The `t` object is automatically injected as the first parameter of test functions. Chain action methods to build test scenarios. Use await with the final action in a chain to ensure completion before proceeding.
Code Reference
Source Location
- Repository: testcafe
- File: src/api/test-controller/index.js
- Lines: 93-654
Signature
class TestController {
// Mouse actions
click(selector: Selector | string, options?: ClickOptions): TestController
rightClick(selector: Selector | string, options?: ClickOptions): TestController
doubleClick(selector: Selector | string, options?: ClickOptions): TestController
hover(selector: Selector | string, options?: HoverOptions): TestController
drag(selector: Selector | string, offsetX: number, offsetY: number, options?: DragOptions): TestController
dragToElement(selector: Selector | string, destination: Selector | string, options?: DragOptions): TestController
// Keyboard actions
typeText(selector: Selector | string, text: string, options?: TypeOptions): TestController
selectText(selector: Selector | string, start?: number, end?: number, options?: TypeOptions): TestController
pressKey(keys: string, options?: PressKeyOptions): TestController
// Navigation
navigateTo(url: string): TestController
// Window/viewport
resizeWindow(width: number, height: number): TestController
maximizeWindow(): TestController
// Frames
switchToIframe(selector: Selector | string): TestController
switchToMainWindow(): TestController
// Dialogs
setNativeDialogHandler(fn: Function | null): TestController
getNativeDialogHistory(): Promise<DialogHistoryItem[]>
// Screenshots
takeScreenshot(path?: string): TestController
takeElementScreenshot(selector: Selector | string, path?: string, options?: ScreenshotOptions): TestController
// Timing
wait(timeout: number): TestController
// Roles
useRole(role: Role): TestController
// Assertions
expect(actual: any): Assertion
}
Import
// TestController is automatically injected as test function parameter
// No import needed
fixture`My Fixture`
.page`https://example.com`;
test('My test', async t => {
// 't' is the TestController instance
await t.click('#button');
});
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| selector | string | Yes (element actions) | Target element for the action |
| options | object | No | Action-specific options (speed, modifiers, offsets, etc.) |
| text | string | Yes (typeText) | Text to type into input |
| keys | string | Yes (pressKey) | Key names or combinations (e.g., 'enter', 'ctrl+a') |
| url | string | Yes (navigateTo) | URL to navigate to |
| timeout | number | Yes (wait) | Milliseconds to wait |
| width, height | number | Yes (resizeWindow) | Window dimensions in pixels |
| path | string | No (screenshots) | File path for screenshot |
Outputs
| Name | Type | Description |
|---|---|---|
| testController | TestController | Returns itself for method chaining (except getNativeDialogHistory) |
| dialogHistory | Promise<array> | Array of dialog interactions (getNativeDialogHistory only) |
Usage Examples
Mouse Actions
import { Selector } from 'testcafe';
fixture`Mouse Actions`
.page`https://example.com`;
test('Click actions', async t => {
await t
.click('#submit-button')
.rightClick('.context-menu-trigger')
.doubleClick('.editable-text')
.hover('#dropdown-menu');
});
test('Click with options', async t => {
await t
.click('#button', { offsetX: 10, offsetY: 5 })
.click('#link', { modifiers: { ctrl: true } })
.click('#target', { speed: 0.5 });
});
Drag and Drop
test('Drag actions', async t => {
// Drag by offset
await t.drag('.draggable', 100, 50);
// Drag to another element
await t.dragToElement('.drag-source', '.drop-target');
});
Keyboard Actions
test('Type and press keys', async t => {
const input = Selector('#username');
await t
.typeText(input, 'john.doe@example.com')
.typeText('#password', 'secret123', { replace: true })
.pressKey('tab')
.pressKey('enter');
});
test('Select text', async t => {
await t
.selectText('#textarea', 0, 10)
.pressKey('ctrl+c');
});
test('Key combinations', async t => {
await t
.pressKey('ctrl+a')
.pressKey('delete')
.pressKey('esc');
});
test('Navigate to URLs', async t => {
await t
.navigateTo('https://example.com/login')
.typeText('#username', 'user')
.navigateTo('https://example.com/dashboard');
});
Window Management
test('Resize window', async t => {
await t
.resizeWindow(1280, 720)
.click('#responsive-menu');
});
test('Maximize window', async t => {
await t.maximizeWindow();
});
Frame Switching
test('Work with iframes', async t => {
await t
.switchToIframe('#payment-iframe')
.typeText('#card-number', '4111111111111111')
.switchToMainWindow()
.click('#submit-order');
});
Dialog Handling
test('Handle native dialogs', async t => {
await t
.setNativeDialogHandler((type, text) => {
if (type === 'confirm')
return true;
if (type === 'prompt')
return 'My answer';
return null;
})
.click('#show-confirm');
const history = await t.getNativeDialogHistory();
await t.expect(history[0].type).eql('confirm');
});
Screenshots
test('Take screenshots', async t => {
await t
.takeScreenshot('page-state.png')
.takeElementScreenshot('#dashboard', 'dashboard.png');
});
Waiting
test('Wait for delays', async t => {
await t
.click('#start-animation')
.wait(3000)
.expect(Selector('.animated').visible).ok();
});
Action Chaining
test('Complex action chain', async t => {
await t
.typeText('#search', 'TestCafe')
.click('#search-button')
.wait(1000)
.hover('.result-item')
.click('.result-item a')
.expect(Selector('h1').textContent).contains('TestCafe');
});