Overview
Drama Finder integrates seamlessly with Spring Boot to provide robust end-to-end testing for Vaadin applications. This guide walks you through setting up your test infrastructure using the AbstractBasePlaywrightIT base class.
Project Setup
Add Drama Finder dependency
Add the Drama Finder library as a test dependency in your pom.xml: < dependency >
< groupId > org.vaadin.addons </ groupId >
< artifactId > dramafinder </ artifactId >
< version > 1.0.0-SNAPSHOT </ version >
< scope > test </ scope >
</ dependency >
Configure Maven Failsafe Plugin
Integration tests in Drama Finder use the maven-failsafe-plugin and follow the *IT.java naming convention: < plugin >
< groupId > org.apache.maven.plugins </ groupId >
< artifactId > maven-failsafe-plugin </ artifactId >
< version > 3.0.0-M5 </ version >
< executions >
< execution >
< goals >
< goal > integration-test </ goal >
< goal > verify </ goal >
</ goals >
</ execution >
</ executions >
</ plugin >
Unit tests (using *Test.java) run with Surefire, while integration tests (using *IT.java) run with Failsafe during the verify phase.
Create base test class
Create a Spring-specific base class that extends AbstractBasePlaywrightIT: package com.example.tests;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.vaadin.addons.dramafinder.AbstractBasePlaywrightIT;
public abstract class SpringPlaywrightIT extends AbstractBasePlaywrightIT {
@ LocalServerPort
private int port ;
@ Override
public String getUrl () {
return String . format ( "http://localhost:%d/" , port);
}
}
This class automatically injects the random port that Spring Boot assigns to your test server.
Create your first test
Create a test class that extends your Spring base class: package com.example.tests;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.vaadin.addons.dramafinder.element.ButtonElement;
import org.vaadin.addons.dramafinder.element.TextFieldElement;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
@ SpringBootTest ( webEnvironment = WebEnvironment . RANDOM_PORT )
public class LoginViewIT extends SpringPlaywrightIT {
@ Override
public String getView () {
return "login" ;
}
@ Test
public void testLoginForm () {
TextFieldElement username = TextFieldElement . getByLabel (page, "Username" );
TextFieldElement password = TextFieldElement . getByLabel (page, "Password" );
ButtonElement loginButton = ButtonElement . getByText (page, "Login" );
username . assertVisible ();
password . assertVisible ();
loginButton . assertEnabled ();
username . setValue ( "testuser" );
password . setValue ( "password123" );
loginButton . click ();
assertThat ( page . getByText ( "Welcome, testuser!" )). isVisible ();
}
}
Understanding AbstractBasePlaywrightIT
The AbstractBasePlaywrightIT class provides essential infrastructure for your tests:
Lifecycle Management
@ BeforeAll
public static void setup () {
// Creates Playwright instance and launches browser (Chromium by default)
// Uses ThreadLocal for thread-safe parallel test execution
}
@ BeforeEach
public void setupTest () {
// Creates new page instance
// Navigates to getUrl() + getView()
// Waits for Vaadin Flow to be ready
// Sets default timeouts
}
@ AfterEach
public void cleanupTest () {
// Closes the page after each test
}
@ AfterAll
public static void cleanup () {
// Closes browser and Playwright instance
}
Vaadin Flow Readiness Check
The base class includes a WAIT_FOR_VAADIN_SCRIPT that ensures Vaadin Flow is fully loaded before tests run:
page . waitForFunction (WAIT_FOR_VAADIN_SCRIPT);
This prevents flaky tests by ensuring all Vaadin clients are inactive before proceeding.
Default Timeouts
page . setDefaultNavigationTimeout ( 4000 ); // 4 seconds for navigation
page . setDefaultTimeout ( 15000 ); // 15 seconds for element operations
Adjust these timeouts in your base class if your application needs more time to load or respond.
Accessing Playwright Objects
The base class provides protected accessors:
protected Page page ; // Available as field
protected Page getPage (); // Accessor method
protected Browser getBrowser (); // For multi-page scenarios
protected Playwright getPlaywright (); // For advanced configuration
Running Tests
Run all integration tests
Or with the integration test profile:
Run a single test class
mvn -Dit.test=LoginViewIT verify
Run a specific test method
mvn -Dit.test=LoginViewIT #testLoginForm verify
Debug with visible browser
By default, tests run in headless mode. To see the browser:
mvn -Dit.test=LoginViewIT -Dheadless=false verify
Or create a debug profile in your pom.xml:
< profile >
< id > debug-ui </ id >
< properties >
< headless > false </ headless >
</ properties >
</ profile >
Then run:
mvn -Pdebug-ui -Dit.test=LoginViewIT verify
Headless Mode Configuration
The AbstractBasePlaywrightIT class checks for headless mode in this order:
System property: -Dheadless=false
Environment variable: HEADLESS=false
Default: true (headless)
protected static boolean isHeadless () {
String propertyValue = System . getProperty ( "headless" );
if (propertyValue == null || propertyValue . isBlank ()) {
propertyValue = System . getenv ( "HEADLESS" );
}
if (propertyValue == null || propertyValue . isBlank ()) {
return true ;
}
return Boolean . parseBoolean (propertyValue);
}
HasTestView Interface
Implement the HasTestView interface to specify the view path for your test:
public interface HasTestView {
String getUrl (); // Base URL (provided by SpringPlaywrightIT)
default String getView () {
return "" ; // Override to specify view path
}
}
Example
@ SpringBootTest ( webEnvironment = WebEnvironment . RANDOM_PORT )
public class CheckoutViewIT extends SpringPlaywrightIT implements HasTestView {
@ Override
public String getView () {
return "checkout" ; // Navigates to http://localhost:{port}/checkout
}
}
If you don’t override getView(), tests will navigate to the root path (/).
Thread Safety and Parallel Execution
The base class uses ThreadLocal storage for Playwright, Browser, and Page instances, making it safe for parallel test execution:
private static final ThreadLocal < Playwright > playwright = new ThreadLocal <>();
private static final ThreadLocal < Browser > browser = new ThreadLocal <>();
To enable parallel execution in Maven:
< plugin >
< groupId > org.apache.maven.plugins </ groupId >
< artifactId > maven-failsafe-plugin </ artifactId >
< configuration >
< parallel > classes </ parallel >
< threadCount > 4 </ threadCount >
</ configuration >
</ plugin >
CI/CD Integration
GitHub Actions
name : Integration Tests
on : [ push , pull_request ]
jobs :
test :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- uses : actions/setup-java@v3
with :
java-version : '21'
distribution : 'temurin'
- name : Install Playwright browsers
run : mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps chromium"
- name : Run integration tests
run : mvn verify
env :
HEADLESS : true
GitLab CI
integration-tests :
image : maven:3.9-eclipse-temurin-21
stage : test
script :
- mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps chromium"
- mvn verify
variables :
HEADLESS : "true"
Playwright browsers are downloaded automatically on first run, but explicitly installing them in CI ensures consistent behavior.
Troubleshooting Setup Issues
Browser not found
If you see “Executable doesn’t exist” errors, install Playwright browsers:
mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install"
Tests timing out
Increase timeouts in your base class:
@ BeforeEach
public void setupTest () throws Exception {
page = browser . get (). newPage ();
page . navigate ( getUrl () + getView ());
page . waitForFunction (WAIT_FOR_VAADIN_SCRIPT);
page . setDefaultNavigationTimeout ( 10000 ); // Increased to 10 seconds
page . setDefaultTimeout ( 30000 ); // Increased to 30 seconds
}
Port conflicts
Spring Boot automatically assigns a random port with WebEnvironment.RANDOM_PORT. If you need a specific port:
@ SpringBootTest ( webEnvironment = WebEnvironment . DEFINED_PORT )
@ TestPropertySource ( properties = "server.port=8888" )
public class MyViewIT extends SpringPlaywrightIT {
// ...
}
Vaadin not loading
If the WAIT_FOR_VAADIN_SCRIPT times out, check:
Dev mode bundle is built (mvn vaadin:build-frontend)
No JavaScript errors in console (enable debug mode to see)
Network requests are completing successfully
Next Steps
Best Practices Learn best practices for maintainable tests
Common Patterns Explore real-world testing scenarios
Troubleshooting Solutions to common testing issues
Element Reference Browse all available element wrappers