diff --git a/.classpath b/.classpath
new file mode 100644
index 00000000..db3ceb26
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index 0275ff56..98a6bc15 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
build
.idea
-.gradle
\ No newline at end of file
+.gradle
+/target/
diff --git a/.project b/.project
new file mode 100644
index 00000000..193ba108
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ codingRound
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..44322481
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 00000000..14b697b7
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/REVIEW_COMMENTS_&_KEY_POINTS.txt b/REVIEW_COMMENTS_&_KEY_POINTS.txt
new file mode 100644
index 00000000..59c51460
--- /dev/null
+++ b/REVIEW_COMMENTS_&_KEY_POINTS.txt
@@ -0,0 +1,109 @@
+Review Points And Comments:
+
+Review Comments and Key points on the fixes and framework created are Oredered as follows:
+
+
+(1) Common and Test Class Level Review on design and errors.
+(2) Framework design pattern, files placing, reusability, reporting.
+
+
+ 1. Test Class Level Review on design and errors.
+
+(i) Common Issues:
+
+ (a). set the path for driver before initialize the same.
+
+ (b). create a common utility to launch driver and set chrome driver path.
+
+ (c). create property file to input test configuration values i.e browser name, driver path other common configuration needs before test.
+
+ (d). it is better to have test case executed via testNG xml while using testNG, hence it should be configured right.
+
+ (e). Should try to keep the implementation for tests abstract/ hidden and reusable and add provision for further updates of the same
+ which would assure maintainability.
+
+ (f). Assert every validation and report with screenshot for failed step/every step if possible. Since, html results
+ can be easily edited and hence for show casing tests to client is one step ahead if the tests have proper
+ evidences.
+
+ (g). Must avoid using thread.sleep (hard wait of any type). Instead use explicit waits.
+
+ (h). should follow a proper design pattern across the tests for efficient testing i.e page factory for example.
+
+ (i). Always the tests must NOT be placed/developed in the main src folder, it should be placed in the test src folder
+ the main should only have common utils.
+
+ (j) The classes should not be developed in "default package" it should be developed in a properly created
+ package with correct naming conventions.
+
+ (k) The drivers can be placed in a separate relevant folder which can make the framework presentable.
+
+ (l) Important of all a framework or automation is about reusabilty which requires reusable library for all
+ the tests.
+
+
+(ii)FlightBookingTest:
+
+ (a).Use explicit waits.
+
+ (b).Update the chrome driver to latest for supporting latest chrome versions. It can cause errors during execution.
+ such that the chrome driver which was already there caused exception when sending text to 'from' text box
+ which got fixed after updating the chrome driver.
+
+ (c).Xpath Id for the To(destination) text box was not correct i.e the actual value for the attribute id is 'ToTag'
+ but in script the vale was'toTag' hence it throws 'NoSuchElementException.
+
+ (d).The date picker xpath is hard coded to pick a date and not flexible which is not good for a locator. Should change the
+ xpath in such a way that it can take any date from the user. write a common method.
+
+ (e).Assesrtion should be done specifically whether Bangalore to New Delhi flights are shown and not just 'searchSummary' text
+ so that what gets Asserted will completley validate the scenario.
+
+
+(ii)HotelBookingtest:
+
+ (a). This class has pagefactory pattern implemented for finding elements which was missing "PageFactory.initElements()" this method
+ will implicitly call the findElement method from behind without which the script fails.
+
+ (b). Date picker must be automated for any inputs from the user and should be reusable.
+
+
+(iii)SignInTest:
+
+ (a). Identify whether an element is within a frame i.e "SignIn" button is an element located within a frame
+ because of which the element cannot be identified unless switched to that frame.
+
+
+
+Key Points of the framework developed and fixed
+
+ 2 Framework design pattern, files placing, reusability, reporting.
+
+ (a). An automation framework must follow a design pattern with correct usage of OOP's concepts
+ for better understanding, readability and reusability.
+
+ The fixes made to the task does not only resolve the issues but also follows a strong "Page Abstraction/Page Factory Pattern"
+ with "LoadableComponent" implemented for every page i.e "FlightBookingPage.class", "HotelBookingPage.class",
+ "SearchSummaryPage.class", "SignInPage.class".
+
+
+ (b). Common Reusable Library "UiCommons" is used which was not present.
+
+ (c). "DriverFactory"class is implemented for initializing driver and closing the same which can be used across
+ tests.
+
+ (d). Input/output utilities created to read test configuration properties from ".properties" file.
+
+ (e). Listener class implemented for running failed tests again, the number of times as user specified.
+
+ (f). Listener class implemented for intuitive reporting with html that has screenshots attached within the html report page.
+
+ (g). TestNG xml included for running as TestNG suite.
+
+ (h). Proper assertion done for validation.
+
+
+**Run the tests using TestNg.xml present as suite to generate reports and retry failed.
+**The results will be generated in "ExtentReports" folder within the project, to view the same please,refresh the project
+
+
diff --git a/chromedriver_linux b/drivers/chromedriver_linux
old mode 100755
new mode 100644
similarity index 100%
rename from chromedriver_linux
rename to drivers/chromedriver_linux
diff --git a/chromedriver b/drivers/chromedriver_mac
old mode 100755
new mode 100644
similarity index 100%
rename from chromedriver
rename to drivers/chromedriver_mac
diff --git a/chromedriver.exe b/drivers/chromedriver_win.exe
old mode 100755
new mode 100644
similarity index 52%
rename from chromedriver.exe
rename to drivers/chromedriver_win.exe
index 4bfff1ef..d7ac3c69
Binary files a/chromedriver.exe and b/drivers/chromedriver_win.exe differ
diff --git a/pom.xml b/pom.xml
index 839ed21f..cf0bcc28 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,28 +1,40 @@
-
- 4.0.0
- com.testvagrant.codingRound
- codoingRound
- 1.0-SNAPSHOT
-
-
- junit
- junit
- 4.11
- compile
-
-
- org.seleniumhq.selenium
- selenium-java
- 3.6.0
- compile
-
-
- org.testng
- testng
- 6.11
- compile
-
-
+
+ 4.0.0
+ com.testvagrant.codingRound
+ codoingRound
+ 1.0-SNAPSHOT
+
+
+ junit
+ junit
+ 4.11
+ compile
+
+
+ org.seleniumhq.selenium
+ selenium-java
+ 3.6.0
+ compile
+
+
+ org.testng
+ testng
+ 6.11
+ compile
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+ com.relevantcodes
+ extentreports
+ 2.41.2
+
+
diff --git a/src/main/java/FlightBookingTest.java b/src/main/java/FlightBookingTest.java
deleted file mode 100644
index 19d98ddf..00000000
--- a/src/main/java/FlightBookingTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-import com.sun.javafx.PlatformUtil;
-import org.openqa.selenium.By;
-import org.openqa.selenium.NoSuchElementException;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.support.ui.Select;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import java.util.List;
-
-public class FlightBookingTest {
-
- WebDriver driver = new ChromeDriver();
-
-
- @Test
- public void testThatResultsAppearForAOneWayJourney() {
-
- setDriverPath();
- driver.get("https://www.cleartrip.com/");
- waitFor(2000);
- driver.findElement(By.id("OneWay")).click();
-
- driver.findElement(By.id("FromTag")).clear();
- driver.findElement(By.id("FromTag")).sendKeys("Bangalore");
-
- //wait for the auto complete options to appear for the origin
-
- waitFor(2000);
- List originOptions = driver.findElement(By.id("ui-id-1")).findElements(By.tagName("li"));
- originOptions.get(0).click();
-
- driver.findElement(By.id("toTag")).clear();
- driver.findElement(By.id("toTag")).sendKeys("Delhi");
-
- //wait for the auto complete options to appear for the destination
-
- waitFor(2000);
- //select the first item from the destination auto complete list
- List destinationOptions = driver.findElement(By.id("ui-id-2")).findElements(By.tagName("li"));
- destinationOptions.get(0).click();
-
- driver.findElement(By.xpath("//*[@id='ui-datepicker-div']/div[1]/table/tbody/tr[3]/td[7]/a")).click();
-
- //all fields filled in. Now click on search
- driver.findElement(By.id("SearchBtn")).click();
-
- waitFor(5000);
- //verify that result appears for the provided journey search
- Assert.assertTrue(isElementPresent(By.className("searchSummary")));
-
- //close the browser
- driver.quit();
-
- }
-
-
- private void waitFor(int durationInMilliSeconds) {
- try {
- Thread.sleep(durationInMilliSeconds);
- } catch (InterruptedException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
-
-
- private boolean isElementPresent(By by) {
- try {
- driver.findElement(by);
- return true;
- } catch (NoSuchElementException e) {
- return false;
- }
- }
-
- private void setDriverPath() {
- if (PlatformUtil.isMac()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver");
- }
- if (PlatformUtil.isWindows()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
- }
- if (PlatformUtil.isLinux()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver_linux");
- }
- }
-}
diff --git a/src/main/java/HotelBookingTest.java b/src/main/java/HotelBookingTest.java
deleted file mode 100644
index 2be026bb..00000000
--- a/src/main/java/HotelBookingTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-import com.sun.javafx.PlatformUtil;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.support.FindBy;
-import org.openqa.selenium.support.ui.Select;
-import org.testng.annotations.Test;
-
-public class HotelBookingTest {
-
- WebDriver driver = new ChromeDriver();
-
- @FindBy(linkText = "Hotels")
- private WebElement hotelLink;
-
- @FindBy(id = "Tags")
- private WebElement localityTextBox;
-
- @FindBy(id = "SearchHotelsButton")
- private WebElement searchButton;
-
- @FindBy(id = "travellersOnhome")
- private WebElement travellerSelection;
-
- @Test
- public void shouldBeAbleToSearchForHotels() {
- setDriverPath();
-
- driver.get("https://www.cleartrip.com/");
- hotelLink.click();
-
- localityTextBox.sendKeys("Indiranagar, Bangalore");
-
- new Select(travellerSelection).selectByVisibleText("1 room, 2 adults");
- searchButton.click();
-
- driver.quit();
-
- }
-
- private void setDriverPath() {
- if (PlatformUtil.isMac()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver");
- }
- if (PlatformUtil.isWindows()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
- }
- if (PlatformUtil.isLinux()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver_linux");
- }
- }
-
-}
diff --git a/src/main/java/SignInTest.java b/src/main/java/SignInTest.java
deleted file mode 100644
index 2c109950..00000000
--- a/src/main/java/SignInTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-import com.sun.javafx.PlatformUtil;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-public class SignInTest {
-
- WebDriver driver = new ChromeDriver();
-
- @Test
- public void shouldThrowAnErrorIfSignInDetailsAreMissing() {
-
- setDriverPath();
-
- driver.get("https://www.cleartrip.com/");
- waitFor(2000);
-
- driver.findElement(By.linkText("Your trips")).click();
- driver.findElement(By.id("SignIn")).click();
-
- driver.findElement(By.id("signInButton")).click();
-
- String errors1 = driver.findElement(By.id("errors1")).getText();
- Assert.assertTrue(errors1.contains("There were errors in your submission"));
- driver.quit();
- }
-
- private void waitFor(int durationInMilliSeconds) {
- try {
- Thread.sleep(durationInMilliSeconds);
- } catch (InterruptedException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
-
- private void setDriverPath() {
- if (PlatformUtil.isMac()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver");
- }
- if (PlatformUtil.isWindows()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
- }
- if (PlatformUtil.isLinux()) {
- System.setProperty("webdriver.chrome.driver", "chromedriver_linux");
- }
- }
-
-
-}
diff --git a/src/main/java/com/codinground/driverutiils/DriverFactory.java b/src/main/java/com/codinground/driverutiils/DriverFactory.java
new file mode 100644
index 00000000..8f475c90
--- /dev/null
+++ b/src/main/java/com/codinground/driverutiils/DriverFactory.java
@@ -0,0 +1,69 @@
+package com.codinground.driverutiils;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.openqa.selenium.firefox.FirefoxDriver;
+
+import com.codinground.ioutils.PropertiesFileUtil;
+import com.sun.javafx.PlatformUtil;
+
+public class DriverFactory {
+
+ protected static WebDriver driver;
+ private static ChromeOptions options;
+
+ public DriverFactory() {
+ initialize();
+ }
+
+ public void initialize() {
+
+ if (driver == null)
+ createNewDriverInstance();
+ }
+
+ private void createNewDriverInstance() {
+ String browser = new PropertiesFileUtil().readProperty("browser");
+ String driverPathWin =new PropertiesFileUtil().readProperty("driverPathWin");
+ String driverPathMac = new PropertiesFileUtil().readProperty("driverPathMac");
+ String driverPathLinux = new PropertiesFileUtil().readProperty("driverPathLinux");
+ if (browser.equals("firefox")) {
+ driver = new FirefoxDriver();
+ } else if
+ (browser.equals("chrome")) {
+ if (PlatformUtil.isMac()) {
+ System.setProperty("webdriver.chrome.driver", driverPathMac);
+ }
+ if (PlatformUtil.isWindows()) {
+ System.setProperty("webdriver.chrome.driver", driverPathWin);
+ }
+ if (PlatformUtil.isLinux()) {
+ System.setProperty("webdriver.chrome.driver", driverPathLinux);
+ }
+ options = new ChromeOptions();
+ options.addArguments("--disable-notifications");
+ driver = new ChromeDriver(options);
+ }
+
+ }
+
+ public void launchUrl() {
+ String url = new PropertiesFileUtil().readProperty("url");
+ driver.get(url);
+
+ }
+ public WebDriver getDriver() {
+ return driver;
+ }
+
+ public void destroyDriver() {
+ driver.quit();
+ driver = null;
+ }
+
+
+
+
+
+}
diff --git a/src/main/java/com/codinground/ioutils/PropertiesFileUtil.java b/src/main/java/com/codinground/ioutils/PropertiesFileUtil.java
new file mode 100644
index 00000000..2c1a5b9a
--- /dev/null
+++ b/src/main/java/com/codinground/ioutils/PropertiesFileUtil.java
@@ -0,0 +1,29 @@
+package com.codinground.ioutils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class PropertiesFileUtil {
+
+ Properties properties = new Properties();
+ InputStream inputStream = null;
+
+ public PropertiesFileUtil() {
+ loadProperties();
+ }
+
+ private void loadProperties() {
+ try {
+ inputStream = new FileInputStream("./src/test/resources/testconfig/uitestconfig.properties");
+ properties.load(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String readProperty(String key) {
+ return properties.getProperty(key);
+ }
+}
diff --git a/src/main/java/com/codinground/pages/FlightBookingPage.java b/src/main/java/com/codinground/pages/FlightBookingPage.java
new file mode 100644
index 00000000..c277b348
--- /dev/null
+++ b/src/main/java/com/codinground/pages/FlightBookingPage.java
@@ -0,0 +1,233 @@
+package com.codinground.pages;
+
+
+
+import java.util.List;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.LoadableComponent;
+import org.testng.Assert;
+
+import com.codinground.uicommon.UiCommonLibrary;
+
+
+ public class FlightBookingPage extends LoadableComponent{
+
+
+ private WebDriver driver;
+
+ private static UiCommonLibrary objCommon;
+ //private static SimpleDateFormat formatter = new SimpleDateFormat("dd/mmmm/yyyy");
+ private static String delimiter = null;
+ private static String day = null;
+ private static String month = null;
+ private static String year = null;
+ private static String strActualMonth = null;
+ private static String strActualYear = null;
+ private static String[] dateArr;
+
+ private static final String STR_DATE_PICKER = "//*[@id='ui-datepicker-div']";
+ private static final String STR_MONTH_FIRST_LAST = STR_DATE_PICKER+"/child::div";
+
+ private static final By LOCATOR_BUTTON_ONEWAY = By.id("OneWay");
+ private static final By LOCATOR_INPUT_FROM = By.id("FromTag");
+ private static final By LOCATOR_INPUT_FROM_CHECK = By.id("From");
+ private static final By LOCATOR_INPUT_TO = By.id("ToTag");
+ private static final By LOCATOR_INPUT_TO_CKECK = By.id("To");
+ private static final By LOCATOR_BUTTON_SEARCH = By.id("SearchBtn");
+ private static final By LOCATOR_MONTH_FIRST_LAST = By.xpath(STR_MONTH_FIRST_LAST);
+ private static final By LOCATOR_LINK_FLIGHTS = By.linkText("Flights");
+ private static final By LOCATOR_LINK_HOTELS = By.linkText("Hotels");
+ private static final By LOCATOR_LIST_ORIGIN_OPT = By.xpath("//*[@id='ui-id-1']/li");
+ private static final By LOCATOR_LIST_DESTINATION_OPT = By.xpath("//*[@id='ui-id-2']/li");
+ private static final By LOCATOR_BUTTON_CALANDER_ICON = By.linkText("Cal");
+ private static final By LOCATOR_LINK_YOUR_TRIPS = By.linkText("Your trips");
+ private static final By LOCATOR_BUTTON_SIGNIN = By.id("SignIn");
+
+ private static WebElement btnOneWay;
+ private static WebElement txtFrom;
+ private static WebElement txtTo;
+ private static WebElement btnSearch;
+ private static WebElement lnkFlights;
+ private static WebElement lnkHotels;
+ private static WebElement lnkYourTrips;
+ private static List elemDayRows;
+ private static List elemColumns;
+ private static WebElement actualDay;
+ private static WebElement txtFromCheck;
+ private static WebElement txtToCheck;
+ private static List originOptions;
+ private static List destinationOptions;
+ private static List monthFirstLast;
+
+ public FlightBookingPage(WebDriver driver) {
+ this.driver = driver;
+ objCommon = new UiCommonLibrary(driver);
+ }
+
+
+ public FlightBookingPage enterDepartFrom(String place) {
+ for(int i =0; i<+3;i++) {
+ try {
+ objCommon.sendKeysOneByOne(LOCATOR_INPUT_FROM,place);
+ objCommon.waitFor(ExpectedConditions.presenceOfAllElementsLocatedBy(LOCATOR_LIST_ORIGIN_OPT),10);
+ driver.findElements(LOCATOR_LIST_ORIGIN_OPT).get(0).click();
+ break;
+ }catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return this;
+ }
+
+ public boolean checkIfFromEntered(String excpected) {
+
+ return objCommon.checkIfOptionEntered(LOCATOR_INPUT_FROM_CHECK,excpected);
+
+ }
+
+ public boolean checkIfToEntered(String excpected) {
+
+ return objCommon.checkIfOptionEntered(LOCATOR_INPUT_TO_CKECK,excpected);
+
+ }
+
+ public FlightBookingPage enterToArrive(String place) {
+ for(int i =0; i<+3;i++) {
+ try {
+ objCommon.sendKeysOneByOne(LOCATOR_INPUT_TO,place);
+ objCommon.waitFor(ExpectedConditions.presenceOfAllElementsLocatedBy(LOCATOR_LIST_DESTINATION_OPT),10);
+ driver.findElements(LOCATOR_LIST_DESTINATION_OPT).get(0).click();
+ break;
+ }catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ return this;
+ }
+
+ public FlightBookingPage clickOneWay() {
+ try {
+ if(objCommon.isElementDisplayed(LOCATOR_BUTTON_ONEWAY)) {
+ if(!driver.findElement(LOCATOR_BUTTON_ONEWAY).getAttribute("checked").equals("true")) {
+ objCommon.clickElement(LOCATOR_BUTTON_ONEWAY);
+ }
+ }
+ }catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ return this;
+ }
+
+ public boolean chechIfOnWayClicked(String expected) {
+
+ return objCommon.checkIfRadioButtonClicked(LOCATOR_BUTTON_ONEWAY,expected);
+
+ }
+
+ public void clickYourTrips() {
+
+ objCommon.clickElement(LOCATOR_LINK_YOUR_TRIPS);
+
+ }
+
+ public SignInPage clickSignInBtn(String name) {
+
+ objCommon.clickElement(LOCATOR_BUTTON_SIGNIN);
+ //objCommon.switchToFrameByIndex(frameIndex);
+ objCommon.switchToFrameByNameOrId(name);
+
+ return new SignInPage(driver).get();
+
+ }
+
+ public SearchSummaryPage clickSearchBtn() {
+
+ if(objCommon.isElementDisplayed(LOCATOR_BUTTON_SEARCH)) {
+ objCommon.clickElement(LOCATOR_BUTTON_SEARCH);
+ }
+ return new SearchSummaryPage(driver).get();
+ }
+
+public HotelBookingPage clickHotelLnk() {
+
+ objCommon.clickElement(LOCATOR_LINK_HOTELS);;
+ return new HotelBookingPage(driver).get();
+ }
+
+
+ public void pickFromDate(String date) {
+
+ delimiter= "/";
+ dateArr = date.split(delimiter);
+ day = dateArr[0];
+ month = dateArr[1];
+ year = dateArr[2];
+ monthFirstLast = driver.findElements(LOCATOR_MONTH_FIRST_LAST);
+ int i=0,j=0,k=0;
+ for (i=0; i{
+
+
+ private WebDriver driver;
+ private static UiCommonLibrary objCommon;
+ private static String delimiter = null;
+ private static String day = null;
+ private static String month = null;
+ private static String year = null;
+ private static String strActualMonth = null;
+ private static String strActualYear = null;
+ private static String[] dateArr;
+
+ private static final By LOCATOR_OPTIONS = By.xpath("//*[@id='ui-id-1']/li");
+ private static final String STR_DATE_PICKER = "//*[@id='ui-datepicker-div']";
+ private static final String STR_MONTH_FIRST_LAST = STR_DATE_PICKER+"/child::div";
+ private static final By LOCATOR_MONTH_FIRST_LAST = By.xpath(STR_MONTH_FIRST_LAST);
+ private static final By LOCATOR_BUTTON_SEARCH_HOTEL = By.id("SearchHotelsButton");
+
+
+
+ @FindBy(linkText = "Hotels")
+ private static WebElement hotelLink;
+
+ @FindBy(id = "Tags")
+ private static WebElement localityTextBox;
+
+ @FindBy(id = "SearchHotelsButton")
+ private static WebElement searchButton;
+
+ @FindBy(id = "travellersOnhome")
+ private static WebElement travellerSelection;
+
+ private static List elemOptions;
+ private static List monthFirstLast;
+ private static List elemDayRows;
+ private static List elemColumns;
+ private static WebElement actualDay;
+
+ public HotelBookingPage(WebDriver driver) {
+
+ this.driver = driver;
+ PageFactory.initElements(driver, this);
+ objCommon = new UiCommonLibrary(driver);
+
+ }
+
+ public HotelBookingPage clickHotelLnk() {
+
+ hotelLink.click();
+ return this;
+ }
+
+ public HotelBookingPage enterLocationTxt(String place) {
+
+ objCommon.sendKeysOneByOne(By.id("Tags"), place);
+ objCommon.waitFor(ExpectedConditions.presenceOfAllElementsLocatedBy(LOCATOR_OPTIONS), 10);
+ driver.findElements(LOCATOR_OPTIONS).get(1).click();
+ return this;
+ }
+
+ public HotelBookingPage selectTravellers(String text) {
+ objCommon.waitFor(ExpectedConditions.visibilityOf(driver.findElement(By.id("travellersOnhome"))), 10);
+ objCommon.selectByValue(By.id("travellersOnhome"),text);
+ return this;
+ }
+
+ public SearchSummaryPage clickSearchBtn() {
+
+ if(objCommon.isElementDisplayed(LOCATOR_BUTTON_SEARCH_HOTEL)) {
+ objCommon.clickElement(LOCATOR_BUTTON_SEARCH_HOTEL);
+ }
+ return new SearchSummaryPage(driver).get();
+ }
+
+ public void pickDate(String date) {
+
+ delimiter= "/";
+ dateArr = date.split(delimiter);
+ day = dateArr[0];
+ month = dateArr[1];
+ year = dateArr[2];
+ monthFirstLast = driver.findElements(LOCATOR_MONTH_FIRST_LAST);
+ int i=0,j=0,k=0;
+ for (i=0; i{
+
+
+ private WebDriver driver;
+ private static WebElement elemSearchSummary;
+ private static String place;
+
+ private static final By LOCATOR_TITLE_SEARCH_SUMMARY = By.className("searchSummary");
+ private static final By LOCATOR_TXT_FROMTO_SEARCH_RESULTS = By.xpath("//*[@class='searchSummary']/*[1]");
+
+ public SearchSummaryPage(WebDriver driver) {
+ this.driver = driver;
+ }
+ public boolean verifyIfRelevant(String from, String to) {
+ boolean flag = false;
+ if(driver.findElement(LOCATOR_TXT_FROMTO_SEARCH_RESULTS).getText().contains(from)&&
+ driver.findElement(LOCATOR_TXT_FROMTO_SEARCH_RESULTS).getText().contains(to)) {
+ flag = true;
+ }
+
+ return flag;
+ }
+
+ public boolean verifyIfRelevant(String place) {
+ boolean flag = false;
+ if(driver.findElement(LOCATOR_TXT_FROMTO_SEARCH_RESULTS).getText().contains(place)) {
+ flag = true;
+ }
+
+ return flag;
+ }
+
+ @Override
+ protected void load() {
+
+ elemSearchSummary = driver.findElement(LOCATOR_TITLE_SEARCH_SUMMARY);
+ }
+
+ @Override
+ protected void isLoaded() throws Error {
+
+ Assert.assertTrue(driver.findElement(LOCATOR_TITLE_SEARCH_SUMMARY).isDisplayed());
+
+ }
+
+
+}
diff --git a/src/main/java/com/codinground/pages/SignInPage.java b/src/main/java/com/codinground/pages/SignInPage.java
new file mode 100644
index 00000000..30c2335a
--- /dev/null
+++ b/src/main/java/com/codinground/pages/SignInPage.java
@@ -0,0 +1,57 @@
+package com.codinground.pages;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.LoadableComponent;
+import org.testng.Assert;
+
+import com.codinground.uicommon.UiCommonLibrary;
+import com.codinground.uicommon.UiConstants;
+
+public class SignInPage extends LoadableComponent{
+
+ private WebDriver driver;
+ private static WebElement signInBtn;
+ private static UiCommonLibrary objCommon;
+
+ private static final By LOCATOR_SIGNIN_BUTTON = By.id("signInButton");
+ private static final By LOCATOR_ERRORS = By.id("errors1");
+
+
+ public SignInPage(WebDriver driver) {
+ this.driver=driver;
+ objCommon = new UiCommonLibrary(driver);
+
+ }
+
+ public SignInPage clickSignIn() {
+ objCommon.waitFor(ExpectedConditions.visibilityOf(driver.findElement(LOCATOR_SIGNIN_BUTTON)), 10);
+ objCommon.clickElement(LOCATOR_SIGNIN_BUTTON);
+ return this;
+ }
+
+ public boolean verifyErrorMsg() {
+
+ boolean flag = false;
+ if(driver.findElement(LOCATOR_ERRORS).getText().contains(UiConstants.SIGN_IN_ERROR)) {
+ flag = true;
+ }
+ return flag;
+ }
+
+ @Override
+ protected void load() {
+ signInBtn =driver.findElement(LOCATOR_SIGNIN_BUTTON);
+
+ }
+
+ @Override
+ protected void isLoaded() throws Error {
+ objCommon.waitFor(ExpectedConditions.visibilityOf(driver.findElement(LOCATOR_SIGNIN_BUTTON)), 10);
+ Assert.assertTrue(driver.findElement(LOCATOR_SIGNIN_BUTTON).isDisplayed());
+
+ }
+
+}
diff --git a/src/main/java/com/codinground/reportutils/ReportListener.java b/src/main/java/com/codinground/reportutils/ReportListener.java
new file mode 100644
index 00000000..3a532259
--- /dev/null
+++ b/src/main/java/com/codinground/reportutils/ReportListener.java
@@ -0,0 +1,101 @@
+package com.codinground.reportutils;
+
+
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.apache.commons.io.FileUtils;
+import org.openqa.selenium.OutputType;
+import org.openqa.selenium.TakesScreenshot;
+
+
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+
+import com.codinground.driverutiils.DriverFactory;
+import com.relevantcodes.extentreports.ExtentReports;
+import com.relevantcodes.extentreports.ExtentTest;
+import com.relevantcodes.extentreports.LogStatus;
+
+
+public class ReportListener implements ITestListener {
+
+
+
+ protected static ExtentReports reports;
+ protected static ExtentTest test;
+ private ITestContext context;
+ private DriverFactory objDriverFac = new DriverFactory();
+
+ public void onTestStart(ITestResult result) {
+ System.out.println("on test start");
+ test = reports.startTest(result.getMethod().getMethodName());
+ test.log(LogStatus.INFO, result.getMethod().getMethodName() + "test is started");
+ }
+
+ public void onTestSuccess(ITestResult result) {
+ System.out.println("on test success");
+ test.log(LogStatus.PASS, result.getMethod().getMethodName() + "test is passed");
+ TakesScreenshot ts = (TakesScreenshot) objDriverFac.getDriver();
+ File src = ts.getScreenshotAs(OutputType.FILE);
+ try {
+ FileUtils.copyFile(src, new File(System.getProperty("user.dir") + "\\ExtentReports\\"+context.getName()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"_passed.png"));
+ // String file = test.addScreenCapture("./" + result.getTestName()+result.getMethod().getMethodName() + ".png");
+ String file = test.addScreenCapture(System.getProperty("user.dir") + "\\ExtentReports\\"+context.getName()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"_passed.png");
+ System.out.println("**********************************=======================================************************************************");
+ test.log(LogStatus.PASS, result.getMethod().getMethodName() + "test passed", file);
+ test.log(LogStatus.PASS, result.getMethod().getMethodName() + "test passed");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+ public void onTestFailure(ITestResult result) {
+ System.out.println("on test failure");
+ test.log(LogStatus.FAIL, result.getMethod().getMethodName() + "test is failed");
+ TakesScreenshot ts = (TakesScreenshot) objDriverFac.getDriver();
+ File src = ts.getScreenshotAs(OutputType.FILE);
+ try {
+ FileUtils.copyFile(src, new File(System.getProperty("user.dir") + "\\ExtentReports\\"+context.getName()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"_failed.png"));
+ String file = test.addScreenCapture(System.getProperty("user.dir") + "\\ExtentReports\\"+context.getName()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"_failed.png");
+ System.out.println("**********************************=======================================************************************************");
+ test.log(LogStatus.FAIL, result.getMethod().getMethodName() + "test failed", file);
+ test.log(LogStatus.FAIL, result.getMethod().getMethodName() + "test failed", result.getThrowable().getMessage());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public void onTestSkipped(ITestResult result) {
+ System.out.println("on test skipped");
+ test.log(LogStatus.SKIP, result.getMethod().getMethodName() + "test is skipped");
+ }
+
+
+ public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
+ System.out.println("on test sucess within percentage");
+ }
+
+
+ public void onStart(ITestContext context) {
+ System.out.println("on start");
+ String workingDir = System.getProperty("user.dir");
+ this.context = context;
+ reports = new ExtentReports(workingDir + "\\ExtentReports\\"+context.getName()+"_"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"_ExtentReportResults.html",true);
+
+ }
+
+
+ public void onFinish(ITestContext context) {
+ System.out.println("on finish");
+ reports.endTest(test);
+ reports.flush();
+ }
+}
+
diff --git a/src/main/java/com/codinground/testrunutils/AddAnnotations.java b/src/main/java/com/codinground/testrunutils/AddAnnotations.java
new file mode 100644
index 00000000..1a8f53eb
--- /dev/null
+++ b/src/main/java/com/codinground/testrunutils/AddAnnotations.java
@@ -0,0 +1,17 @@
+package com.codinground.testrunutils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.testng.IAnnotationTransformer;
+import org.testng.annotations.ITestAnnotation;
+
+public class AddAnnotations implements IAnnotationTransformer{
+
+ public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
+
+ annotation.setRetryAnalyzer(RetryFailed.class);
+
+ }
+
+}
diff --git a/src/main/java/com/codinground/testrunutils/RetryFailed.java b/src/main/java/com/codinground/testrunutils/RetryFailed.java
new file mode 100644
index 00000000..5df3ebc8
--- /dev/null
+++ b/src/main/java/com/codinground/testrunutils/RetryFailed.java
@@ -0,0 +1,24 @@
+package com.codinground.testrunutils;
+
+import org.testng.IRetryAnalyzer;
+import org.testng.ITestResult;
+
+import com.codinground.ioutils.PropertiesFileUtil;
+
+public class RetryFailed implements IRetryAnalyzer{
+
+ private PropertiesFileUtil objProperty = new PropertiesFileUtil();
+ private int counter =0;
+ private String retriesLimiter = objProperty.readProperty("numberOfRetriesFailed");
+
+ public boolean retry(ITestResult result) {
+ //&&(!result.isSuccess())
+
+ while(counter void waitFor(ExpectedCondition expectedConditions,int timeOut) {
+
+ new WebDriverWait(driver, timeOut).until(expectedConditions);
+
+ }
+
+ /*public String alertHandler(String operation) {
+
+ alert = driver.switchTo().alert();
+ String strToReturn = null;
+
+ switch(operation) {
+ case"dissmis":
+ alert.dismiss();
+ strToReturn = alert.getText()+": Alert Dissmissed";
+ case"accept":
+ alert.accept();
+ strToReturn = alert.getText()+": Alert Accepted";
+ case"getText":
+ alert.getText();
+ strToReturn = "Alert Text: "+alert.getText();
+ }
+ return strToReturn;
+ }*/
+
+ public void clickElement(By xpath) {
+
+ driver.findElement(xpath).click();
+
+ }
+
+ public boolean isElementDisplayed(By xpath) {
+ boolean state= false;
+ state = driver.findElement(xpath).isDisplayed();
+ return state;
+ }
+
+ public void implictWaitOn() {
+
+ driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
+
+ }
+
+ public void implicitWaitOff() {
+
+ driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
+
+ }
+
+ /*public void selectValue(By xpath, String value, String method) {
+
+ select = new Select(driver.findElement(xpath));
+
+ switch (method) {
+
+ case "byIndex":
+
+ select.selectByIndex(Integer.valueOf(value));
+
+ case "byValue":
+
+ select.selectByValue(value);
+
+ case "byVisibleText":
+
+ select.selectByVisibleText(value);
+ }
+ }*/
+
+ public void selectByValue(By xpath, String value) {
+
+ select = new Select(driver.findElement(xpath));
+ select.selectByVisibleText(value);
+ }
+
+ public boolean checkIfOptionEntered(By xpath, String expected) {
+ boolean flag=false;
+ waitFor(ExpectedConditions.presenceOfElementLocated(xpath), 10);
+ if(driver.findElement(xpath).getAttribute("value").equalsIgnoreCase(expected)) {
+ flag=true;
+ }
+ return flag;
+ }
+
+ public boolean checkIfRadioButtonClicked(By xpath, String expected) {
+ boolean flag=false;
+ waitFor(ExpectedConditions.presenceOfElementLocated(xpath), 10);
+ if(driver.findElement(xpath).getAttribute("checked").equalsIgnoreCase(expected)) {
+ flag=true;
+ }
+ return flag;
+ }
+ }
+
+
+
+
+
+
+
diff --git a/src/main/java/com/codinground/uicommon/UiConstants.java b/src/main/java/com/codinground/uicommon/UiConstants.java
new file mode 100644
index 00000000..ec98474e
--- /dev/null
+++ b/src/main/java/com/codinground/uicommon/UiConstants.java
@@ -0,0 +1,11 @@
+
+package com.codinground.uicommon;
+
+public class UiConstants {
+
+ public static final String BANGALORE = "BLR";
+ public static final String NEW_DELHI = "DEL";
+ public static final String ATTRIBUTE_CHECKED = "true";
+ public static final String SIGN_IN_ERROR = "There were errors in your submission";
+
+}
diff --git a/src/main/resources/com/codinground/dummy_ignore/Dummy.java b/src/main/resources/com/codinground/dummy_ignore/Dummy.java
new file mode 100644
index 00000000..f72b9712
--- /dev/null
+++ b/src/main/resources/com/codinground/dummy_ignore/Dummy.java
@@ -0,0 +1,10 @@
+package com.codinground.dummy_ignore;
+
+/**
+ * Added to avoid missing src/main/resources error on importing
+ * has no dependencies
+ * can be removed
+*/
+public class Dummy {
+
+}
diff --git a/src/test/java/com/codinground/tests/FlightBookingTest.java b/src/test/java/com/codinground/tests/FlightBookingTest.java
new file mode 100644
index 00000000..8efdd779
--- /dev/null
+++ b/src/test/java/com/codinground/tests/FlightBookingTest.java
@@ -0,0 +1,63 @@
+package com.codinground.tests;
+import com.codinground.driverutiils.DriverFactory;
+import com.codinground.pages.FlightBookingPage;
+import com.codinground.pages.SearchSummaryPage;
+import com.codinground.reportutils.ReportListener;
+import com.codinground.uicommon.UiConstants;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.openqa.selenium.WebDriver;
+import org.testng.Assert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+
+
+public class FlightBookingTest extends ReportListener {
+
+
+
+
+ private WebDriver driver;
+ private static FlightBookingPage objFlightPage;
+ private static DriverFactory objDriverFactory;
+ private static SearchSummaryPage objSearchSummaryPage;
+ private static ReportListener objReportListener;
+
+ @BeforeTest
+ public void before() {
+ objDriverFactory = new DriverFactory();
+ objDriverFactory.launchUrl();
+ driver = objDriverFactory.getDriver();
+ driver.manage().window().maximize();
+
+ }
+
+ @Test
+ public void testThatResultsAppearForAOneWayJourney() {
+
+ objFlightPage = new FlightBookingPage(driver).get();
+
+ objFlightPage = objFlightPage.clickOneWay();
+ Assert.assertTrue(objFlightPage.chechIfOnWayClicked(UiConstants.ATTRIBUTE_CHECKED));
+ objFlightPage = objFlightPage.enterDepartFrom("Bangalore");
+ Assert.assertTrue(objFlightPage.checkIfFromEntered(UiConstants.BANGALORE));
+ objFlightPage = objFlightPage.enterToArrive("New Delhi");
+ Assert.assertTrue(objFlightPage.checkIfToEntered(UiConstants.NEW_DELHI));
+ objFlightPage = new FlightBookingPage(driver).get();
+ objFlightPage.pickFromDate(new SimpleDateFormat("d/MMMM/yyyy").format(new Date()));
+ objSearchSummaryPage = objFlightPage.clickSearchBtn();
+ Assert.assertTrue(objSearchSummaryPage.verifyIfRelevant("Bangalore", "New Delhi"));
+ }
+
+ @AfterTest
+ public void after() {
+
+ objDriverFactory.destroyDriver();
+
+ }
+
+}
diff --git a/src/test/java/com/codinground/tests/HotelBookingTest.java b/src/test/java/com/codinground/tests/HotelBookingTest.java
new file mode 100644
index 00000000..07a7de10
--- /dev/null
+++ b/src/test/java/com/codinground/tests/HotelBookingTest.java
@@ -0,0 +1,67 @@
+package com.codinground.tests;
+import com.codinground.driverutiils.DriverFactory;
+import com.codinground.pages.FlightBookingPage;
+import com.codinground.pages.HotelBookingPage;
+import com.codinground.pages.SearchSummaryPage;
+import com.codinground.reportutils.ReportListener;
+import com.codinground.uicommon.UiCommonLibrary;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.openqa.selenium.WebDriver;
+import org.testng.Assert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+public class HotelBookingTest extends ReportListener{
+
+ private WebDriver driver;
+ private static Date today;
+ private static Calendar cal;
+ private static String date;
+ private static HotelBookingPage objHotelPage;
+ private static DriverFactory objDriverFactory;
+ private static SearchSummaryPage objSearchSummaryPage;
+ private static FlightBookingPage objFlightPage;
+
+ @BeforeTest
+ public void before() {
+ objDriverFactory = new DriverFactory();
+ objDriverFactory.launchUrl();
+ driver = objDriverFactory.getDriver();
+ driver.manage().window().maximize();
+ }
+ @Test
+ public void shouldBeAbleToSearchForHotels() throws InterruptedException {
+
+ objFlightPage = new FlightBookingPage(driver).get();
+ objHotelPage = objFlightPage.clickHotelLnk();
+ objHotelPage = objHotelPage.enterLocationTxt("Indiranagar, Bangalore");
+ objHotelPage.pickDate(new SimpleDateFormat("d/MMMM/yyyy").format(new Date()));
+ /*pick the next day*/
+ today = new Date();
+ cal = Calendar.getInstance();
+ cal.setTime(today);
+ cal.add(Calendar.DATE, 1);
+ today = cal.getTime();
+ date = new SimpleDateFormat("d/MMMM/yyyy").format(today);
+ objHotelPage.pickDate(date);
+ objHotelPage = objHotelPage.selectTravellers("1 room, 2 adults");
+ objSearchSummaryPage = objHotelPage.clickSearchBtn();
+ Assert.assertTrue(objSearchSummaryPage.verifyIfRelevant("Bangalore"));
+
+ }
+
+
+ @AfterTest
+ public void after() {
+
+ objDriverFactory.destroyDriver();
+
+ }
+
+
+}
diff --git a/src/test/java/com/codinground/tests/SignInTest.java b/src/test/java/com/codinground/tests/SignInTest.java
new file mode 100644
index 00000000..66257d6a
--- /dev/null
+++ b/src/test/java/com/codinground/tests/SignInTest.java
@@ -0,0 +1,49 @@
+package com.codinground.tests;
+import org.openqa.selenium.WebDriver;
+import org.testng.Assert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import com.codinground.driverutiils.DriverFactory;
+import com.codinground.pages.FlightBookingPage;
+import com.codinground.pages.SignInPage;
+import com.codinground.reportutils.ReportListener;
+
+public class SignInTest extends ReportListener{
+
+ private WebDriver driver;
+ private static DriverFactory objDriverFactory;
+ private static FlightBookingPage objFlightPage;
+ private static SignInPage objSignInPage;
+
+
+ @BeforeTest
+ public void beforeTest() {
+ objDriverFactory = new DriverFactory();
+ objDriverFactory.launchUrl();
+ driver = objDriverFactory.getDriver();
+ objSignInPage = new SignInPage(driver);
+ driver.manage().window().maximize();
+ }
+
+ @Test
+ public void shouldThrowAnErrorIfSignInDetailsAreMissing() {
+
+ objFlightPage = new FlightBookingPage(driver).get();
+ objFlightPage.clickYourTrips();
+ objSignInPage = objFlightPage.clickSignInBtn("modal_window");
+ objSignInPage.clickSignIn();
+ Assert.assertTrue(objSignInPage.verifyErrorMsg());
+
+
+
+ }
+
+ @AfterTest
+ public void afterTest() {
+ objDriverFactory.destroyDriver();
+
+ }
+
+}
diff --git a/src/test/resources/testconfig/uitestconfig.properties b/src/test/resources/testconfig/uitestconfig.properties
new file mode 100644
index 00000000..25a96038
--- /dev/null
+++ b/src/test/resources/testconfig/uitestconfig.properties
@@ -0,0 +1,6 @@
+browser=chrome
+driverPathWin=./drivers/chromedriver_win.exe
+driverPathMac=./drivers/chromedriver_mac
+driverPathLinux=./drivers/chromedriver_Linux
+url=https://www.cleartrip.com/
+numberOfRetriesFailed=2
\ No newline at end of file
diff --git a/testng.xml b/testng.xml
new file mode 100644
index 00000000..80b06bff
--- /dev/null
+++ b/testng.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+