Implementation:DevExpress Testcafe ClientFunctionBuilder
| Knowledge Sources | |
|---|---|
| Domains | Testing, Client-Side Execution, Compilation |
| Principle | Client function compilation |
| Last Updated | 2026-02-12 12:00 GMT |
Overview
ClientFunctionBuilder compiles a JavaScript function into a serialized form that can be transmitted to and executed within the browser context, returning results back to the Node.js test process.
Description
Defined in src/client-functions/client-function-builder.js, ClientFunctionBuilder is the core engine behind TestCafe's ClientFunction API. When instantiated, it:
- Validates the provided options (must be a non-null object;
boundTestRunanddependenciesare validated if present). - Compiles the user-supplied function into a string code representation using
compileClientFunction. - Creates a replicator (serializer/deserializer) with appropriate transforms for encoding function arguments and dependencies for cross-process transport.
The getFunction() method returns a callable that, when invoked during a test, resolves the current test run, captures the callsite for error reporting, and delegates to _executeCommand. This method builds an ExecuteClientFunctionCommand with the compiled code, encoded arguments, and encoded dependencies, then executes it via the test run's command infrastructure. The result is returned as a ReExecutablePromise, enabling smart assertion integration.
The .with(options) method on the returned function creates a new builder with merged options (e.g., to override dependencies or boundTestRun), supporting the chainable pattern.
Key design features:
- Lazy execution via
ReExecutablePromisefor integration with TestCafe's assertion retry mechanism. - Callsite tracking for accurate error reporting pointing back to user test code.
- Replicator-based serialization to safely encode/decode function arguments across the Node-to-browser boundary.
Usage
ClientFunctionBuilder is the internal implementation behind the public ClientFunction API. Use ClientFunction when you need to execute arbitrary JavaScript in the browser and retrieve the result in your test code. The builder handles compilation, serialization, execution, and result deserialization transparently.
Code Reference
Source Location
- Repository: DevExpress_Testcafe
- File: src/client-functions/client-function-builder.js
- Lines: 1-191
Signature
export default class ClientFunctionBuilder {
constructor (fn, options, callsiteNames = {}) { ... }
_renderError (error) { ... }
_decorateFunction (clientFn) { ... }
_getClientFnWithOverriddenOptions (options) { ... }
getBoundTestRun () { ... }
_getTestRun () { ... }
_getObservedCallsites () { ... }
getFunction () { ... }
getCommand (args = []) { ... }
// Overridable methods
getFunctionDependencies () { ... }
_createTestRunCommand (encodedArgs, encodedDependencies) { ... }
_getCompiledFnCode () { ... }
_createInvalidFnTypeError () { ... }
_executeCommand (args, testRun, callsite) { ... }
_processResult (result) { ... }
_validateOptions (options) { ... }
_getReplicatorTransforms () { ... }
}
Import
import ClientFunctionBuilder from '../client-functions/client-function-builder';
// Public API:
// import { ClientFunction } from 'testcafe';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| fn | Function |
Yes | The JavaScript function to compile and execute in the browser. Must be a function type (not a string or other value).
|
| options | Object |
No | Configuration options. Defaults to {} if null or undefined.
|
| options.dependencies | Object |
No | An object whose properties are made available inside the client function's scope. |
| options.boundTestRun | TestRun | No | Explicitly binds the client function to a specific test run (required when calling outside a test action context). |
| callsiteNames | Object |
No | Object with instantiation and execution callsite name strings for error reporting.
|
Outputs
| Name | Type | Description |
|---|---|---|
| getFunction() | Function |
Returns a callable client function. When invoked with arguments, it returns a ReExecutablePromise that resolves to the browser-side return value.
|
| getCommand(args) | ExecuteClientFunctionCommand |
Returns the raw test-run command object with encoded arguments and dependencies. |
| getBoundTestRun() | null | Returns the bound test run instance, or null if not explicitly bound.
|
| compiledFnCode | null | The compiled string representation of the client function. |
Usage Examples
import { ClientFunction } from 'testcafe';
// Basic usage - get the current page URL
const getPageUrl = ClientFunction(() => window.location.href);
// With dependencies
const elementExists = ClientFunction((selector) => {
return !!document.querySelector(selector);
});
// With options
const getLocalStorageItem = ClientFunction((key) => {
return window.localStorage.getItem(key);
});
fixture `Client Function Tests`
.page `https://example.com`;
test('Check page URL', async t => {
const url = await getPageUrl();
await t.expect(url).eql('https://example.com/');
});
test('Use .with() to override options', async t => {
const getTitle = ClientFunction(() => document.title);
// Create a new client function with additional dependencies
const getTitleWithPrefix = getTitle.with({
dependencies: { prefix: 'Page: ' },
});
const title = await getTitleWithPrefix();
await t.expect(title).ok();
});
Related Pages
Note: This is an orphan Implementation — client function compilation is an internal subsystem with no dedicated Principle page.