Principle:DevExpress Testcafe Smart Assertions
| Knowledge Sources | |
|---|---|
| Domains | Testing, Web_Automation |
| Last Updated | 2026-02-12 04:00 GMT |
Overview
Smart Assertions is the concept of verifying expected conditions in automated tests with built-in retry logic that accommodates asynchronous DOM updates and dynamic page behavior.
Description
Traditional assertions in testing frameworks evaluate conditions once and immediately fail if the condition is not met. In web testing, this approach is problematic because:
- DOM elements may not be available immediately after page load
- Element properties change asynchronously (AJAX updates, animations)
- User interactions trigger delayed state changes
- Network requests complete at unpredictable times
Smart assertions solve this by automatically retrying the assertion until it passes or a timeout expires. This eliminates the need for manual waiting logic and makes tests more reliable. The framework distinguishes between:
- Static values: Evaluated once (literals, variables)
- Re-executable values: Evaluated on each retry attempt (Selector properties, ClientFunctions)
Smart assertions provide:
- Automatic retry with configurable timeout
- Retry delay between attempts
- Support for complex assertion types (equality, comparison, pattern matching)
- Clear failure messages with actual vs expected values
- Optional custom error messages
Usage
Use smart assertions when:
- Verifying element properties that may change asynchronously
- Checking conditions after user interactions
- Waiting for AJAX responses to update the UI
- Validating dynamic content
- Testing animations or timed transitions
- Verifying counts of element collections
Theoretical Basis
Smart assertions follow these principles:
Retry Loop:
// Pseudocode
async function smartAssert(actual, expected, matcher, options) {
const startTime = now()
const timeout = options.timeout || defaultTimeout
while (now() - startTime < timeout) {
const actualValue = await evaluate(actual)
const expectedValue = await evaluate(expected)
if (matcher(actualValue, expectedValue)) {
return // Assertion passed
}
if (isReExecutable(actual) || isReExecutable(expected)) {
await delay(retryDelay)
continue // Retry
} else {
throw AssertionError(actualValue, expectedValue)
}
}
throw TimeoutError()
}
Re-executable Detection: Values that trigger retry:
- Selector properties (.count, .visible, .textContent, etc.)
- ClientFunction results
- Promises
Static values that don't trigger retry:
- Literals (strings, numbers, booleans)
- Variables
- Plain objects and arrays
Assertion Types:
// Equality
expect(actual).eql(expected)
// Comparison
expect(actual).gt(expected)
expect(actual).gte(expected)
expect(actual).lt(expected)
expect(actual).lte(expected)
// Boolean
expect(actual).ok()
expect(actual).notOk()
// String/Array operations
expect(actual).contains(substring)
expect(actual).match(pattern)
// Type checking
expect(actual).typeOf(type)
// Range
expect(actual).within(min, max)
Configuration:
- Default timeout from test configuration
- Per-assertion timeout override
- Retry delay (typically 200ms)
- Custom error messages