Skip to content

Commit 6020efa

Browse files
committed
Initial setup of BDD testing framework with Selenium WebDriver and Cucumber
1 parent 78c3cff commit 6020efa

File tree

8 files changed

+378
-142
lines changed

8 files changed

+378
-142
lines changed

pom.xml

Lines changed: 105 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4-
<modelVersion>4.0.0</modelVersion>
5-
<parent>
6-
<groupId>org.springframework.boot</groupId>
7-
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>3.2.0</version>
9-
<relativePath/> <!-- lookup parent from repository -->
10-
</parent>
11-
<groupId>com.productstore</groupId>
12-
<artifactId>product-service</artifactId>
13-
<version>0.0.1-SNAPSHOT</version>
14-
<name>product-service</name>
15-
<description>Product Store Service</description>
16-
<properties>
17-
<java.version>21</java.version>
18-
<jacoco.version>0.8.12</jacoco.version>
19-
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>3.2.0</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
<groupId>com.productstore</groupId>
12+
<artifactId>product-service</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
<name>product-service</name>
15+
<description>Product Store Service</description>
16+
<properties>
17+
<java.version>21</java.version>
18+
<jacoco.version>0.8.12</jacoco.version>
19+
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
2020
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
2121
<sonar.jacoco.reportPath>${project.basedir}/target/jacoco.exec</sonar.jacoco.reportPath>
2222
<sonar.language>java</sonar.language>
23-
<cucumber.version>7.14.0</cucumber.version>
24-
<selenium.version>4.16.1</selenium.version>
25-
<rest-assured.version>5.3.2</rest-assured.version>
26-
</properties>
27-
<dependencies>
28-
<dependency>
29-
<groupId>org.springframework.boot</groupId>
30-
<artifactId>spring-boot-starter-data-jpa</artifactId>
31-
</dependency>
32-
<dependency>
33-
<groupId>org.springframework.boot</groupId>
34-
<artifactId>spring-boot-starter-web</artifactId>
35-
</dependency>
36-
<dependency>
37-
<groupId>org.springframework.boot</groupId>
38-
<artifactId>spring-boot-starter-validation</artifactId>
39-
</dependency>
40-
<dependency>
41-
<groupId>org.postgresql</groupId>
42-
<artifactId>postgresql</artifactId>
43-
<scope>runtime</scope>
44-
</dependency>
45-
<dependency>
46-
<groupId>com.h2database</groupId>
47-
<artifactId>h2</artifactId>
48-
<scope>test</scope>
49-
</dependency>
50-
<dependency>
51-
<groupId>org.projectlombok</groupId>
52-
<artifactId>lombok</artifactId>
53-
<version>1.18.30</version>
54-
<scope>provided</scope>
55-
</dependency>
56-
<dependency>
57-
<groupId>org.springframework.boot</groupId>
58-
<artifactId>spring-boot-starter-test</artifactId>
59-
<scope>test</scope>
60-
</dependency>
61-
<!-- Selenium WebDriver -->
23+
<cucumber.version>7.14.0</cucumber.version>
24+
<selenium.version>4.16.1</selenium.version>
25+
<rest-assured.version>5.3.2</rest-assured.version>
26+
</properties>
27+
<dependencies>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-data-jpa</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-web</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-validation</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.postgresql</groupId>
42+
<artifactId>postgresql</artifactId>
43+
<scope>runtime</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>com.h2database</groupId>
47+
<artifactId>h2</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
<dependency>
51+
<groupId>org.projectlombok</groupId>
52+
<artifactId>lombok</artifactId>
53+
<version>1.18.30</version>
54+
<scope>provided</scope>
55+
</dependency>
56+
<dependency>
57+
<groupId>org.springframework.boot</groupId>
58+
<artifactId>spring-boot-starter-test</artifactId>
59+
<scope>test</scope>
60+
</dependency>
61+
<!-- Selenium WebDriver -->
6262
<dependency>
6363
<groupId>org.seleniumhq.selenium</groupId>
6464
<artifactId>selenium-java</artifactId>
@@ -72,7 +72,7 @@
7272
<version>${rest-assured.version}</version>
7373
</dependency>
7474

