Skip to content

Commit

Permalink
refactor and improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Tahanima committed Dec 2, 2023
1 parent 1c9e67c commit c2a17b7
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 68 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ The project is structured as follows:
- ### Test Data
The project uses *csv* or *json* file to store test data and [*univocity-parsers*](https://github.com/uniVocity/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 [*data*](./src/main/java/io/github/tahanima/data) 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:
To add configurations for new test data, add a new Java bean in the [*data*](./src/main/java/io/github/tahanima/dto) 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.data;
package io.github.tahanima.dto;
import com.univocity.parsers.annotations.Parsed;
Expand Down Expand Up @@ -186,7 +186,7 @@ The project is structured as follows:
}
]
```
For reference, check [this](./src/main/java/io/github/tahanima/data/LoginData.java), [this](./src/test/resources/testdata/login.csv) and [this](./src/test/java/io/github/tahanima/e2e/LoginE2ETest.java).
For reference, check [this](./src/main/java/io/github/tahanima/dto/LoginData.java), [this](./src/test/resources/testdata/login.csv) and [this](./src/test/java/io/github/tahanima/e2e/LoginE2ETest.java).

- ### Browser
The project contains the implementation of the *Chrome* and *Firefox* browsers. If you want to include an implementation of a new browser type, add the relevant codes in the [*BrowserFactory*](./src/main/java/io/github/tahanima/factory/BrowserFactory.java) enum.
Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repositories {
}

dependencies {
implementation 'org.seleniumhq.selenium:selenium-java:4.14.1'
implementation 'org.seleniumhq.selenium:selenium-java:4.15.0'
implementation 'org.aeonbits.owner:owner:1.0.12'
implementation 'com.univocity:univocity-parsers:2.9.1'
implementation 'com.aventstack:extentreports:5.1.1'
Expand All @@ -26,6 +26,8 @@ dependencies {

compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
testCompileOnly 'org.projectlombok:lombok:1.18.30'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.30'

testImplementation 'org.testng:testng:7.8.0'
testImplementation 'org.assertj:assertj-core:3.24.2'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.tahanima.data;
package io.github.tahanima.dto;

import com.univocity.parsers.annotations.Parsed;

Expand All @@ -10,7 +10,7 @@
*/
@Getter
@ToString
public class BaseData {
public class BaseDto {

@Parsed(field = "Test Case ID", defaultNullRead = "")
private String testCaseId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.tahanima.data;
package io.github.tahanima.dto;

import com.univocity.parsers.annotations.Parsed;

Expand All @@ -10,7 +10,7 @@
*/
@Getter
@ToString(callSuper = true)
public class LoginData extends BaseData {
public class LoginDto extends BaseDto {

@Parsed(field = "Username", defaultNullRead = "")
private String username;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.tahanima.data;
package io.github.tahanima.dto;

import com.univocity.parsers.annotations.Parsed;

Expand All @@ -10,7 +10,7 @@
*/
@Getter
@ToString(callSuper = true)
public final class ProductsData extends BaseData {
public final class ProductsDto extends BaseDto {

@Parsed(field = "User Name", defaultNullRead = "")
private String username;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import io.github.tahanima.ui.page.BasePage;

import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.WebDriver;

/**
* @author tahanima
*/
@Slf4j
public final class BasePageFactory {

private BasePageFactory() {}
Expand All @@ -21,7 +23,7 @@ public static <T extends BasePage> T createInstance(

return clazz.cast(instance);
} catch (Exception e) {
e.printStackTrace();
log.error("BasePageFactory::createInstance", e);
}

throw new NullPointerException("Page class instantiation failed.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
* @author tahanima
Expand Down Expand Up @@ -36,7 +37,7 @@ public static ExtentReports createReport() {
extentReport.setSystemInfo(
"Test Group",
StringUtils.capitalize(
StringUtils.defaultString(System.getProperty("groups"), "regression")));
Objects.toString(System.getProperty("groups"), "regression")));

return extentReport;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public abstract class BaseComponent {

protected WebDriver driver;

public BaseComponent(WebDriver driver) {
protected BaseComponent(WebDriver driver) {
this.driver = driver;
}
}
2 changes: 1 addition & 1 deletion src/main/java/io/github/tahanima/ui/page/LoginPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public LoginPage open() {
return this;
}

private void clearAndType(WebElement elem, String text) {
private void clearAndType(final WebElement elem, final String text) {
elem.clear();
elem.sendKeys(text);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* @author tahanima
*/
@Listeners(TestListener.class)
public abstract class BaseE2ETest {
public abstract class BaseTest {

private final WebDriver driver =
BrowserFactory.valueOf(config().browser().toUpperCase()).getDriver();
Expand All @@ -30,10 +30,6 @@ protected String getScreenshotFilePath(String path) {
return config().baseScreenshotPath() + path;
}

public WebDriver getDriver() {
return driver;
}

@BeforeClass(alwaysRun = true)
public void setup() {
loginPage = BasePageFactory.createInstance(driver, LoginPage.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import io.github.tahanima.data.LoginData;
import io.github.tahanima.dto.LoginDto;
import io.github.tahanima.ui.page.ProductsPage;
import io.github.tahanima.util.TestRetry;

Expand All @@ -19,15 +19,15 @@
/**
* @author tahanima
*/
public final class LoginE2ETest extends BaseE2ETest {
public final class LoginTest extends BaseTest {

private static final String FILE_PATH = "login.csv";

@DataProvider(name = "loginData")
public Object[][] getLoginData(final Method testMethod) {
String testCaseId = testMethod.getAnnotation(Test.class).testName();

return processTestData(LoginData.class, getTestDataFilePath(FILE_PATH), testCaseId);
return processTestData(LoginDto.class, getTestDataFilePath(FILE_PATH), testCaseId);
}

@AfterMethod(alwaysRun = true)
Expand All @@ -49,7 +49,7 @@ public void captureScreenshotOnFailure(ITestResult result) {
dataProvider = "loginData",
groups = {"smoke", "regression"},
retryAnalyzer = TestRetry.class)
public void testCorrectUserNameAndCorrectPassword(final LoginData data) {
public void testCorrectUserNameAndCorrectPassword(final LoginDto data) {
ProductsPage productsPage = loginPage.loginAs(data.getUsername(), data.getPassword());

assertThat(productsPage.getTitle()).isEqualTo("Products");
Expand All @@ -60,7 +60,7 @@ public void testCorrectUserNameAndCorrectPassword(final LoginData data) {
dataProvider = "loginData",
groups = {"validation", "regression"},
retryAnalyzer = TestRetry.class)
public void testImproperCredentialsShouldGiveErrorMessage(final LoginData data) {
public void testImproperCredentialsShouldGiveErrorMessage(final LoginDto data) {
loginPage.loginAs(data.getUsername(), data.getPassword());

assertThat(loginPage.getErrorMessage()).isEqualTo(data.getErrorMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import io.github.tahanima.data.ProductsData;
import io.github.tahanima.dto.ProductsDto;
import io.github.tahanima.util.TestRetry;

import org.testng.ITestNGMethod;
Expand All @@ -18,15 +18,15 @@
/**
* @author tahanima
*/
public final class ProductsE2ETest extends BaseE2ETest {
public final class ProductsTest extends BaseTest {

private static final String FILE_PATH = "products.csv";
private static final String FILE_PATH = "products.json";

@DataProvider(name = "productsData")
public Object[][] getProductsData(final Method testMethod) {
String testCaseId = testMethod.getAnnotation(Test.class).testName();

return processTestData(ProductsData.class, getTestDataFilePath(FILE_PATH), testCaseId);
return processTestData(ProductsDto.class, getTestDataFilePath(FILE_PATH), testCaseId);
}

@AfterMethod(alwaysRun = true)
Expand All @@ -48,7 +48,7 @@ public void captureScreenshotOnFailure(ITestResult result) {
dataProvider = "productsData",
groups = {"smoke", "regression"},
retryAnalyzer = TestRetry.class)
public void testSuccessfulLogout(final ProductsData data) {
public void testSuccessfulLogout(final ProductsDto data) {
loginPage.loginAs(data.getUsername(), data.getPassword()).clickOnLogout();

assertThat(loginPage.getUrl()).isEqualTo(data.getUrl());
Expand Down
79 changes: 45 additions & 34 deletions src/test/java/io/github/tahanima/util/DataProviderUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,46 @@
import com.google.gson.reflect.TypeToken;
import com.univocity.parsers.csv.CsvParserSettings;
import com.univocity.parsers.csv.CsvRoutines;
import io.github.tahanima.data.BaseData;

import io.github.tahanima.dto.BaseDto;

import lombok.extern.slf4j.Slf4j;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
* @author tahanima
*/
@Slf4j
public final class DataProviderUtil {

private DataProviderUtil() {}

public static Object[][] processTestData(Class<? extends BaseData> clazz, String fileName, String id) {
if (fileName.endsWith(".csv")) {
return processCsv(clazz, fileName, id);
} else if (fileName.endsWith(".json")) {
return processJson(clazz, fileName, id);
}
public static Object[][] processTestData(
Class<? extends BaseDto> clazz, String fileName, String id) {
if (fileName.endsWith(".csv")) return processCsv(clazz, fileName, id);

if (fileName.endsWith(".json")) return processJson(clazz, fileName, id);

return new Object[0][0];
}

private static Object[][] processCsv(Class<? extends BaseData> clazz, String fileName, String id) {
CsvParserSettings settings = new CsvParserSettings();
private static Object[][] processCsv(
Class<? extends BaseDto> clazz, String fileName, String id) {
var settings = new CsvParserSettings();

settings.getFormat().setLineSeparator("\n");

CsvRoutines routines = new CsvRoutines(settings);
var routines = new CsvRoutines(settings);

try (Reader reader =
try (var reader =
new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8)) {
ArrayList<ArrayList<? extends BaseData>> testData = new ArrayList<>();
ArrayList<ArrayList<? extends BaseDto>> testData = new ArrayList<>();

routines.iterate(clazz, reader)
.forEach(
Expand All @@ -57,42 +60,50 @@ private static Object[][] processCsv(Class<? extends BaseData> clazz, String fil

return toArray(testData);
} catch (IOException e) {
e.printStackTrace();
log.error("DataProviderUtil::processCsv", e);
}

return new Object[0][0];
}

private static <T extends BaseData> Object[][] processJson(Class<T> clazz, String fileName, String id) {
try (Reader reader = new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8)) {
ArrayList<ArrayList<? extends BaseData>> testData = new ArrayList<>();
List<T> jsonData = new Gson().fromJson(reader, TypeToken.getParameterized(List.class, clazz).getType());
jsonData
.forEach(
e -> {
if (e.getTestCaseId().equals(id)) {
testData.add(new ArrayList<>() {{
add(e);
}});
}
});
private static <T extends BaseDto> Object[][] processJson(
Class<T> clazz, String fileName, String id) {
try (var reader =
new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8)) {
ArrayList<ArrayList<? extends BaseDto>> testData = new ArrayList<>();
List<T> jsonData =
new Gson()
.fromJson(
reader,
TypeToken.getParameterized(List.class, clazz).getType());

jsonData.forEach(
e -> {
if (e.getTestCaseId().equals(id)) {
testData.add(
new ArrayList<>() {
{
add(e);
}
});
}
});

return toArray(testData);
} catch (IOException e) {
e.printStackTrace();
log.error("DataProviderUtil::processJson", e);
}
return new Object[0][0];
}

private static Object[][] toArray(ArrayList<ArrayList<? extends BaseData>> data) {
int noOfRows = data.size();
Object[][] dataArray = new Object[noOfRows][1];
private static Object[][] toArray(ArrayList<ArrayList<? extends BaseDto>> testData) {
int noOfRows = testData.size();
Object[][] testDataArray = new Object[noOfRows][1];

for (int i = 0; i < noOfRows; i++) {
dataArray[i][0] = data.get(i).get(0);
testDataArray[i][0] = testData.get(i).get(0);
}

return dataArray;
return testDataArray;
}

}
Loading

0 comments on commit c2a17b7

Please sign in to comment.