Friday, May 08, 2015

Dealing with <object> tags in selenium webdriver

Many web pages uses <object> tags for embedded object within an HTML document. This element is mainly used to embed SVG elements, multimedia, Java applets, Flash etc.
Many web pages also use the <object> tag to embed another webpage or frames into the HTML document.

Though <object> tags looks slimilar to <iframe>, it won't work if you do switch frame by webdriver (e.g. driver.switchTo().frame(objIDorIndex);)

Here are few scenarios that you can handle using selenium webdriver with javascript/jQuery.

Example - 1: 
widthmm=90.48768097536195 heightmm=49.38127063754128 ... ...
Example - 2: 

Content HTML Viewer
(Case 1) In example-1, if you want to click on a "g" elements of SVG element
WebElement objectTag= findElement(By.xpath("//div[@id='imageholder']//object"));
((JavascriptExecutor) driver).executeScript("return (arguments[0].contentDocument.getElementsByTagName('g')[0]).click()", objectTag);
(Case 2) In example-2, if you want to get the title for assertion, then try as an example given below
List<WebElement> objects = findElements(By.xpath("//div[@class='contentViewer']//object"));
String objectId = objects.get(0).getAttribute("id");
WebDriver driver = getDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
String text = (String) js.executeScript("return (((document.getElementById('" + objectId + "')).contentDocument).getElementsByClassName('titleText')[0]).innerHTML");
getDriver().switchTo().defaultContent();
(Case 3) In example-2, if you want to get any specific attribute, then try something like below
List<WebElement> objects = findElements(By.xpath("//div[@class='contentViewer']//object"));
String objectId = objects.get(0).getAttribute("id");
WebElement objectTag = findElement(By.id(objectId));
String btnTitle = ((JavascriptExecutor) driver).executeScript("return arguments[0].contentDocument.getElementById('closeText').getAttribute('title')", objectTag).toString();
Assert.assertEquals(btnTitle, "Cancel to close");
(Case 4) In example-2, if you want to do any action inside the iFrame, you can use as below given example
WebElement btnDone = (WebElement) js.executeScript("return ((((document.getElementById('" + objectId
            + "')).contentDocument).getElementsByTagName('iFrame')[0]).getElementById('done'))");
btnDone.click();
Note: I have just gave few examples actions w.r.t my example html code snippet. By referring the above examples you do actions inside <object> tag as per your requirements

Sunday, May 03, 2015

Scroll pages in Selenium Webdriver

Most of the cases Selenium automatically calls the javascript "scrollIntoView" function on any element that you try to interact with. If you know an element exists at the bottom of the page then doing anything with that element (including getting an attribute or hovering over it, etc) will cause the page to scroll.

If the above doesn't work, please do either of the followings:

Scroll to a WebElement:
WebElement element = driver.findElement(By.id("navPanel"));
JavascriptExecutor jsexecutor = (JavascriptExecutor) driver;
jsexecutor.executeScript("arguments[0].scrollIntoView();", element);
(Or)
WebElement element = driver.findElement(By.id("navPanel"));
Coordinates coordinate = ((Locatable) element).getCoordinates();
coordinate.onPage();
coordinate.inViewPort();
(Or)
Point point = element.getLocation();
((JavascriptExecutor) driver).executeScript("return window.title;");
Thread.sleep(6000);
((JavascriptExecutor) driver).executeScript("window.scrollBy(0," + (point.getY()) + ");");

Scroll up the web page:
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("scroll(300, 0)"); 
// here x value(horizontal value)'300' can be changed as needed
Scroll down the web page:
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("scroll(0, 300)"); 
// here y value(vertical value) '300' can be changed as needed
Scroll to end/bottom of page:
Actions actions = new Actions(driver);
actions.keyDown(Keys.CONTROL).sendKeys(Keys.END).perform();
(Or)
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;  
jsExecutor.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));");
(Or)
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
for (int second = 0;; second++) {
  if(second >=60){
    break;
  }
  jsExecutor.executeScript("window.scrollBy(0,750)", ""); 
  Thread.sleep(3000);
}
//y value(vertical length) '750' can be changed as needed

Wednesday, August 20, 2014

Data driven testing in Selenium WebDriver with TestNG using Excel

When we want to implement data driven testing using Excel, you need to understand how to read from an Excel sheet. You can read an Excel sheet by using Apache POI. 

You need to use the below jars for reading from an excel file. 
  1. poi-3.7-20101029.jar
  2. poi-ooxml-3.7-20101029.jar
  3. poi-ooxml-schemas-3.7-20101029.jar
  4. xmlbeans-2.3.0.jar
  5. dom4j-1.6.1.jar
