Wednesday, November 29, 2017

Calendar Control / DatePicker Automation with Selenium Webdriver

Selenium Automation for AJAX Calendar Control

There are different types of calendar controls in web as

  1. Ajax Calendar Control
  2. JQuery Calendar ( DatePicker ) control
  3. BootStrap Calendar control
There is no built in selenium automation support for any of above calendar control. We you need to write a logic to handle all case in selecting a date.

Here, I am going to discuss the approach on how to automate AJAX Calendar Control

Below image explains the locator for different controls (elements) in calendar.

Create Utility Page Class for Calendar Control

Now just use above class in test case.

That's All.



Saturday, September 16, 2017

Excel Read Write Library over Apache POI

Maven Dependency

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


 Simple Library class for Excel Read and Write operations using Apache POI
package com.apache.excel.example;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelOperations {

 Workbook workbook;
 
 public ExcelOperations(String filePath) {
  try {
   workbook = new XSSFWorkbook(filePath);
  } catch (IOException e) {
   throw new RuntimeException("Error while reading workbook",e);
  }
 }
 public ExcelOperations() {
  workbook = new XSSFWorkbook(); 
 }
 public Object getValue(int sheetIndex, int rowIndex,int colIndex){
  Sheet sheet = workbook.getSheetAt(sheetIndex);
  return getValue(sheet, rowIndex, colIndex);
 }
 public Object getValue(String sheetName, int rowIndex,int colIndex){
  Sheet sheet = workbook.getSheet(sheetName);
  return getValue(sheet, rowIndex, colIndex);
 }
 public Object getValue( int rowIndex,int colIndex){
  
  return getValue(workbook.getActiveSheetIndex(), rowIndex, colIndex);
 }
 public Object getValue(Sheet sheet, int rowIndex,int colIndex){
  Object value =null;
  Cell c = sheet.getRow(rowIndex).getCell(colIndex);
  switch (c.getCellType()) {
  case STRING:
   value= c.getStringCellValue();
   break;
  case NUMERIC:
   value=c.getNumericCellValue();
   break;
  case _NONE:
  case BLANK:
   value="";
   break;
  case ERROR:
   value="#ERR#";
   break;
  case BOOLEAN:
   value = c.getBooleanCellValue();
   break;
  case FORMULA:
   value= c.getCellFormula();
   break;
  default:
   break;
  }
  return value;
 }
 public int getRowCount(){
  return activeSheet().getLastRowNum()+1;
 }
 private Sheet activeSheet(){
  int index = workbook.getActiveSheetIndex();
  return workbook.getSheetAt(index);
 }
 public int getColumnCount(int rowIndex){
  return getRow(rowIndex).getLastCellNum();
 }
 private Row getRow(int rowIndex) {
  return activeSheet().getRow(rowIndex);
 }
 public void save(String saveToFilePath) {
  try {
   FileOutputStream fos = new FileOutputStream(saveToFilePath);
   workbook.write(fos);
   fos.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 public void setValue(int rowNo, int cellNo,  Object value) {
  setValue(workbook.getActiveSheetIndex(), rowNo, cellNo, value);
 }

 public void setValue(int sheetIndex, int rowNo, int cellNo,  Object value) {
  
  Sheet sheet = workbook.getSheetAt(sheetIndex);
  setValue(sheet, rowNo, cellNo, value);
 }
 public void setValue(String sheetName, int rowNo, int cellNo, Object value) {
  Sheet sheet = workbook.getSheet(sheetName);
  setValue(sheet, rowNo, cellNo, value);
 }
 public void setValue(Sheet sheet, int rowNo, int cellNo,  Object value) {
  
  Row row = sheet.getRow(rowNo);
  if(row==null){
   row = sheet.createRow(rowNo);
  }
  Cell cell = row.getCell(cellNo);
  if(cell==null){
   cell = row.createCell(cellNo);
  }
  writeToCell(cell,value);
  
 }
  void closeReading() {
  try {
   workbook.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
 }
 public void createSheet(String sheetName) {
  Sheet sheet = workbook.getSheet(sheetName);
  if(sheet==null){
   workbook.createSheet(sheetName);
   int index = workbook.getSheetIndex(sheetName);
   workbook.setActiveSheet(index);
  }
 }
 public void write2DData(Object[][] data, int startRowIndex, int startColIndex) {
  
  Sheet sheet = activeSheet();
  for (int i = 0; i < data.length; i++) { // iterate over rows (i is row offset counter)
   Row row = sheet.getRow(startRowIndex+i);
   if(row==null){
    row = sheet.createRow(startRowIndex+i);
   }
   writeToRow(row,data[i],startColIndex);
  }
 }
 private void writeToRow(Row row, Object[] data, int startCellNo) {
  for (int j = 0; j < data.length; j++) { // iterate over columns, j is column offset index
   Cell cell = row.getCell(startCellNo+j);
   if(cell == null){
    cell = row.createCell(startCellNo+j);
   }
   writeToCell(cell,data[j]);
  }
 }
 private void writeToCell(Cell cell, Object valueObject) { 
  if(valueObject instanceof String) {
   cell.setCellValue((String)valueObject);
  }
  else if(valueObject instanceof Integer || valueObject instanceof Double || valueObject instanceof Float || valueObject instanceof Long){
   
   Double doubleValue = Double.parseDouble(valueObject.toString());
   cell.setCellValue(doubleValue);
  }else if(valueObject instanceof Boolean){
   cell.setCellValue((Boolean) valueObject);
  }else if(valueObject instanceof Date){
   cell.setCellValue((Date)valueObject);
  }else if(valueObject instanceof Calendar){
   cell.setCellValue((Calendar)valueObject);
  } 
 }
}

Mobile Device - Perform Swipe / Scroll

Example : How to perform Swipe screen using Appium for Mobile device.


package com.vikas.automation.example;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.Test;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;

public class AndroidLinkedInTest {

 @Test
 public void testMobileSwipe() throws MalformedURLException {

  URL appiumUrl = new URL("http://127.0.0.1:4723/wd/hub");
  DesiredCapabilities caps = new DesiredCapabilities();
  caps.setCapability(MobileCapabilityType.APP,
    "C:\\Users\\vikas\\O2\\apps\\BookMyShow_5.3.0.apk");
  caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "android");
  caps.setCapability(MobileCapabilityType.DEVICE_NAME, "OnePlus3T");
  caps.setCapability(MobileCapabilityType.NO_RESET, true);
  caps.setCapability(MobileCapabilityType.FULL_RESET, false);
  //caps.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "");
  caps.setCapability(AndroidMobileCapabilityType.APP_WAIT_ACTIVITY, "*");
  AppiumDriver<WebElement> driver = new AndroidDriver<WebElement>(appiumUrl, caps);
  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

  //swipeUp(driver);
  swipeToRight(driver);
  System.out.println("Swipe completed");
  
  driver.quit();
 }

 private void swipeUp(AppiumDriver<WebElement> driver) {

  System.out.println(driver.manage().window().getSize());
  TouchAction action = new TouchAction(driver);
  // Just for beginning and manking it simple lets hardcode the x and y 
  int startX = 540;
  int startY = 1680;
  int endX = 540;
  int endY = 240;
  // Only need to give start and end point, No need of offset
  action.press(startX, startY).waitAction(Duration.ofMillis(500)).moveTo(endX,endY).release().perform();
  
 }
 private void swipeToRight(AppiumDriver<WebElement> driver) {

  // Take dynamic X and Y coordinates , below code should support devices with diffrent screen sizes
  Dimension d =driver.manage().window().getSize();
  int y = d.height/2;
  int endX = d.width/4;
  int startX = endX * 3;
  TouchAction action = new TouchAction(driver);  
  action.press(startX, y).waitAction(Duration.ofMillis(500)).moveTo(endX,y).release().perform();
 }
}

Friday, August 18, 2017

Customizing ExtentReport : Adding External Link

Extent Report  (http://extentreports.com/) is undoubtedly a great Reporting Library for any test automation framework.

Below is one example of how to customize ExtentReport for your project need.

The example will guide you on How to add a Hyperlink into HTML report.



Step 1: Create your own class as below

import com.aventstack.extentreports.markuputils.Markup;

/**
 * Class that represents Hyperlink
 */
class ExtentLink implements Markup {
private String linkUrl;
public String getLinkUrl() {
return this.linkUrl;
}
public void setLinkUrl(String linkUrl) {
this.linkUrl = linkUrl;
}
public String getLinkText() {
return this.linkText;
}
public void setLinkText(String linkText) {
this.linkText = linkText;
}
private String linkText;
@Override
public String getMarkup() {
                final String htmlTag = "+this.linkText+";
                return htmlTag;
}
@Override
public String toString() {
return this.linkText;
}

}

*Target is specified as _blank so the link will open in new window. You you wants to open in same window then remove target='_blank'

Step 2: Create object of ExtentLink and add it to Extent Log as below

ExtentReports extent = new ExtentReports();
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter("extent.html");
extent.attachReporter(htmlReporter);
//start of test case
ExtentTest test = extent.createTest("TestName");
//....
//Add a link in test report
final ExtentLink link = new ExtentLink();
link.setLinkText("Link Text goes here");
link.setLinkUrl("http://somedomain.com");
test.log(Status.INFO, link);
//...
//..
// Now Save report
extent.flush();


Thats All you need!!

Conclusion:
You can easily customize ExtentReport by adding any  HTML object like Links, Label, Tables, Image with the help of "Markup" class.

Sunday, May 14, 2017

Tutorial : Setting up Selenium GRID in LAN

Trying to learn and set up selenium GRID in local network? Here is the simple tutorial to start with.

Selenium GRID - components

  1. Selenium GRID Hub
  2. Selenium GRID Node

Step 1: Start Selenium GRID HUB Server 

java  -jar selenium-server-standalone-3.3.1.jar -role hub

After running this command you will a message as  below

16:55:49.766 INFO - Selenium Grid hub is up and running
17:16:34.636 INFO - Nodes should register to http://192.168.0.128:4444/grid/register/

Step 2: Start Selenium GRID NODE

2.1 Go to node machine & node configuration file with below JSON

FileName: nodeConfiguration.json


   "capabilities":[ 
      { 
         "browserName":"chrome",
         "maxInstances":10,
         "platform":"WIN8",
         "version":"58",
         "seleniumProtocol":"WebDriver"
      },
      {
         "browserName":"firefox",
         "maxInstances":3,
         "platform":"WIN8",
         "version":"53",
         "seleniumProtocol":"WebDriver"
      }
   ],
   "debug":false,
   "proxy":"org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
   "register":true,
   "registerCycle":5000,
   "maxSession":6
}

 2.2 Execute below command to start node and connect to hub

java -Dwebdriver.chrome.driver=C:\Users\vikas\selenium_drivers\chromedriver.exe -Dwebdriver.gecko.driver=c:\geckodriver.exe -jar selenium-server-standalone-3.3.1.jar -role node -nodeConfig nodeConfigFile.json -hub http://192.168.0.128:4444/grid/register

Step 3: Confirm Node is connected and hub is running by opening below url in browser

http://192.168.0.128:4444/grid/console

Step 4: Run Test case from eclipse. below is the sample code.

package com.vikas.samples;

import java.net.MalformedURLException;
import java.net.URL;

import org.apache.tools.ant.taskdefs.XSLTProcess.TraceConfiguration;
import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.vikas.framework.core.Browser;

public class GridExecutionDemo {

    @Test(dataProvider = "multipleTests")
    public void testOnRemmoteChromeBrowser(int testNumber, String browserName) throws MalformedURLException {
      
        // WebDriver driver = new ChromeDriver();
        System.out.println("Starting test :" + testNumber);
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setBrowserName(browserName);
        caps.setPlatform(Platform.WIN8);
        // OR caps.setCapability("browserName", "chrome");
        URL hubUrl = new URL("http://192.168.0.128:4444/wd/hub");

        WebDriver driver = new RemoteWebDriver(hubUrl, caps);
        driver.get("http://google.com");
        driver.findElement(By.name("q")).sendKeys("Vikas Thange Selenium");

        driver.quit();
    }

    @DataProvider(parallel = true)
    public Object[][] multipleTests() {
        return new Object[][] { { 1, "firefox"}, { 2, "chrome" } };
    }
}