Component Testers
Component testers simulate user interactions in browserless tests. Each tester wraps a specific component type and provides methods that mirror what a real user can do — clicking, typing, and selecting items.
Testers provide actions such as setValue(), click(), and selectItem() with usability checks.
Some testers also expose component-specific inspection methods, such as grid row access and notification text.
The component’s Java API remains available for reading values, visibility, and other state.
Using Component Testers
Wrap any component with the test() method of a window — or of a base class or extension — to get a tester for it:
Source code
Java
window.test(textField).setValue("Jane");
window.test(button).click();
// Reading state is done via the component API directly
String value = textField.getValue();A tester drives the component through the same path the browser uses, so a listener that branches on isFromClient() behaves in a test as it does in a running application.
The test() method returns a tester matched to the component’s type. You can also request a specific tester type explicitly:
Source code
Java
TextFieldTester tester = window.test(TextFieldTester.class, textField);Usability Checks
Before performing any action, testers verify that the component is in a usable state. An action fails with a clear error message if the component is:
-
Not visible
-
Not enabled
-
Not attached to the UI
-
Behind a modal overlay
-
Read-only, when it is a value component
This catches common issues where a test passes by calling the Java API directly, but the corresponding user action would be impossible in a browser.
Common Testers
The following table shows frequently used testers and their key methods:
| Component | Key Tester Methods |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tip
|
Selection Uses String Labels
The Source codeJava |
Slot-Scoped Finders
Components that place content in named slots expose finders scoped to a single slot, so that a query doesn’t have to sift through everything the component holds:
Source code
Java
Button save = window.test(dialog).findInFooter(Button.class).withText("Save").single();
Span caption = window.test(card).findInHeader(Span.class).single();
Button next = window.test(splitLayout).findInPrimary(Button.class).single();DialogTester and CardTester have findInHeader() and findInFooter(), SplitLayoutTester has findInPrimary() and findInSecondary(), and LoginOverlayTester has findInFooter() and findInCustomFormArea(). These are tester methods; the generated locators don’t have them. For any other slot, filter a query with withinSlot() — see Filtering by Slot.
Constraint Enforcement
Testers enforce the constraints that a browser enforces, and they stop where a browser stops.
A constraint that keeps the value out of the field makes the tester throw. The maximum length of a text field and an allowed character pattern work this way, because a browser drops the keystrokes that break them:
Source code
Java
TextField code = new TextField("Code");
code.setMaxLength(5);
// Throws: a browser stops the typing at five characters
window.test(code).setValue("123456");A constraint that only marks the field invalid works differently: a browser commits such a value, and so does the tester. This covers min, max, step, and a required value on NumberField, DatePicker, TimePicker, and DateTimePicker. Assert the outcome with isValid(), which runs the component’s own default validator and honors an invalid state set from outside, such as the state a Binder sets:
Source code
Java
NumberField amount = new NumberField("Amount");
amount.setMin(0);
// Committed, as in a browser, and the field is left invalid
window.test(amount).setValue(-5.0);
Assertions.assertFalse(window.test(amount).isValid());To test how the application reacts to a value that no user can produce, set that value through the component’s Java API instead of the tester:
Source code
Java
// Bypass the tester to exercise the validation logic
code.setValue("123456");Clearing a Value
Emptying a field works the same way in every text, number, date, and time tester. clear() models deleting the contents from the keyboard, which a user can do whether or not the component shows a clear button. clickClearButton() models clicking that button, and fails when the button is hidden:
Source code
Java
window.test(name).clear(); // Always available
window.test(name).clickClearButton(); // Requires a visible clear buttonA field can legitimately end up invalid once emptied, a required field for instance, so clear() never refuses.
Selection components use their own wording for the same action: deselectItem() on RadioButtonGroupTester, clearSelection() on MultiSelectListBoxTester, and deselectAll() on GridTester. On ComboBoxTester, selectItem(null) clears the selection without a clear button.
Upload Constraints
UploadTester puts files through the same gate the browser applies before it sends anything to the server: setMaxFiles(), setMaxFileSize(), and the accepted file types, in that order. A file that fails one of them never reaches the upload handler or receiver, and a FileRejectedEvent is fired, as it is in the browser.
An upload is different from a value: a refused file is no more of an error in the tester than it is in the browser, so the upload doesn’t throw. Check what became of each file with getLastUploadStatus(), or call ensureUploaded() to fail the test unless every file of the last upload went through:
Source code
Java
window.test(upload).upload(new File("report.pdf"));
window.test(upload).ensureUploaded();maxFiles is checked against an emulated file list, so files stay in it between calls, the same way the entries the browser shows do. An Upload with a plain Receiver implicitly allows one file, which makes a second upload fail; removeFile() makes room for it the way the user does.
getFiles() returns that file list, in the order the browser shows it: the most recently added file first. Every upload adds an entry of its own, even for a file with the same name as one already in the list. When several entries share a name, removeFile(String) removes the most recently added one. To reach a specific entry, pass its position in getFiles() to removeFile(int) instead.
To test how the application handles a failure, uploadFailed() simulates a transfer that fails, and uploadAborted() simulates the user aborting it. ensureUploadFailed() is the counterpart of ensureUploaded(): it fails the test unless at least one file of the last upload failed or was rejected.
Uploads without Auto Upload
When auto upload is turned off with setAutoUpload(false), the browser keeps the files the user picks in the file list. It sends each one only when the user clicks its start button. The tester does the same: upload() and uploadAll() still check the constraints, but an accepted file waits in the file list with the PENDING status and doesn ’t reach the upload handler. Start it with startUpload(), by file name, by File, or by position in the list:
Source code
Java
upload.setAutoUpload(false);
window.test(upload).upload(file);
// Nothing has reached the upload handler yet
window.test(upload).startUpload(file);
window.test(upload).ensureUploaded();When several waiting entries share a name, startUpload(String) starts the most recently added one. Starting a file that isn’t waiting throws an IllegalArgumentException.
uploadFailed() and uploadAborted() add the file and start its transfer at once, whether auto upload is on or off.
Modular Upload Components
The components of the modular upload — UploadButton, UploadDropZone, and UploadFileList — have testers that emulate the UploadManager they’re linked to, the way the browser does:
Source code
Java
manager.setMaxFiles(1);
window.test(uploadButton).upload(reportFile);
window.test(uploadButton).ensureUploaded();
// The file list is full, so the button can't be used
Assertions.assertFalse(window.test(uploadButton).isUsable());
window.test(fileList).removeFile(reportFile);
window.test(dropZone).drop(otherFile);UploadButtonTester simulates the user picking files in the file dialog, and UploadDropZoneTester simulates the user dropping them on the drop zone. Both put the files through the manager’s maxFiles, maxFileSize, and accepted file type checks, in that order. A refused file fires an UploadManager.FileRejectedEvent with the matching FileRejectionReason, never reaches the upload handler, and is reported as REJECTED. As with UploadTester, a refused file doesn’t make the upload throw, so check the outcome with getLastUploadStatus(), ensureUploaded(), or ensureUploadFailed().
Both testers also have uploadFailed() and uploadAborted(). A failed file stays in the file list and keeps counting toward maxFiles. An aborted file is removed from the list, which fires an UploadManager.FileRemovedEvent and frees its slot.
All the components linked to the same manager share one file list. UploadFileListTester reads it with getFiles(), most recently added file first. It also simulates the buttons on its entries: removeFile() removes a file and frees its slot, and startUpload() starts a file that waits because auto upload is turned off. Both accept a file name, a File, or a position in the list. UploadManager.clearFileList() empties the list, as it does in the browser.
As in the browser, none of the three components is usable in these cases:
-
It isn’t linked to a manager.
-
The manager’s owner component isn’t attached.
-
The manager or its owner component is disabled.
The button and the drop zone also aren’t usable when the file list already holds maxFiles files. The exception thrown for an action on a component that isn’t usable tells which of these applies.
Base Methods
All testers inherit from ComponentTester, which provides methods useful across component types:
| Method | Description |
|---|---|
| Click the component. All variants accept optional |
| Returns |
| Simulates a server round-trip, processing any pending client-server communication. |
| Fires a DOM event on the component, such as |
| Creates a component query scoped to the children of the wrapped component. |
Standalone Component Environments
BrowserlessUIContext.forComponent(component) creates a route-free environment and attaches the component to its UI.
Closing the returned context tears down the environment.
The supplier overload creates the component after installing the Vaadin thread-locals, allowing its constructor to access the current UI and session.
BrowserlessApplicationContext.forComponent(Supplier) creates a fresh component for each new window.
Custom Tester Contracts
Custom testers extend ComponentTester<C> and declare the component type with @Tests.
The fqn attribute accepts a fully qualified class name when a class literal is unsuitable.
Custom action methods call ensureComponentIsUsable() before performing the interaction.
They can delegate to other component testers.
Tester discovery scans com.vaadin.flow.component by default.
@ComponentTesterPackages adds application packages to scan for testers.
Extensions and application-context builders also support tester-package configuration.
For a worked example, see Test a Custom Component.
A1B2C3D4-E5F6-7890-ABCD-EF1234567890