Docs

Documentation versions (currently viewingVaadin 25)
Documentation translations (currently viewingEnglish)

Test User Interactions

Learn how a browserless test works, then fill in forms, select Grid rows, confirm dialogs, and test navigation, shortcuts, and menus.

The examples in this guide use the plain Java setup. For another framework, change the base class as described in Use the Examples with Your Framework. Each example belongs inside a test method unless shown otherwise.

How a Browserless Test Works

Each setup guide ends with a test for the same HelloWorldView. The test navigates to the view, enters a name, clicks a button, and checks the notification that appears:

Source code
Java
final HelloWorldView helloView = navigate(HelloWorldView.class);

test(helloView.name).setValue("Test");
test(helloView.sayHello).click();

Notification notification = find(Notification.class).single();
Assertions.assertEquals("Hello Test", test(notification).getText());

The following sections explain each step. They work the same way with every setup; only the test base class differs.

The navigate() method opens a view, as a user would navigate to it in the browser. It returns the view instance so you can interact with it directly.

Source code
Java
final HelloWorldView helloView = navigate(HelloWorldView.class);

Use the Java API Directly

Since the test runs on the server side, it has direct access to the Java component API. The TextField and Button fields of HelloWorldView are package-private, so a test in the same Java package can read them — for example, if the view is in src/main/java/com/example/app/, put the test in src/test/java/com/example/app/.

Source code
Java
// Read a component's value directly
String currentValue = helloView.name.getValue();

// Check component state
boolean isEnabled = helloView.sayHello.isEnabled();
boolean isVisible = helloView.name.isVisible();

Simulate User Actions with Testers

To simulate how a user interacts with a component, wrap it with test(). This returns a component-specific tester that provides methods like setValue(), click(), and getText(). Unlike calling the Java API directly, tester methods also verify that the component is in a usable state — visible, enabled, and attached to the UI.

Source code
Java
// Simulate typing into a text field
test(helloView.name).setValue("Test");

// Simulate clicking a button
test(helloView.sayHello).click();

// Read the text a user would see
String text = test(notification).getText();

Each Vaadin component has a tester tailored to its behavior. For example, a CheckboxTester uses click() to toggle checked state, a ComboBoxTester has selectItem(), and a GridTester has getRow(). See Component Testers for supported operations and Test a Custom Component to build your own tester.

Find Components

Not every component is stored in a view field. For example, the Notification in the test is created inside a click listener and isn’t referenced anywhere in the view. Use the find() query method to find components in the UI by their type:

Source code
Java
// Find the single Notification currently open
Notification notification = find(Notification.class).single();

The query API supports filtering by properties, predicates, and scoping to specific parts of the component tree. See Querying Components for details.

Find the Component to Exercise

Use a label or visible text when it identifies the component unambiguously. When the same field appears more than once, for example in the view and in an open dialog, scope the query to the view:

Source code
Java
TextField name = findInView(TextField.class)
        .withLabel("First name").single();
test(name).setValue("Ada");
Assertions.assertEquals("Ada", name.getValue());

Use find(Type.class, container) to restrict a query to a particular container. A component inside a Grid renderer may need to be obtained through test(grid).getCellComponent(…​) before it can be exercised. If a top-level query finds nothing, the component may be inside a renderer or a closed overlay, which queries don’t reach. See Query Boundaries and Component Queries for the full behavior.

Fill In and Submit a Form

Set each field through its tester, then click the submit button. For a SignUpView with a Name text field, an Email email field, and a Sign up button that shows a welcome notification:

Source code
Java
navigate(SignUpView.class);
test(find(TextField.class).withLabel("Name").single()).setValue("Ada");
test(find(EmailField.class).withLabel("Email").single())
        .setValue("ada@example.com");
test(find(Button.class).withText("Sign up").single()).click();

Assertions.assertEquals("Welcome, Ada",
        test(find(Notification.class).single()).getText());

A tester sets the value the way a user does, so the field’s validation runs as it would in the browser:

Source code
Java
EmailField email = find(EmailField.class).withLabel("Email").single();
test(email).setValue("not an email");
Assertions.assertTrue(email.isInvalid());

