A lightweight Web UI test automation framework built with Kotlin, Playwright, JUnit 5, and Allure.
The project demonstrates Page Object architecture, isolated browser contexts, JUnit 5 lifecycle management, parameter injection, and automatic screenshots on test failure.
| Tool | Version | Purpose |
|---|---|---|
| Kotlin | 2.3.20 | Primary programming language |
| Java | 24 | JVM toolchain |
| Playwright | 1.55.0 | Browser automation |
| JUnit | 5.14.4 | Test runner and lifecycle management |
| Allure Java | 2.35.2 | Test reporting integration |
| Allure Gradle Plugin | 4.0.2 | Report generation |
| AssertJ | 3.27.7 | Fluent assertions |
| Kotlin Logging | 7.0.3 | Logging facade |
| Logback | 1.5.13 | Logging implementation |
| Gradle | 9.5.1 | Build system with Kotlin DSL |
The tests cover the public demo application:
https://www.saucedemo.com
src/
├── main/kotlin/
│ ├── config/
│ │ └── TestConfig.kt
│ ├── context/
│ │ ├── PageHolder.kt
│ │ └── PlaywrightHolder.kt
│ ├── data/enums/
│ │ └── BrowserEngine.kt
│ ├── extensions/
│ │ └── PlaywrightExtension.kt
│ └── pages/
│ ├── BasePage.kt
│ ├── CartPage.kt
│ ├── CheckoutCompletePage.kt
│ ├── CheckoutStepOnePage.kt
│ ├── CheckoutStepTwoPage.kt
│ ├── InventoryPage.kt
│ └── LoginPage.kt
└── test/
├── kotlin/
│ ├── CheckoutTest.kt
│ ├── InventoryTest.kt
│ └── LoginTest.kt
└── resources/
├── META-INF/services/
│ └── org.junit.jupiter.api.extension.Extension
├── allure.properties
└── junit-platform.properties
Page-specific actions and assertions are encapsulated inside Page Object classes. Tests describe user scenarios without directly working with selectors.
LoginPage(page)
.open()
.login("standard_user", "secret_sauce")
.addProductToCartByName("Sauce Labs Backpack")
.goToCart()
.shouldHaveItemCount(1)PlaywrightExtension manages the Playwright lifecycle and is registered globally through JUnit ServiceLoader.
The extension provides:
- one
PlaywrightandBrowserinstance per test class; - a new
BrowserContextandPagefor every test; - automatic injection of
Page,BrowserContext, andBrowserinto test methods; - automatic resource cleanup;
- a full-page screenshot attached to Allure when a test fails.
Every test receives a separate BrowserContext. Cookies, local storage, and session state are therefore isolated between test cases.
The framework is configured through JVM system properties.
| Property | Gradle default | Supported values |
|---|---|---|
browser |
CHROMIUM |
CHROMIUM, FIREFOX, WEBKIT |
headless |
true |
true, false |
baseUrl |
https://www.saucedemo.com |
Any valid application URL |
- JDK 24
- Git
The project includes Gradle Wrapper, so a separate Gradle installation is not required.
./gradlew clean test./gradlew clean test -Dheadless=false./gradlew clean test -Dbrowser=FIREFOX./gradlew clean test -Dbrowser=WEBKIT./gradlew clean test -DbaseUrl=https://example.com./gradlew clean test \
-Dbrowser=FIREFOX \
-Dheadless=false \
-DbaseUrl=https://www.saucedemo.com./gradlew test --tests LoginTest./gradlew test --tests LoginTest.successfulLoginTest results are stored in:
build/allure-results
Run the tests and open the Allure report:
./gradlew clean test allureServeGenerate the report without opening it:
./gradlew allureReportWhen a test fails, the framework automatically attaches a full-page screenshot to the report.
The project currently contains 15 UI tests.
| Test suite | Tests | Covered scenarios |
|---|---|---|
LoginTest |
4 | Successful login, locked user, invalid credentials, empty credentials |
InventoryTest |
6 | Product count, adding and removing products, cart badge, price sorting, name sorting |
CheckoutTest |
5 | Single-product checkout, multi-product checkout, form validation, cart item removal, return to products |
- Chromium
- Firefox
- WebKit
Tests run sequentially by default. Each test method receives an isolated browser context and page.
The project uses Kotlin Logging with Logback. Browser lifecycle events and resource cleanup failures are written to the test logs.
Anuar Abitay Senior QA Automation Engineer
- GitHub: AnuarAbitay
- LinkedIn: anuar-abitay-automationqa