Ready-to-use UI Test Automation Architecture using Java and Playwright.
- Configuration-based architecture
- Utilizes Page Objects and Page Component Objects
- Data-Driven
- Captures screenshot on test failure
- Records video of test execution
- Provides detailed test report
- Supports parallel test execution
- Supports gemini-cli for AI-assisted coding
In order to use the framework:
- Fork the repository.
- Clone, i.e, download your copy of the repository to your local machine using
git clone https://github.com/[your_username]/playwright-java-test-automation-architecture.git
- Import the project in IntelliJ IDEA.
- Make your desired changes.
- Use IntelliJ IDEA to run your desired tests. Alternatively, you can use the terminal to run the tests, for example
./gradlew test -Dbrowser=firefox -Dheadless=falseto run all the tests using the firefox browser in headed mode. - Build and browse the allure report using
./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=valueThen, add a method in the Configuration interface in the below format.
@Key("key") dataType key();
For example, let's say I want to add a new property named
contextwith the valuedev. In theconfig.propertiesfile, I'll add:context=devIn the
Configurationinterface, I'll add:@Key("context") String context();
To use your newly created property, you need to use the below import statement.
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 callconfig().context(). -
You can supply the properties present in the
config.propertiesfile as system properties in your test via gradle../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
Userwith the attributesFirst NameandLast Name. The code for this is as follows: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 attribute
Test Case ID.Now, in the testdata folder you can add a csv file
user.csvforUserwith the below contents and use it in your tests.Test Case ID,First Name,Last Name TC-1,Tahanima,Chowdhury -
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.
- Gemini CLI: -Installed and authenticated via your Google Account.
- Project Root: Ensure you run the CLI from the project root to allow it to parse the .gemini/ configuration.
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 (likeTimeoutError) 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:
# To perform a code review
gemini "Review this new test class: @src/test/java/io/github/tahanima/e2e/NewFeatureTest.java"
# To fix a failing locator
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"