Select a Grid Row

Use the Grid tester to read rows and select items. For a PersonListView with a people grid of Person items and a details span that shows the selected person:

Source code
Java
var view = navigate(PersonListView.class);
var grid = test(view.people);
Assertions.assertEquals(3, grid.size());
Assertions.assertEquals("Ada", grid.getCellText(0, 0));

grid.select(0);
Assertions.assertEquals("Selected: Ada", view.details.getText());

The tester also has clickRow() for views that react to item clicks, and getRow() for reading the item on a row. See Component Testers for the other Grid operations.

Confirm a Dialog

An open dialog is attached to the UI, so a top-level query finds it. For an AccountView whose Delete account button opens a ConfirmDialog, and whose status span reports the result:

Source code
Java
var view = navigate(AccountView.class);
test(find(Button.class).withText("Delete account").single()).click();

var dialog = test(find(ConfirmDialog.class).single());
Assertions.assertEquals("Delete account?", dialog.getHeader());
dialog.confirm();

Assertions.assertEquals("Account deleted", view.status.getText());

Call cancel() or reject() on the tester to click the dialog’s other buttons. For a Dialog, find its buttons with find() while the dialog is open.

Use Test IDs

Use Component.setTestId() to assign a stable identifier to a component for use in tests. This sets the data-testid HTML attribute on the component’s element, which can also be used by browser-based testing frameworks:

Source code
Java
Button submitButton = new Button("Submit");
submitButton.setTestId("submit-button");

// Later, retrieve the test ID
String testId = submitButton.getTestId(); // "submit-button"

Use a test ID when a label or visible text would be ambiguous or would change with translations. Keep the identifier independent of styling and layout.

Browserless tests can use the same identifier: the testId() terminal operator and the withTestId() filter look up components by their test ID:

Source code
Java
Button submit = find(Button.class).testId("submit-button");

See Querying Components for details.

Use Locators for Repeated Interactions

If your test extends a base class, implement Locators to combine lookup and interaction in one call:

Source code
CartViewLocatorsTest.java
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.vaadin.browserless.BrowserlessTest;
import com.vaadin.browserless.locator.Locators;

class CartViewLocatorsTest extends BrowserlessTest implements Locators {
    @Test
    void addItem_increasesCartSize() {
        navigate(CartView.class);
        findButton().withText("Add to cart").click();
        Assertions.assertEquals("1 item",
                findSpan().withId("cart-size").getText());
    }
}

This example assumes a CartView with an Add to cart button and a span with the ID cart-size that shows the number of items. With Java EE/CDI, add implements Locators to your AbstractCdiViewTest subclass. For locator reuse and invalidation rules, see Locator Resolution.

Test Navigation

Navigate by location when the outcome may be a redirect, and pass the view class you expect to end up in. The call fails if navigation ends in another view:

Source code
Java
navigate("protected", LoginView.class);

A location can also carry a query string and fragment; for example, navigate("orders/123?tab=history#details", OrderView.class). Assert the state selected by those parameters after navigation.

For route parameters and other navigation forms, see Navigation.

Test Keyboard Shortcuts

Fire a shortcut with fireShortcut(), then assert the same outcome as the matching button click. For a form with a Ctrl+S save shortcut:

Source code
Java
fireShortcut(Key.KEY_S, KeyModifier.CONTROL);
// Assert the saved state or the confirmation shown by your view.

Test Menu Actions

Use a menu tester to reach overlay content. For a view exposing a contextMenu field with a checkable Bold item:

Source code
Java
var view = navigate(EditorView.class);
var menu = test(view.contextMenu);
menu.open();
menu.clickItem("Bold");
Assertions.assertTrue(menu.isItemChecked("Bold"));

Open the menu before clicking items or reading their state; the tester throws an exception for a closed menu. For nested actions, pass a text path such as clickItem("Share", "Email"). For a menu containing custom components, call test(menuComponent).find(…​). This query also works while the menu is closed, but the components it returns stay detached until the menu opens. See Overlay Component Testers for indexing and attachment semantics.

BDC6250E-E9D6-44DD-9B67-777C0F7E98AA