Monday, July 18, 2016

GUI Framework

Folks,

Done with setup !!!!

Before going to integration of different GUI ,API and Mobile apps scripts, we should have separate scripts / framework for each of these(GUI Automation Framework, API Automation Framework and Mobile App Automation Framework ). So let us start learning these frameworks individually and will have separate post for integration these frameworks.

 In this post i am going to discuss about the GUI framework.


 The above  architecture diagram you can see the components and flow of the GUI Framework.


Framework mainly consist of following components 


  1. Page Elements - Page Elements is package, contains application page wise web elements. Its like web elements / object repository. We should create new class for every new page in the application so that it will be helpful in maintenance, debugging and creating scripts.                                                                                                                                                                                        Example -  Assume that we have one automation flow where we need to login to application , after login click on menu and select one option from menu. After analyzing the flow for this flow we have to have mainly 3 web elements classes  as below                                                                                           LoginElements - In this class we will be having all the elements in login page i.e. user id, password, login button forgot password link etc...                                  HomePageElements - All the elements in home page i.e. menu button home page icon, logout etc....                                                                                        MenuPageElements - All the elements in menu link , on click whatever the selection under menu link will be stored here.    We can reuse these element classes for other flows like where ever we get login flow to the application we can use these elements.                                                                                                 As i  am using PageFactory pattern  in the framework so i am using @FindBy annotation to identify the web elements.   Using the PageFactory, these Web Elements are usually initialized when a Page Object is created. You can see Login page elements  in following screenshot                                                             package PageElements;

    import java.util.List;

    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.support.FindBy;

    public class LoginElements {

    @FindBy(id="username-email")
    public WebElement txt_username;


    @FindBy(id="password")
    public WebElement  txt_password;

    @FindBy(id="btnLogin")
    public WebElement btn_login;     
          
    }  
                                                                                                                                  
                                                                                                                                                 Syntax for identifying elements using FindBy annotation -                                                                                                                                    @FindBy(locator ="locator value as in application ")                                                    accessmodifier WebElement nameofelement;                                                                                                                                                                               Ex - @FindBy(id = "username-email")                                                                            public WebElement txt_username ;                                                                                                                                                                                     Annotation supports all the locators type present in selenium  Class Name,CSS,ID,Name, LinkText, Partial Link Text , Tag Name and Xpath. For more information click here                                                                                                                                                                                                        

  2.  Page Operation - Page operation is package,  contains page wise operations. We should have one class operation for one page element.  Example - Consider the same login flow as in  above Web Element section. We have 3 elements class in Page element section i.e  LoginElements , HomePageElements and MenuPageElements  so we should have 3 operation classes i.e                                                                                                                                                       LoginOperation - The class contains operations related to login page Ex - entering user id password clicking login button etc.. To work with login operation we need of login page web elements so LoginOperation Extends LoginElements so that we can use all the elements in LoginElements in LoginOperations class. HomePageOperation - The class contains operations related to Home page , as explained in LoginOperation here HomePageOperation Extends HomePageElements class so the HomePageOperation class can access HomePageElements.                                                                          MenuPageOperation - Class contains MenuPageOperation , this class extends MenuPageElements.   You can see the operations in below screenshot        
      
    package PageOperations;                                                   import java.util.List;
    import PageElements.LoginElements;
    import atu.testng.reports.ATUReports;
    import atu.testng.reports.logging.LogAs;
    import atu.testng.selenium.reports.CaptureScreen;
    import atu.testng.selenium.reports.CaptureScreen.ScreenshotOf;

    public class LoginOperation extends LoginElements {

           public void login(String userid, String Password ){
              try {
                     txt_username.sendKeys(userid);
                     txt_password.sendKeys(Password);
                     btn_login.click(); // Use ATUReports or TestNG report as of now i am using ATUReports we will discuss about reporting later
                     ATUReports.add("Logging in as ", userid, LogAs.PASSED, new CaptureScreen(ScreenshotOf.BROWSER_PAGE));
                        
              } catch (Exception e) {
                     ATUReports.add("Logging in as ", userid, LogAs.FAILED, new CaptureScreen(ScreenshotOf.BROWSER_PAGE));
                  }    
           }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                         Syntax to use page elements in operation -                                                              nameofement.operation ;                                                                                     Ex - txt_username.sendkeys("");                                                                                                                                                                                                          Over all the page elements contains individual page elements PageElements 1 , PageElements 2 .................. PageElements N and the Operations extends these elements PageOperation 1 Extends PageElements 1 , PageOperation 2 Extends PageElements 2 ....................... PageOperation N Extends PageElements N                                                                                                                                                                      
  3. Base Page - Base Page package contains Pages class. In Pages class we are calling PageFactory, and initiating the elements. For more details on Page Factory click here    For every operation page create one method in Pages class and add return statement of PageFactory.initelements(driver,class), So that we will be having all the operations and elements in that method. You can see initiating elements in below screenshot, for example the method login() is having all the login page operation and login elements. The operations and elements of the login are initialized here. In the same way we should create the methods for all operation classes       package BasePage;


    import org.openqa.selenium.support.PageFactory;
    import PageOperations.BOSS_AssociateAndDownlineformsPageOperation;
    import PageOperations.BOSS_AssociateOnlyTransferOperations;
    import PageOperations.BOSS_DirectDepositAuthorizationCAOperation;
    import PageOperations.BOSS_InactiveTransferformOperations;
    import PageOperations.BOSS_MapLeadershipAgreementOperations;
    import PageOperations.HomePageOperations;
    import PageOperations.LoginOperation;
    import PageOperations.MenuOperations;
    import TestSuite.SuperTestNG;

    /*This method creates pagefactory of all oparations methods*/
    public class Pages {

                    public LoginOperation login() {
                                    return PageFactory.initElements(SuperTestNG.driver,
                                                                    LoginOperation.class);
                    }

                    public HomePageOperations homepage() {
                                    return PageFactory.initElements(SuperTestNG.driver,
                                                                    HomePageOperations.class);
                    }

                    public MenuOperations menupage() {
                                    return PageFactory.initElements(SuperTestNG.driver,
                                                                    MenuOperations.class);
                    }
    }                                                                                                                   
      
     
  4. Test Suite - Test suite consists of all the tests and SuperTestNG classes. In test we are going to create the scenarios by calling operations class using BasePage  Example - login to the application. In this scenario Pages(). navigate you to base page, In base page you can see different operations methods. As per the scenario we want to navigate to login so use login() method i.e Pages().login() now you are in login page operation you can access all methods and elements in login operation class. So to call login method inside the loginoperation class you have to write code like Pages().login().login()                                                                     Note : - every test class in test suite should extend the SuperTestNG class, so that we can use the SuperTestNG methods and elements in our tests.                                                                                                                         mm                                                                                                                                                          
                          SuperTestNG  - SuperTestNG is class in the TestSuite package. In SuperTestNG class we will be having @BeforeTest and @AfterTest. In @BeforeTest we will be adding methods to initializing browser, opening required browsers and opening the URL. We are setting URL in Configuration.properties file from this file we are extracting the URL. In @AfterTest we are clearing cache and closing the browser.                                                                                                                                                                     Test class

    package TestSuite;
    import org.testng.annotations.Test;
    import CommonLibrary.ExcelUtils;
    public class logintest extends SuperTestNG{
                @Test
                public void login() {
                           
                            Pages().login().login("user id ", "password");
                            Pages().homepage().clickmenu();
                }
    }

    SuperTestNG Class

    package TestSuite;

    import java.io.File;
    import java.io.FileInputStream;
    import java.util.Properties;
    import java.util.concurrent.TimeUnit;

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.firefox.FirefoxProfile;
    import org.openqa.selenium.support.PageFactory;
    import org.testng.Reporter;
    import org.testng.annotations.AfterTest;
    import org.testng.annotations.BeforeTest;

    import BasePage.Pages;

    public class SuperTestNG {

     public static WebDriver driver;
     public static Properties properties = new Properties();

     @BeforeTest
     /*
      * 1) This method Sets initialize driver, opens specified browser with URl
      * and
      */
     public static void TestInit() {
      properties = ReadPropertiesFile("src/main/Resources/Configuration.properties");
      driver = TestInitialize(properties.getProperty("Browser"));
      driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
      driver.manage().window().maximize();
      driver.manage().deleteAllCookies();
      driver.get(properties.getProperty("URL"));
      Reporter.log("Test Initialized Successfully");
     
     }

     /* This method clears cache and quit the browser */
     @AfterTest
     public static void TestClean() {
      TestCleanUp();
     }

     public static WebDriver TestInitialize(String browser) {
      if (browser.equals("chrome")) {
       System.setProperty("webdriver.chrome.driver", properties.getProperty("ChromeDriverPath"));
       driver = new ChromeDriver();
      }

      if (browser.equals("ff")) {

        driver= new FirefoxDriver();
      }

      return driver;
     }

     public static void TestCleanUp() {
      driver.manage().deleteAllCookies();
      driver.close();
      try {
       Thread.sleep(3000);
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }

     }

     /*
      * Method to read properties in a file FileName - path of the file
      */
     public static Properties ReadPropertiesFile(String FileName) {
      File file = new File(FileName);
      FileInputStream fileInput;
      try {
       fileInput = new FileInputStream(file);
       properties.load(fileInput);
      } catch (Exception e) {
       e.printStackTrace();
      }
      return properties;
     }

     /* initialize all the elements in pages class under BasePage package */
     public static Pages Pages() {
      return PageFactory.initElements(driver, Pages.class);
     }



  5.   Common Library -   Common library is package where we can  reusable components, these classes can be used in any of the projects. These classes should be generic/global example fetching data from  excel sheet. here we are using Apache poi jar to extract data.                                                                    package CommonLibrary;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.xssf.usermodel.XSSFCell;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;

    public class ExcelUtils {
                    /* Declaration of Excel sheet,workbook,cell and row */
                    private static XSSFSheet ExcelWSheet;
                    private static XSSFWorkbook ExcelWBook;
                    private static XSSFCell Cell;
    //            private static XSSFRow Row;
                    /* Set Excel path and name */
                    public static void setExcelFile(String Path, String SheetName) throws Exception {
                                try {
                                      FileInputStream ExcelFile = new FileInputStream(Path);
                                      ExcelWBook = new XSSFWorkbook(ExcelFile);
                                      ExcelWSheet = ExcelWBook.getSheet(SheetName);
                                    } catch (Exception e) {
                                                    throw (e);
                                    }
                    }

                    /* Get cell value from particular row and column */
                    public static String getCellData(int RowNum, int ColNum) throws Exception {
                              try {
                                    Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
                                    Cell.setCellType(Cell.CELL_TYPE_STRING);
                                     String CellData = Cell.getStringCellValue();
                                     return CellData;
                                    } catch (Exception e) {
                                                    return "";
                                    }
                    }                                                                                                                                                                    In the above class we have 2 methods setExcelFile() and getCellData() . We can use these methods in our test scripts to get data from excel sheet , first set excel path and sheet name as parameter in setExcelFile method then get the data by sending row and column number as parameter in getCellData method.     You can use this code in your tests as shown below    package TestSuite;

    import CommonLibrary.ExcelUtils;

    public class Testexcel {

           public void name1() throws Exception {
                  ExcelUtils.setExcelFile("C:/Users/veeresh.m/Desktop/DDDF1.xlsx", "Sheet1");
                  for(int i=0;i<6;i++){
                         String value = ExcelUtils.getCellData(2, i);
                         System.out.println(value);
                  }
                 
                  String value = ExcelUtils.getCellData(2, 1);
                  System.out.println(value);
                  String value1 = ExcelUtils.getCellData(2, 2);
                  System.out.println(value1);
                  String value2 = ExcelUtils.getCellData(2, 3);
                  System.out.println(value2);
                  String value3 = ExcelUtils.getCellData(2, 4);
                  System.out.println(value3);             
           }
        
    }                                                                                                  
  6.  Test Data , Configuration.properties and Drivers     -   TestData - Create one folder under src/main/resources name it as TestData, all the data related to test are created under TestData folder the data may be in excel or text file. Configuration.properties - is property file where all the configuration are added ex URL, Drivers path, error message etc. Its like final static variables stored in the file. Drivers -  Create one drivers folder, download required drivers from seleniumhq url, add all the drivers related to selenium in that folder.                                                                                                                               
                                                                                                                                                                                                                      
  7. TestNG.xml  -  Convert our test scripts to testng by right click on test - TestNG - convert to testNG or create TestNG.xml file and set the tests to be executed in testng.xml. Click Here for more information on TestNG                                                                                                           
  8. POM.xml - pom.xml having information about plugins, dependencies. Right click on project - click Run - click maven clean after build clean, right click on project - click Run - click maven install. When we clean install maven dowloads all the dependency jars in to .m2 repository and attach to our projects. By using maven no need to download and attach jars externally. pom.xml automatically downloads jars and attach to framework.  In pom.xml we need to set which testng.xml to be executed in <suiteXmlFiles>. The full pom.xml file is as below                                                                                                                                                                                                                                                                                            <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.insurance</groupId>
    <artifactId>WFG</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>

    <configuration>
    <!-- Suite testng xml file to consider for test execution -->

    <reportsDirectory>${project.basedir}/target/</reportsDirectory>

    <suiteXmlFiles>
    <suiteXmlFile>testng.xml</suiteXmlFile>
    </suiteXmlFiles>

    <suiteXmlFiles>
    <suiteXmlFile>testng.xml</suiteXmlFile>
    </suiteXmlFiles>

    <properties>
    Setting ReportNG listeners
    <property>
    <name>listener</name>
    <value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter</value>
    </property>

    <property>
    <name>ATUReportsListener</name>
    <value>atu.testng.reports.listeners.ATUReportsListener,atu.testng.reports.listeners.ConfigurationListener,atu.testng.reports.listeners.MethodListener</value>
    </property>

    </properties>

    </configuration>
    </plugin>

    <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
    <fork>true</fork>
    <executable>C:\Program Files\Java\jdk1.8.0_20\bin\javac.exe</executable>
    <source>1.8</source>
    <target>1.8</target>
    </configuration>
    </plugin>
    </plugins>
    </build>

    <dependencies>

    <dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.8.5</version>
    <scope>compile</scope>
    </dependency>

    <dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.3.2</version>
    </dependency>
    <dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.47</version>
    </dependency>
    <dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcmail-jdk15on</artifactId>
    <version>1.47</version>
    </dependency>

    <dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jfreechart</artifactId>
    <version>1.0.17</version>
    </dependency>

    <dependency>
    <groupId>org.jfree</groupId>
    <artifactId>jcommon</artifactId>
    <version>1.0.17</version>
    </dependency>

    <dependency>

    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>3.0</version>
    <scope>test</scope>

    <exclusions>
    <exclusion>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    </exclusion>
    </exclusions>

    </dependency>

    <dependency>
    <groupId>org.uncommons</groupId>
    <artifactId>reportng</artifactId>
    <version>1.1.2</version>
    <scope>test</scope>
    </dependency>

    <dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
    </dependency>

    <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.10-FINAL</version>
    </dependency>

    <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.10-FINAL</version>
    </dependency>

    <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.10-FINAL</version>
    </dependency>

    <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.53.0</version>
    </dependency>

    <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-firefox-driver</artifactId>
    <version>2.53.0</version>
    </dependency>

    <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>htmlunit-driver</artifactId>
    <version>2.20</version>
    </dependency>

    <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-server</artifactId>
    <version>2.53.0</version>
    </dependency>
    <dependency>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>xmlbeans-maven-plugin</artifactId>
    <version>2.3.0</version>
    </dependency>

    <dependency>
    <groupId>xml-apis</groupId>
    <artifactId>xml-apis</artifactId>
    <version>1.4.01</version>
    </dependency>

    </dependencies>

    </project>