> Markdown version of [JUnit 6 Extensions](https://vaadin.com/docs/next/flow/testing/browserless/extensions). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# JUnit 6 Extensions (since V25.2)

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](https://vaadin.com/docs/next/flow/testing/browserless/cdi.md). They don’t replace `SpringBrowserlessTest` or `QuarkusBrowserlessTest` — for Spring and Quarkus projects, continue to extend those base classes.

## <a id="when-to-use-an-extension"></a>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.

## <a id="per-method-lifecycle"></a>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`:

```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](https://vaadin.com/docs/next/flow/testing/browserless/locators.md).

## <a id="per-class-lifecycle"></a>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:

```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](https://vaadin.com/docs/next/building-apps/testing/browserless/speed-up-tests.md#sharing-the-vaadin-environment-across-tests).

## <a id="configuring-the-extension"></a>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)` (since undefined)     | Sets a Vaadin application property for the environment the extension creates. `withApplicationProperties(Map)` sets several at once.                |
| `withFeatureFlags(String…​)` (since undefined)                  | Enables the given feature flags. `withFeatureFlag(String, boolean)` enables or disables a single flag. Both methods also have a `Feature` overload. |
| `withConfiguration(BrowserlessConfiguration)` (since undefined) | 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](https://vaadin.com/docs/next/flow/testing/browserless/test-configuration.md).

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

Extension with Programmatic Configuration

```java
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](https://vaadin.com/docs/next/building-apps/testing/browserless/setup-without-spring.md).

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