I am using Apache POI 3.7 but you can download the latest jars from downloads page of Apache POI(http://poi.apache.org/download.html). Make sure you have added all the above jars to your project build path.

An example excel file(either .xslx or .xls formats) is given below:



The below self explanatory class is used for reading any cell of an excel sheet.
//Keywords class DataDrivenExcel.java
package example.aks.data.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * This class allows us the use of an Excel spreadsheet to provide input data to
 * a test or set of tests.
 * 
 * @author A. K. Sahu
 * 
 */

public class DataDrivenExcel {

 private Workbook wb;
 private Sheet ws;

 /**
  * Opens a excel sheet
  * 
  * @param fileName
  *            name of the file where you want data
  * @param sheetName
  *            name of the sheet in the excel file
  */
 public DataDrivenExcel(String fileName, String sheetName) {
  try {
   if (fileName.indexOf("xlsx") < 0) { //for .xls format
    wb = new HSSFWorkbook(new FileInputStream(new File(fileName)));
    ws = wb.getSheet(sheetName);
   } else { //for .xlsx format
    wb = new XSSFWorkbook(fileName);
    ws = (XSSFSheet) wb.getSheet(sheetName);
   }
  } catch (IOException io) {
   System.err.println("Invalid file '" + fileName
     + "' or incorrect sheet '" + sheetName
     + "', enter a valid one");
  }
 }

 /**
  * Gets a cell value from the opened sheet
  * 
  * @param rowIndex
  *            starting with 0 index
  * @param columnIndex
  *            starting with 0 index
  * @return
  */
 public String getCell(int rowIndex, int columnIndex) {
  Cell cell = null;
  try {
    cell = ws.getRow(rowIndex).getCell(columnIndex);
  } catch (Exception e) {
   System.err.println("The cell with row '" + rowIndex + "' and column '"
     + columnIndex + "' doesn't exist in the sheet");
  }
  return new DataFormatter().formatCellValue(cell);
 }
}
The test class that uses the above keywords of the DataDrivenExcel class looks like below which is also self explanatory.
//Usage in the TestNG test class DataDrivenTest.java
package example.aks.data.test;

import java.util.ArrayList;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import example.aks.data.util.DataDrivenExcel;

/**
 * This class explains the usage of data driven excel
 * 
 * @author A. K. Sahu
 * 
 */
public class DataDrivenTest {

 @DataProvider(name = "loginToAppWithAllRoles")
 public Object[][] getLoginDataForAllRoles() throws Exception {

  DataDrivenExcel userData = new DataDrivenExcel(
    "D:/workspace/DataDriven/data/SampleExcel.xlsx", "Sheet1");

  ArrayList<Object> dataList = new ArrayList<Object>();

  int i = 1;// excluding header row
  int totalRows = 6;
  while (i < totalRows) {
   System.out.println("loginToAppWithAllRoles : line : " + i);

   Object[] dataLine = new Object[4];
   dataLine[0] = userData.getCell(i, 0);
   dataLine[1] = userData.getCell(i, 1);
   dataLine[2] = userData.getCell(i, 2);
   dataLine[3] = userData.getCell(i, 3);

   dataList.add(dataLine);

   i++;
  }

  Object[][] data = new Object[dataList.size()][];
  for (i = 0; i < dataList.size(); i++)
   data[i] = dataList.get(i);

  return data;
 }

 @Test(dataProvider = "loginToAppWithAllRoles", 
       description = "Login with different roles")
 public void testLogin(String userID, String username, String password,
   String role) {

  WebDriver driver = new FirefoxDriver();

  driver.get("http://yoursiteurl.com");

  // Do required actions using the input data, i am just printing here
  System.out.println("userID:" + userID);
  System.out.println("username:" + username);
  System.out.println("password:" + password);
  System.out.println("role:" + role);

  driver.quit();
 }
}
Similarly, you can use an excel file with .xls format.
Important Note: 
In the above test class we used
Object[] dataLine = new Object[4];
Number here should match with the number of parameters for the test case that using this dataprovider.

The  output after executing the tests looks like below:
TestNG Console

Console output

Note: While you are running the tests if you encounter any problem recheck about the below:
  1. Make sure all the above mentioned jars are added to your build path.
  2. The object size defined in the data provider is equal to the number of parameters defined in the test method.
  3. You are reading an existing cell value with a valid row and column index.

Thursday, June 26, 2014

Page Refresh in Selenium WebDriver

There are many ways that we can refresh a web page in Selenium Webdriver tests. Here are listed some of them: 
1) Using refresh() method of WebDriver
driver.navigate().refresh();
This is most commonly used method. 
2) Using F5 key
driver.findElement(By.name("q")).sendKeys(Keys.F5);
This is also commonly used method. We must use it in any text field of the web page as it uses Send keys method. 
3) Using Actions class of WebDriver
Actions actions = new Actions(driver);
actions.keyDown(Keys.CONTROL).sendKeys(Keys.F5).perform();
4) Using jQuery
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("history.go(0)");
5) Using navigate( ).to( ) method of WebDriver
driver.navigate().to(driver.getCurrentUrl());
6) Using ASCII code
driver.findElement(By.name("q")).sendKeys("\uE035");

Navigate Back, Forward and to an Url in Selenium Webdriver

Below scenarios explains how we can navigate across the browser for various web pages.
WebDriver driver = new FirefoxDriver();
driver.get("http://aksahu.blogspot.in/");

Navigate to an Url:
driver.navigate().to("http://knowledgebase-wiki.appspot.com/");
This navigates the page to "http://knowledgebase-wiki.appspot.com/"

Navigate Back:
driver.navigate().back();
This navigates back to the previous page "http://aksahu.blogspot.in/"

Navigate Forward:
driver.navigate().forward();
This navigates the page forward to "http://knowledgebase-wiki.appspot.com/"