Set Up Browserless Tests in Plain Java
Use this setup when the view and its collaborators can be constructed without a dependency injection container.
Tests create the Vaadin environment with BrowserlessApplicationContext, which doesn’t start a dependency injection container.
For Java EE/CDI injection, use the CDI setup; for Quarkus, use the Quarkus setup.
Add Dependencies
Assuming you’ve imported the Vaadin Bill-of-Materials (BOM) and have a Maven project, add the browserless-test-junit6 dependency with a test scope:
Source code
XML
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>browserless-test-junit6</artifactId>
<scope>test</scope>
</dependency>No other test framework dependencies are required.
Create a Test
Create this view:
Source code
HelloWorldView.java
HelloWorldView.javaimport com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.Route;
@Route("")
public class HelloWorldView extends HorizontalLayout {
TextField name;
Button sayHello;
public HelloWorldView() {
name = new TextField("Your name");
sayHello = new Button("Say hello");
sayHello.addClickListener(e -> {
Notification.show("Hello " + name.getValue());
});
add(name, sayHello);
}
}Create a test class in the same Java package as the view under src/test/java:
Source code
HelloWorldViewTest.java
HelloWorldViewTest.javaimport org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.vaadin.browserless.BrowserlessApplicationContext;
import com.vaadin.browserless.BrowserlessUIContext;
class HelloWorldViewTest {
private BrowserlessApplicationContext app;
private BrowserlessUIContext window;
@BeforeEach
void setUp() {
app = BrowserlessApplicationContext.create(HelloWorldView.class); 1
window = app.newUser().newWindow(); 2
}
@AfterEach
void tearDown() {
app.close(); 3
}
@Test
void setText_clickButton_notificationIsShown() {
window.navigate(HelloWorldView.class); 4
window.findTextField().withLabel("Your name").setValue("Test");
window.findButton().withText("Say hello").click();
Assertions.assertEquals("Hello Test",
window.findNotification().getText());
}
}-
Creates the application context. It scans the package of
HelloWorldViewand its sub-packages for routes; if your views are in several packages, pass a class from each. -
Creates a user with its own Vaadin session, and opens a window for that user. The window shows the root route.
-
Closes the application context, together with every user and window created from it.
-
The test drives the UI through the window: it finds components by their label or text, and types and clicks, as a user does.
See How a Browserless Test Works for what each line of the test method does.
When only one test method needs the application context, create it in the test with try-with-resources instead of in @BeforeEach and @AfterEach methods:
Source code
Java
try (var app = BrowserlessApplicationContext.create(HelloWorldView.class)) {
var window = app.newUser().newWindow();
// Drive the UI through the window and assert the outcome.
}Run the Test
Run the test from your IDE or with mvn test.
The test passes when entering a name and clicking the button shows the expected notification.
Use a Base Class or an Extension Instead
A test can also extend BrowserlessTest, which creates the Vaadin environment with one user and one window before each test method, and closes it afterwards.
The test then calls the window methods on itself:
Source code
HelloWorldViewTest.java
HelloWorldViewTest.javaimport org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.vaadin.browserless.BrowserlessTest;
import com.vaadin.flow.component.notification.Notification;
class HelloWorldViewTest extends BrowserlessTest {
@Test
public void setText_clickButton_notificationIsShown() {
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 base class scans the whole classpath for routes, unless the test class has a @ViewPackages annotation.
If the test class already extends another class, register an instance of BrowserlessExtension to get the same lifecycle.
It’s included in the same dependency.
Source code
CartViewExtensionTest.java
CartViewExtensionTest.javaimport org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import com.vaadin.browserless.BrowserlessExtension;
import com.vaadin.browserless.ViewPackages;
@ViewPackages(classes = CartView.class)
class CartViewExtensionTest {
@RegisterExtension
BrowserlessExtension ext = new BrowserlessExtension();
@Test
void addItemToCart() {
ext.navigate(CartView.class);
ext.findButton().withText("Add to cart").click();
Assertions.assertEquals("1 item",
ext.findSpan().withId("cart-size").getText());
}
}Call the methods on the extension instance to navigate and interact with components.
The example assumes a CartView with an Add to cart button and a span with the ID cart-size that shows the number of items.
For lifecycle and configuration options, see JUnit 6 Extensions.
See Base Classes for when to choose a base class.
Next Steps
-
Test User Interactions explains how the test works and how to cover more complex views.
-
Debug a Failing Browserless Test helps when a test fails.
-
Application, User, and Window Contexts describes the context API in detail.
D68CAC9E-6131-45C9-84E6-6D1CA1E44E81