75-
<dependency>
75+
<dependency>
7676
<groupId>com.github.javafaker</groupId>
7777
<artifactId>javafaker</artifactId>
7878
<version>1.0.2</version>
@@ -95,29 +95,51 @@
9595
<version>${cucumber.version}</version>
9696
<scope>test</scope>
9797
</dependency>
98-
<dependency>
99-
<groupId>org.mockito</groupId>
100-
<artifactId>mockito-inline</artifactId>
101-
<version>5.2.0</version>
102-
<scope>test</scope>
103-
</dependency>
104-
</dependencies>
98+
<dependency>
99+
<groupId>org.junit.platform</groupId>
100+
<artifactId>junit-platform-suite</artifactId>
101+
<scope>test</scope>
102+
</dependency>
103+
<dependency>
104+
<groupId>org.mockito</groupId>
105+
<artifactId>mockito-inline</artifactId>
106+
<version>5.2.0</version>
107+
<scope>test</scope>
108+
</dependency>
109+
</dependencies>
105110

106-
<build>
107-
<plugins>
108-
<plugin>
109-
<groupId>org.springframework.boot</groupId>
110-
<artifactId>spring-boot-maven-plugin</artifactId>
111-
<configuration>
112-
<excludes>
113-
<exclude>
114-
<groupId>org.projectlombok</groupId>
115-
<artifactId>lombok</artifactId>
116-
</exclude>
117-
</excludes>
118-
</configuration>
119-
</plugin>
120-
<plugin>
111+
<build>
112+
<plugins>
113+
<plugin>
114+
<groupId>org.apache.maven.plugins</groupId>
115+
<artifactId>maven-surefire-plugin</artifactId>
116+
<version>3.1.2</version>
117+
<configuration>
118+
<includes>
119+
<include>**/*Test.java</include>
120+
</includes>
121+
</configuration>
122+
<dependencies>
123+
<dependency>
124+
<groupId>org.junit.vintage</groupId>
125+
<artifactId>junit-vintage-engine</artifactId>
126+
<version>5.9.3</version>
127+
</dependency>
128+
</dependencies>
129+
</plugin>
130+
<plugin>
131+
<groupId>org.springframework.boot</groupId>
132+
<artifactId>spring-boot-maven-plugin</artifactId>
133+
<configuration>
134+
<excludes>
135+
<exclude>
136+
<groupId>org.projectlombok</groupId>
137+
<artifactId>lombok</artifactId>
138+
</exclude>
139+
</excludes>
140+
</configuration>
141+
</plugin>
142+
<plugin>
121143
<groupId>org.apache.maven.plugins</groupId>
122144
<artifactId>maven-checkstyle-plugin</artifactId>
123145
<version>3.3.1</version>
@@ -136,7 +158,7 @@
136158
<linkXRef>false</linkXRef>
137159
</configuration>
138160
</plugin>
139-
<plugin>
161+
<plugin>
140162
<groupId>org.jacoco</groupId>
141163
<artifactId>jacoco-maven-plugin</artifactId>
142164
<version>0.8.12</version>
@@ -192,7 +214,7 @@
192214
</execution>
193215
</executions>
194216
</plugin>
195-
</plugins>
196-
</build>
217+
</plugins>
218+
</build>
197219

198-
</project>
220+
</project>

src/main/resources/application.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Database Configuration
2-
spring.datasource.url=jdbc:postgresql://localhost:5232/postgres
2+
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
33
spring.datasource.username=postgres
4-
spring.datasource.password=18June20!8
4+
spring.datasource.password=postgres
55
spring.datasource.driver-class-name=org.postgresql.Driver
66

77
# JPA/Hibernate properties
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package com.productstore.service;
22

3-
import org.junit.runner.RunWith;
4-
53
import io.cucumber.junit.Cucumber;
64
import io.cucumber.junit.CucumberOptions;
5+
import org.junit.runner.RunWith;
76

87
@RunWith(Cucumber.class)
98
@CucumberOptions(
@@ -14,9 +13,8 @@
1413
"html:target/cucumber-reports/cucumber-pretty.html",
1514
"json:target/cucumber-reports/CucumberTestReport.json"
1615
},
17-
monochrome = true,
18-
dryRun = false
16+
monochrome = true
1917
)
20-
public class CucumberConfig {
21-
// This class serves as an entry point for Cucumber tests
22-
}
18+
public class CucumberConfigRunner {
19+
// This class serves as an entry point for running the Cucumber tests
20+
}
Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,31 @@
11
package com.productstore.service.steps;
22

3-
import static org.junit.jupiter.api.Assertions.assertEquals;
43

5-
import java.math.BigDecimal;
64
import java.util.List;
75
import java.util.Map;
86

9-
import org.springframework.http.HttpStatus;
10-
import org.springframework.http.ResponseEntity;
11-
import org.springframework.web.client.RestTemplate;
127

138
import com.productstore.service.model.Product;
149

15-
import io.cucumber.datatable.DataTable;
10+
import com.fasterxml.jackson.core.type.TypeReference;
11+
import com.fasterxml.jackson.databind.ObjectMapper;
1612
import io.cucumber.java.en.Given;
13+
import io.restassured.http.ContentType;
14+
import io.restassured.response.Response;
15+
import io.cucumber.datatable.DataTable;
16+
17+
import java.util.HashMap;
18+
19+
import static io.restassured.RestAssured.given;
20+
import static org.assertj.core.api.Assertions.assertThat;
1721

1822
public class BackgroundSteps {
19-
private final String baseUrl = "http://localhost:8080";
20-
private final RestTemplate restTemplate = new RestTemplate();
23+
private final TestContext context;
2124

22-
@Given("the following products")
23-
public void theFollowingProducts(DataTable dataTable) {
24-
// Delete all existing products first
25-
restTemplate.delete(baseUrl + "/products");
26-
27-
// Extract rows from data table
28-
List<Map<String, String>> rows = dataTable.asMaps();
29-
30-
// For each row, create a product and send POST request
31-
for (Map<String, String> row : rows) {
32-
// Create product object from row data
33-
Product product = new Product();
34-
product.setName(row.get("name"));
35-
product.setDescription(row.get("description"));
36-
product.setPrice(new BigDecimal(row.get("price")));
37-
product.setAvailable(Boolean.parseBoolean(row.get("available")));
38-
product.setCategory(Product.Category.valueOf(row.get("category")));
39-
40-
// Send POST request
41-
ResponseEntity<Product> response = restTemplate.postForEntity(
42-
baseUrl + "/products",
43-
product,
44-
Product.class);
45-
46-
// Verify response
47-
assertEquals(HttpStatus.CREATED, response.getStatusCode());
48-
}
25+
public BackgroundSteps(TestContext context) {
26+
this.context = context;
4927
}
28+
29+
30+
5031
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.productstore.service.steps;
2+
3+
import io.cucumber.java.After;
4+
import io.cucumber.java.Before;
5+
import org.openqa.selenium.WebDriver;
6+
import org.openqa.selenium.firefox.FirefoxDriver;
7+
import org.openqa.selenium.firefox.FirefoxOptions;
8+
9+
import java.time.Duration;
10+
11+
public class Hooks {
12+
private TestContext context;
13+
14+
public Hooks(TestContext context) {
15+
this.context = context;
16+
}
17+
18+
@Before
19+
public void setup() {
20+
// Set up environment variables
21+
String baseUrl = System.getenv("BASE_URL");
22+
if (baseUrl == null || baseUrl.isEmpty()) {
23+
baseUrl = "http://localhost:8080";
24+
}
25+
context.setBaseUrl(baseUrl);
26+
27+
String waitSecondsStr = System.getenv("WAIT_SECONDS");
28+
int waitSeconds = 60; // Default
29+
if (waitSecondsStr != null && !waitSecondsStr.isEmpty()) {
30+
try {
31+
waitSeconds = Integer.parseInt(waitSecondsStr);
32+
} catch (NumberFormatException e) {
33+
// Use default value
34+
}
35+
}
36+
context.setWaitSeconds(waitSeconds);
37+
38+
// Initialize WebDriver
39+
FirefoxOptions options = new FirefoxOptions();
40+
options.addArguments("--headless"); // Changed from addArgument to addArguments
41+
WebDriver driver = new FirefoxDriver(options);
42+
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(waitSeconds));
43+
context.setDriver(driver);
44+
}
45+
46+
@After
47+
public void tearDown() {
48+
// Clean up resources
49+
if (context.getDriver() != null) {
50+
context.getDriver().quit();
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)