Creating a framework with Selenium WebDriver, RestAssured, Page Factory Pattern, Docker, Kubernetes, and Cucumber combines modern testing strategies with behavioral-driven development (BDD). Here’s a comprehensive guide to setting up this framework.
1. Framework Structure
project-root/
│
├── src/main/java/
│ ├── com.framework.base/
│ │ ├── BaseTest.java
│ │ ├── DriverFactory.java
│ └── com.framework.pages/
│ ├── LoginPage.java
│ ├── HomePage.java
│
├── src/test/java/
│ ├── com.framework.steps/
│ │ ├── UISteps.java
│ │ ├── APISteps.java
│ ├── com.framework.runners/
│ └── TestRunner.java
│ ├── com.framework.tests/
│ ├── UITests.java
│ └── ApiTests.java
│
├── src/test/resources/
│ ├── features/
│ │ ├── login.feature
│ │ └── api.feature
│ └── application.properties
│
├── Dockerfile
├── docker-compose.yaml
├── pom.xml
├── README.md
2. Maven Dependencies
Add the following dependencies to your pom.xml
:
<dependencies>
<!-- Selenium WebDriver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.x.x</version>
</dependency>
<!-- RestAssured -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.x.x</version>
<scope>test</scope>
</dependency>
<!-- Cucumber -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.x.x</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>7.x.x</version>
</dependency>
<!-- TestNG -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.x.x</version>
<scope>test</scope>
</dependency>
</dependencies>
3. Framework Components
DriverFactory.java (WebDriver Setup)
package com.framework.base;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class DriverFactory {
private static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
public static WebDriver getDriver() {
if (driver.get() == null) {
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--no-sandbox", "--disable-dev-shm-usage");
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
driver.set(new ChromeDriver(options));
}
return driver.get();
}
public static void quitDriver() {
if (driver.get() != null) {
driver.get().quit();
driver.remove();
}
}
}
Page Object: LoginPage.java
package com.framework.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage {
WebDriver driver;
@FindBy(id = "username")
WebElement usernameField;
@FindBy(id = "password")
WebElement passwordField;
@FindBy(id = "loginButton")
WebElement loginButton;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void login(String username, String password) {
usernameField.sendKeys(username);
passwordField.sendKeys(password);
loginButton.click();
}
}
Step Definitions
UISteps.java
package com.framework.steps;
import com.framework.base.DriverFactory;
import com.framework.pages.LoginPage;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import static org.testng.Assert.assertTrue;
public class UISteps {
LoginPage loginPage;
@Given("the user is on the login page")
public void navigateToLoginPage() {
DriverFactory.getDriver().get("http://localhost:8080");
loginPage = new LoginPage(DriverFactory.getDriver());
}
@When("the user enters username {string} and password {string}")
public void enterCredentials(String username, String password) {
loginPage.login(username, password);
}
@Then("the user should see the home page")
public void verifyHomePage() {
assertTrue(DriverFactory.getDriver().getTitle().contains("Home"));
}
}
APISteps.java
package com.framework.steps;
import io.restassured.RestAssured;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
public class APISteps {
@Given("the API base URI is set")
public void setBaseURI() {
RestAssured.baseURI = "http://localhost:8080/api";
}
@When("I send a GET request to {string}")
public void sendGETRequest(String endpoint) {
RestAssured.requestSpecification = given().basePath(endpoint);
}
@Then("the response should have status code {int}")
public void validateStatusCode(int statusCode) {
RestAssured.requestSpecification.get().then().statusCode(statusCode);
}
}
Feature Files
login.feature
Feature: User Login
Scenario: Successful Login
Given the user is on the login page
When the user enters username "admin" and password "password"
Then the user should see the home page
API.feature
Feature: API Testing
Scenario: Validate GET Request
Given the API base URI is set
When I send a GET request to "/resource"
Then the response should have status code 200
Cucumber Test Runner
TestRunner.java
package com.framework.runners;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
@CucumberOptions(
features = "src/test/resources/features",
glue = "com.framework.steps",
plugin = {"pretty", "html:target/cucumber-report.html"}
)
public class TestRunner extends AbstractTestNGCucumberTests {
}
4. Docker and Kubernetes Integration
Dockerfile
FROM maven:3.8.4-openjdk-17 AS builder
WORKDIR /app
COPY . .
RUN mvn clean install -DskipTests
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
docker-compose.yaml
version: "3.9"
services:
app:
build: .
ports:
- "8080:8080"
selenium-hub:
image: selenium/hub:4.1.0
ports:
- "4444:4444"
chrome:
image: selenium/node-chrome:4.1.0
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
depends_on:
- selenium-hub
Kubernetes Manifest
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing-framework
spec:
replicas: 1
selector:
matchLabels:
app: testing-framework
template:
metadata:
labels:
app: testing-framework
spec:
containers:
- name: app
image: your-dockerhub-user/testing-framework:latest
ports:
- containerPort: 8080
5. Run Tests
- Use
mvn test
to run locally. - Deploy on Kubernetes and execute tests with CI/CD.
This framework is flexible, modular, and ideal for teams leveraging UI and API testing.