diff --git a/README.md b/README.md index 4870d0e..1532bc3 100644 --- a/README.md +++ b/README.md @@ -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; @@ -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. diff --git a/build.gradle b/build.gradle index 6dda1b8..082b582 100644 --- a/build.gradle +++ b/build.gradle @@ -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' @@ -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' diff --git a/src/main/java/io/github/tahanima/data/BaseData.java b/src/main/java/io/github/tahanima/dto/BaseDto.java similarity index 85% rename from src/main/java/io/github/tahanima/data/BaseData.java rename to src/main/java/io/github/tahanima/dto/BaseDto.java index 17d790b..6a151ce 100644 --- a/src/main/java/io/github/tahanima/data/BaseData.java +++ b/src/main/java/io/github/tahanima/dto/BaseDto.java @@ -1,4 +1,4 @@ -package io.github.tahanima.data; +package io.github.tahanima.dto; import com.univocity.parsers.annotations.Parsed; @@ -10,7 +10,7 @@ */ @Getter @ToString -public class BaseData { +public class BaseDto { @Parsed(field = "Test Case ID", defaultNullRead = "") private String testCaseId; diff --git a/src/main/java/io/github/tahanima/data/LoginData.java b/src/main/java/io/github/tahanima/dto/LoginDto.java similarity index 85% rename from src/main/java/io/github/tahanima/data/LoginData.java rename to src/main/java/io/github/tahanima/dto/LoginDto.java index 1a0f7e6..d1a587e 100644 --- a/src/main/java/io/github/tahanima/data/LoginData.java +++ b/src/main/java/io/github/tahanima/dto/LoginDto.java @@ -1,4 +1,4 @@ -package io.github.tahanima.data; +package io.github.tahanima.dto; import com.univocity.parsers.annotations.Parsed; @@ -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; diff --git a/src/main/java/io/github/tahanima/data/ProductsData.java b/src/main/java/io/github/tahanima/dto/ProductsDto.java similarity index 82% rename from src/main/java/io/github/tahanima/data/ProductsData.java rename to src/main/java/io/github/tahanima/dto/ProductsDto.java index d717542..5f69576 100644 --- a/src/main/java/io/github/tahanima/data/ProductsData.java +++ b/src/main/java/io/github/tahanima/dto/ProductsDto.java @@ -1,4 +1,4 @@ -package io.github.tahanima.data; +package io.github.tahanima.dto; import com.univocity.parsers.annotations.Parsed; @@ -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; diff --git a/src/main/java/io/github/tahanima/factory/BasePageFactory.java b/src/main/java/io/github/tahanima/factory/BasePageFactory.java index 330c7fa..f7f5c90 100644 --- a/src/main/java/io/github/tahanima/factory/BasePageFactory.java +++ b/src/main/java/io/github/tahanima/factory/BasePageFactory.java @@ -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() {} @@ -21,7 +23,7 @@ public static T createInstance( return clazz.cast(instance); } catch (Exception e) { - e.printStackTrace(); + log.error("BasePageFactory::createInstance", e); } throw new NullPointerException("Page class instantiation failed."); diff --git a/src/main/java/io/github/tahanima/report/ExtentReportManager.java b/src/main/java/io/github/tahanima/report/ExtentReportManager.java index 72bf329..b94fb1c 100644 --- a/src/main/java/io/github/tahanima/report/ExtentReportManager.java +++ b/src/main/java/io/github/tahanima/report/ExtentReportManager.java @@ -9,6 +9,7 @@ import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Objects; /** * @author tahanima @@ -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; } diff --git a/src/main/java/io/github/tahanima/ui/component/BaseComponent.java b/src/main/java/io/github/tahanima/ui/component/BaseComponent.java index 973e3fb..d3dc7c2 100644 --- a/src/main/java/io/github/tahanima/ui/component/BaseComponent.java +++ b/src/main/java/io/github/tahanima/ui/component/BaseComponent.java @@ -9,7 +9,7 @@ public abstract class BaseComponent { protected WebDriver driver; - public BaseComponent(WebDriver driver) { + protected BaseComponent(WebDriver driver) { this.driver = driver; } } diff --git a/src/main/java/io/github/tahanima/ui/page/LoginPage.java b/src/main/java/io/github/tahanima/ui/page/LoginPage.java index d7e7ed8..8299b9a 100644 --- a/src/main/java/io/github/tahanima/ui/page/LoginPage.java +++ b/src/main/java/io/github/tahanima/ui/page/LoginPage.java @@ -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); } diff --git a/src/test/java/io/github/tahanima/e2e/BaseE2ETest.java b/src/test/java/io/github/tahanima/e2e/BaseTest.java similarity index 91% rename from src/test/java/io/github/tahanima/e2e/BaseE2ETest.java rename to src/test/java/io/github/tahanima/e2e/BaseTest.java index 7337fda..9857481 100644 --- a/src/test/java/io/github/tahanima/e2e/BaseE2ETest.java +++ b/src/test/java/io/github/tahanima/e2e/BaseTest.java @@ -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(); @@ -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); diff --git a/src/test/java/io/github/tahanima/e2e/LoginE2ETest.java b/src/test/java/io/github/tahanima/e2e/LoginTest.java similarity index 90% rename from src/test/java/io/github/tahanima/e2e/LoginE2ETest.java rename to src/test/java/io/github/tahanima/e2e/LoginTest.java index 30b441c..9e8f388 100644 --- a/src/test/java/io/github/tahanima/e2e/LoginE2ETest.java +++ b/src/test/java/io/github/tahanima/e2e/LoginTest.java @@ -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; @@ -19,7 +19,7 @@ /** * @author tahanima */ -public final class LoginE2ETest extends BaseE2ETest { +public final class LoginTest extends BaseTest { private static final String FILE_PATH = "login.csv"; @@ -27,7 +27,7 @@ public final class LoginE2ETest extends BaseE2ETest { 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) @@ -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"); @@ -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()); diff --git a/src/test/java/io/github/tahanima/e2e/ProductsE2ETest.java b/src/test/java/io/github/tahanima/e2e/ProductsTest.java similarity index 82% rename from src/test/java/io/github/tahanima/e2e/ProductsE2ETest.java rename to src/test/java/io/github/tahanima/e2e/ProductsTest.java index 171a8cc..c9d3b02 100644 --- a/src/test/java/io/github/tahanima/e2e/ProductsE2ETest.java +++ b/src/test/java/io/github/tahanima/e2e/ProductsTest.java @@ -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; @@ -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) @@ -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()); diff --git a/src/test/java/io/github/tahanima/util/DataProviderUtil.java b/src/test/java/io/github/tahanima/util/DataProviderUtil.java index ab890af..e9dacfc 100644 --- a/src/test/java/io/github/tahanima/util/DataProviderUtil.java +++ b/src/test/java/io/github/tahanima/util/DataProviderUtil.java @@ -4,12 +4,14 @@ 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; @@ -17,30 +19,31 @@ /** * @author tahanima */ +@Slf4j public final class DataProviderUtil { private DataProviderUtil() {} - public static Object[][] processTestData(Class 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 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 clazz, String fileName, String id) { - CsvParserSettings settings = new CsvParserSettings(); + private static Object[][] processCsv( + Class 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> testData = new ArrayList<>(); + ArrayList> testData = new ArrayList<>(); routines.iterate(clazz, reader) .forEach( @@ -57,42 +60,50 @@ private static Object[][] processCsv(Class clazz, String fil return toArray(testData); } catch (IOException e) { - e.printStackTrace(); + log.error("DataProviderUtil::processCsv", e); } return new Object[0][0]; } - private static Object[][] processJson(Class clazz, String fileName, String id) { - try (Reader reader = new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8)) { - ArrayList> testData = new ArrayList<>(); - List 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 Object[][] processJson( + Class clazz, String fileName, String id) { + try (var reader = + new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8)) { + ArrayList> testData = new ArrayList<>(); + List 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> data) { - int noOfRows = data.size(); - Object[][] dataArray = new Object[noOfRows][1]; + private static Object[][] toArray(ArrayList> 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; } - } diff --git a/src/test/java/io/github/tahanima/util/TestListener.java b/src/test/java/io/github/tahanima/util/TestListener.java index 3a69093..cb15985 100644 --- a/src/test/java/io/github/tahanima/util/TestListener.java +++ b/src/test/java/io/github/tahanima/util/TestListener.java @@ -5,7 +5,7 @@ import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.MediaEntityBuilder; -import io.github.tahanima.data.BaseData; +import io.github.tahanima.dto.BaseDto; import io.github.tahanima.report.ExtentReportManager; import org.apache.commons.text.StringEscapeUtils; @@ -29,7 +29,7 @@ public void onTestSuccess(ITestResult result) { String testData = "No data parameters are found."; if (result.getParameters().length > 0) { - BaseData data = (BaseData) result.getParameters()[0]; + BaseDto data = (BaseDto) result.getParameters()[0]; testCaseId = data.getTestCaseId(); testCaseDescription = data.getTestCaseDescription(); testData = StringEscapeUtils.escapeHtml4(data.toString()); @@ -54,7 +54,7 @@ public void onTestFailure(ITestResult result) { String testData = "No data parameters are found."; if (result.getParameters().length > 0) { - BaseData data = (BaseData) result.getParameters()[0]; + BaseDto data = (BaseDto) result.getParameters()[0]; testCaseId = data.getTestCaseId(); testCaseDescription = data.getTestCaseDescription(); testData = StringEscapeUtils.escapeHtml4(data.toString()); @@ -89,7 +89,7 @@ public void onTestSkipped(ITestResult result) { String testData = "No data parameters are found."; if (result.getParameters().length > 0) { - BaseData data = (BaseData) result.getParameters()[0]; + BaseDto data = (BaseDto) result.getParameters()[0]; testCaseId = data.getTestCaseId(); testCaseDescription = data.getTestCaseDescription(); testData = StringEscapeUtils.escapeHtml4(data.toString());