Implementation:DevExpress Testcafe TestRunBookmark
| Knowledge Sources | |
|---|---|
| Domains | Test Execution, Role Switching |
| Last Updated | 2026-02-12 12:00 GMT |
Overview
TestRunBookmark captures and restores a snapshot of a test run's state to enable role switching without losing the current execution context.
Description
TestRunBookmark implements a state snapshot/restore pattern used during TestCafe's role switching mechanism. When a test switches to a different Role, the bookmark captures the current test run's context (test/fixture ctx objects), dialog handler, iframe selector, speed, page load timeout, console messages, and URL. After the role is initialized, the bookmark restores all of these properties, navigating back to the appropriate URL with the role's state snapshot and re-establishing the working iframe frame if necessary.
The class manages test run phase transitions, setting the phase to TEST_RUN_PHASE.inBookmarkRestore during restoration and reverting to the previous phase upon completion. Error handling during restoration attaches the callsite for accurate error reporting.
Usage
TestRunBookmark is used internally by the role switching system. When a test calls t.useRole(role), the test run creates a bookmark, initializes it (saving state), performs the role initialization, then calls bookmark.restore(callsite, stateSnapshot) to return to the pre-role state with the new authentication/session applied.
Code Reference
Source Location
- Repository: DevExpress_Testcafe
- File: src/test-run/bookmark.ts
- Lines: 1-160
Signature
export default class TestRunBookmark {
private readonly testRun: TestRun;
private readonly role: Role;
private url: string;
private ctx: object | null;
private fixtureCtx: object | null;
private readonly dialogHandler: ExecuteClientFunctionCommand | null;
private readonly iframeSelector: ExecuteSelectorCommand | null;
private readonly speed: number;
private readonly pageLoadTimeout: number;
private readonly consoleMessages: BrowserConsoleMessages | null;
public constructor(testRun: TestRun, role: Role);
public async init(): Promise<void>;
public async restore(callsite: CallsiteRecord, stateSnapshot: StateSnapshot): Promise<void>;
}
Import
import TestRunBookmark from '../test-run/bookmark';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| testRun | TestRun |
Yes | The test run whose state is being bookmarked |
| role | Role |
Yes | The role being switched to, providing opts.preserveUrl and redirectUrl
|
Inputs (restore method)
| Name | Type | Required | Description |
|---|---|---|---|
| callsite | CallsiteRecord |
Yes | Callsite record for attaching to errors thrown during restoration |
| stateSnapshot | StateSnapshot |
Yes | Hammerhead state snapshot (cookies, storages) to restore along with navigation |
Outputs
| Name | Type | Description |
|---|---|---|
| init return | Promise<void> |
Saves the current state and prepares for role switch (switches to main window, captures redirect URL) |
| restore return | Promise<void> |
Restores all saved state properties to the test run and navigates to the role's redirect URL |
State Properties Captured
| Property | Type | Description |
|---|---|---|
| ctx | object |
Test-level context object (t.ctx)
|
| fixtureCtx | object |
Fixture-level context object (t.fixtureCtx)
|
| dialogHandler | null | Active native dialog handler function |
| iframeSelector | null | Selector for the currently active iframe |
| speed | number |
Test execution speed (default: 1) |
| pageLoadTimeout | number |
Page load timeout in milliseconds |
| consoleMessages | BrowserConsoleMessages |
Browser console message log |
Usage Examples
// Internal usage within TestRun role switching
const bookmark = new TestRunBookmark(testRun, role);
// Save the current state before role initialization
await bookmark.init();
// ... role initialization happens here (login, navigate, etc.) ...
// Restore state after role is ready
const stateSnapshot = role.stateSnapshot;
await bookmark.restore(callsite, stateSnapshot);
// testRun is now back to its pre-role state but with new session/auth
Internal Mechanics
init() Flow
- Saves
testRun.ctxandtestRun.fixtureCtxinto local properties - If an iframe is active, switches to the main window via
SwitchToMainWindowCommand - If
role.opts.preserveUrlis not set, records the current URL as the role's redirect URL for this test
restore() Flow
- Sets test run phase to
TEST_RUN_PHASE.inBookmarkRestore - Restores context objects (
ctx,fixtureCtx) - Restores console messages
- Restores speed via
SetTestSpeedCommand(only if changed) - Restores page load timeout via
SetPageLoadTimeoutCommand(only if changed) - Restores dialog handler via
SetNativeDialogHandlerCommand(only if changed) - Navigates to the redirect URL with the state snapshot (using
testRun.navigateToUrl) - If
preserveUrlis not set, restores the working iframe viaSwitchToIframeCommand - Restores the previous test run phase
Error Handling
During iframe restoration, two specific error types are caught and re-thrown as user-friendly errors:
actionElementNotFoundErrorbecomesCurrentIframeNotFoundErroractionIframeIsNotLoadedErrorbecomesCurrentIframeIsNotLoadedError
All errors during restoration have the callsite attached for accurate stack trace reporting.