Ready-to-use UI Test Automation Architecture using Java and Playwright.
In order to use the framework:
git clone https://github.com/[your_username]/playwright-java-test-automation-architecture.git
./gradlew test -Dbrowser=firefox -Dheadless=false to run all the tests using the firefox browser in headed mode../gradlew allureServe
The project uses the following: - Java as the programming language. - Playwright as the web browser automation framework using the Java binding. - Univocity Parsers to parse and handle CSV files. - JUnit 5 as the testing framework. - Lombok to generate getters. - Owner to minimize the code to handle properties file. - Allure Report as the test reporting strategy. - Gradle as the Java build tool. - IntelliJ IDEA as the IDE. - Gemini CLI as an AI collaborator for code reviews, locator healing, and test generation.
The project is structured as follows:
📦 playwright-java-test-automation-architecture
├─ .gemini
│ └─ skills
│ ├─ code-reviewer
│ │ ├─ review-rules.md
│ │ └─ SKILL.md
│ └─ healing-agent
│ ├─ locator-healer.md
│ └─ SKILL.md
├─ .github
│ ├─ FUNDING.yml
│ ├─ dependabot.yml
│ └─ workflows
│ └─ test-execution.yml
├─ .gitignore
├─ LICENSE
├─ README.md
├─ GEMINI.md
├─ gemini-config.json
├─ build.gradle
├─ gradle
│ └─ wrapper
│ ├─ gradle-wrapper.jar
│ └─ gradle-wrapper.properties
├─ gradlew
├─ gradlew.bat
├─ settings.gradle
└─ src
├─ main
│ ├─ java
│ │ └─ io
│ │ └─ github
│ │ └─ tahanima
│ │ ├─ config
│ │ │ ├─ Configuration.java
│ │ │ └─ ConfigurationManager.java
│ │ ├─ factory
│ │ │ ├─ BasePageFactory.java
│ │ │ └─ BrowserFactory.java
│ │ ├─ testdata
│ │ │ ├─ BaseTestData.java
│ │ │ ├─ LoginTestData.java
│ │ │ └─ ProductsTestData.java
│ │ ├─ report
│ │ │ └─ AllureManager.java
│ │ ├─ ui
│ │ │ ├─ component
│ │ │ │ ├─ BaseComponent.java
│ │ │ │ ├─ Header.java
│ │ │ │ └─ SideNavMenu.java
│ │ │ └─ page
│ │ │ ├─ BasePage.java
│ │ │ ├─ LoginPage.java
│ │ │ └─ ProductsPage.java
│ │ └─ util
│ │ └─ BrowserManager.java
│ └─ resources
│ ├─ allure.properties
│ └─ config.properties
└─ test
├─ java
│ └─ io
│ └─ github
│ └─ tahanima
│ ├─ annotation
│ │ ├─ Regression.java
│ │ ├─ Smoke.java
│ │ ├─ TestDataSource.java
│ │ └─ Validation.java
│ ├─ e2e
│ │ ├─ BaseTest.java
│ │ ├─ LoginTest.java
│ │ └─ ProductsTest.java
│ └─ util
│ ├─ TestDataArgumentsProvider.java
│ └─ CsvLoader.java
└─ resources
├─ junit-platform.properties
└─ testdata
├─ login.csv
└─ products.csv
The project uses a config.properties file to manage global configurations such as browser type and base url.
To add a new property, register a new entry in this file.
key=value
Then, add a method in the Configuration interface in the below format.
java
@Key("key")
dataType key();
For example, let's say I want to add a new property named context with the value dev. In the config.properties file, I'll add:
context=dev
In the Configuration interface, I'll add:
java
@Key("context")
String context();
To use your newly created property, you need to use the below import statement.
java
import static io.github.tahanima.config.ConfigurationManager.config;
Then, you can call config().key() to retrieve the value of your newly created property. For the example I've provided, I need to call config().context().
You can supply the properties present in the config.properties file as system properties in your test via gradle.
bash
./gradlew test -Dkey1=value1 -Dkey2=value2
The project uses csv file to store test data and univocity-parsers to retrieve the data and map it to a Java bean.
To add configurations for new test data, add a new Java bean in the testdata package. For example, let's say I want to add test data for a User with the attributes First Name and Last Name. The code for this is as follows:
```java package io.github.tahanima.testdata;
import com.univocity.parsers.annotations.Parsed;
import lombok.Getter; import lombok.ToString;
@Getter @ToString(callSuper = true) public class UserTestData extends BaseTestData {
@Parsed(field = "First Name", defaultNullRead = "")
private String firstName;
@Parsed(field = "Last Name", defaultNullRead = "")
private String lastName;
}
``
Note that the class extends from BaseTestData and thus, inherits the attributeTest Case ID`.
Now, in the testdata folder you can add a csv file user.csv for User with the below contents and use it in your tests.
Test Case ID,First Name,Last Name
TC-1,Tahanima,Chowdhury
For reference, check this, this and this.
The project uses Page Objects and Page Component Objects to capture the relevant behaviors of a web page. Check the ui package for reference.
The project uses JUnit 5 as the test runner. Check this implementation for reference.
This project is optimized for use with Gemini CLI, providing a specialized AI agent that understands the architecture.
The project includes a GEMINI.md file which serves as the AI's "Source of Truth." This ensures that any code generated or reviewed by the AI adheres to:
- BasePageFactory initialization patterns.
- Layer Separation (Pages vs. TestData POJOs vs. E2E Tests).
- Playwright Best Practices (Accessibility-first locators over brittle XPaths).
The project contains custom Skills in the .gemini/skills/ directory to automate common QA tasks:
code-reviewer: Automatically audits new Page Objects, POJOs, and Tests to ensure they follow the project's layer separation and naming conventions.healing-agent: Diagnoses test failures (like TimeoutError) and suggests robust, accessibility-first Playwright locators (e.g., getByRole) to replace brittle XPaths.Simply run gemini in the project root. You can trigger skills manually or let the AI suggest them:
```bash
gemini "Review this new test class: @src/test/java/io/github/tahanima/e2e/NewFeatureTest.java"
gemini "The login button locator is failing. Use the healing-agent to suggest a fix for @src/main/java/io/github/tahanima/ui/page/LoginPage.java"
$ claude mcp add playwright-java-test-automation-architecture \
-- python -m otcore.mcp_server <graph>