Docs

JUnit 6 Extensions

Composition-based browserless test setup, per-method and per-class lifecycles, and extension configuration.

Extending BrowserlessTest is the most compact way to write browserless tests, but it requires your test class to use inheritance for the Vaadin setup. When a project already has its own test base class, or you prefer composition over inheritance, the BrowserlessExtension and BrowserlessClassExtension JUnit 6 extensions provide the same functionality without requiring a specific superclass.

Note
These extensions are part of the browserless-test-junit6 artifact. They do not apply the custom servlet and Weld initialization from CDI Test Integration. They don’t replace SpringBrowserlessTest or QuarkusBrowserlessTest — for Spring and Quarkus projects, continue to extend those base classes.

When to Use an Extension

Use an extension when any of the following applies:

  • The test class already extends another base class that can’t be changed.

  • The project standardizes on composition-based JUnit 6 extensions.

Per-Method Lifecycle

BrowserlessExtension creates a fresh Vaadin environment before each test method and tears it down after. Register it as an instance field with @RegisterExtension:

Source code
Java
@RegisterExtension
BrowserlessExtension ext = new BrowserlessExtension();

Navigation, queries, and tester interactions are available as methods on the extension instance — ext.navigate(), ext.find(), ext.findInView(), ext.test(), ext.getCurrentView(), ext.fireShortcut(), ext.roundTrip(), and ext.runPendingSignalsTasks(). The extension also exposes typed locator entry points such as ext.findButton() and ext.findTextField(); see Component Locators.

Per-Class Lifecycle

BrowserlessClassExtension initializes the Vaadin environment once in @BeforeAll and shares it across all tests in the class. Register it as a static field:

Source code
Java
@RegisterExtension
static BrowserlessClassExtension ext = new BrowserlessClassExtension();

The session and UI are shared by all test methods in the class. State changes persist between methods; the extension does not reset application state. Base-class tests always recreate the environment per method. For a practical comparison, see Sharing the Vaadin Environment Across Tests.

Configuring the Extension

Both extensions support a builder-style API for configuration, used as an alternative or in addition to annotations.

Table 1. Builder API
Method Description

withViewPackages(Class<?>…​)

Adds the packages of the given classes to the route scan. Equivalent to @ViewPackages(classes = …​).

withViewPackages(String…​)

Adds package names (as strings) to the route scan. Equivalent to @ViewPackages(packages = …​).

withServices(Class<?>…​)

Registers custom implementations with the Vaadin Lookup SPI.

withComponentTesterPackages(String…​)

Adds packages to scan for custom ComponentTester implementations. Equivalent to @ComponentTesterPackages.

withApplicationProperty(String, String)

Sets a Vaadin application property for the environment the extension creates. withApplicationProperties(Map) sets several at once.

withFeatureFlags(String…​)

Enables the given feature flags. withFeatureFlag(String, boolean) enables or disables a single flag. Both methods also have a Feature overload.

withConfiguration(BrowserlessConfiguration)

Applies a configuration built elsewhere as the baseline that the other methods add to, so that several test classes can share it.

Application properties, feature flags, and Lookup services can also be declared with the @BrowserlessTestConfig annotation. On BrowserlessExtension it works both on the test class and on a single test method; BrowserlessClassExtension creates one environment for the whole class, so there the annotation belongs on the test class. See Test Configuration.

The @ViewPackages annotation still works when placed on the test class; programmatic configuration adds to what the annotation declares.

Source code
Extension with Programmatic Configuration
class AdminViewTest {

    @RegisterExtension
    BrowserlessExtension ext = new BrowserlessExtension()
            .withViewPackages("com.example.views", "com.example.admin")
            .withServices(CustomInstantiatorFactory.class)
            .withComponentTesterPackages("com.example.testers");

    @Test
    void adminDashboardLoads() {
        AdminDashboardView view = ext.navigate(AdminDashboardView.class);
        Assertions.assertNotNull(view);
    }
}

For a worked example, see Set Up Browserless Tests in Plain Java.

B51F9D4A-2E73-4B18-8C6F-9A3D7E2B1C04

Updated