Monday 31 March 2014

Xpath | Selenium Uses - Part II


Note|  Text in Blue [#PYTHON] and Orange [#JAVA] can be edited or mentioned important for the entire blog. All the posts are practically done by me.


XPath Axes

XPath Axes lets you navigate and provide direction within the tree representation of the XML document.

The location path can be either
     1| Absolute location path
         - Starts with (/)
         e.g., /step/step/..
     2| Relative location path
         - Does not starts with (/)
         e.g., step/step/..

Here, each and every step consists of
 1| axis
 2| node-test
 3| zero or predicates

axisname::nodetest[predicate]


     Axis name
            ancestor
            ancestor-or-self
            attribute (@)
            child (/)
            descendant (//)
            descendant-or-self
            following
            following-sibling
            namespace
            parent(../)
            preceding
            preceding-sibling
            self (./)


The Xpath Axes mentioned below are based on the following URL, http://docs.python.org/2/library/re.html


    ancestor

     Ancestor lets you select any ancestors [e.g., Parent and Grandparent] of the current node.
     //*[@id='regular-expression-syntax']/ancestor::div[5]/div[2]
     //*[@id='regular-expression-syntax']/ancestor::*

    ancestor-or-self

     Ancestor-or-self lets you select any ancestors [e.g., Parent and Grandparent] of the current                      node including the current node.
     //*[@id='regular-expression-syntax']/ancestor-or-self::div[1]
     //*[@id='regular-expression-syntax']/ancestor-or-self::*

    attribute

     Attribute returns all the attributes in the current node.
     //*[@class='sphinxsidebarwrapper']/attribute::*
     //*[@id='sidebarbutton']/attribute::title

    child

     Child returns all the children in the current node.
     //*[@class='sphinxsidebarwrapper']/child::*
     //*//child::h3

    descendant

     Descendant lets you select all descendants [e.g., Children and Grandchildren] of the current node.
     //*[@class='this-page-menu']/descendant::*
     //*[@class='this-page-menu']/descendant::li[2]
     //*[@class='documentwrapper']/descendant::div[position()=3]

    descendant-or-self

     Descendant-or-self lets you select all descendants [e.g., Children and Grandchildren] of the current       node including the current node.
     //*[@class='this-page-menu']/descendant-or-self::*
     //*[@id='searchbox']/descendant-or-self::form[@class='search']/input[2]

    following

     Following returns all in the document after the closing tag of the current node.
     //*[@class='clearer']/following::*

    following-sibling

     Following-sibling returns all the sibling after the closing tag of the current node.
     //*[@class='related']/following-sibling::*
     //*[@class='related']/following-sibling::div[3]


    namespace

     Namespace returns all namespace nodes in the current node.
     TBD

    parent

     Parent returns the parent of the current node.
     //*[@class='sphinxsidebar']/parent::node()
     //*[@class='bodywrapper']/parent::*
     //*[@class='bodywrapper']/parent::div[1]
     //*[@class='bodywrapper']/parent::div

    preceding

     Preceding is a reverse of Following;  Preceding returns all in the document before the current node
     //*[@class='bodywrapper']/preceding::*

    preceding-sibling

     Preceding-sibling is a reverse of Following-sibling;  Preceding-sibling returns all the sibling before        the current node.
     //*[@class='footer']/preceding-sibling::*
     //*[@class='footer']/preceding-sibling::div[2]

    self

     Self returns the current node.
     //*[@class='footer']/self::*
     //*[@class='footer']/self::div


Note| Refer URL for more details

Friday 28 March 2014

Xpath | Selenium Uses - Part I



XPath, XML Path Language is a W3C standard that is used to navigate through elements and attributes in an XML document.


XPath Functions


     1| Conversion
               boolean( [object] )
               string( [object] )
               number( [object] )

     2| Math
               ceiling( number ) 
               floor( number )
               round( decimal )
               sum( node-set )

     3| Logic
               true()
               false()
               not( expr )

     4| Node
               lang(string)
               name([node-set])
               namespace-uri([node-set])

     5| Context
               count(node-set)
               last()
               position()

     6| String
               contains( haystack-string needle-string )
               concat( string1 string2 [stringn]* )
               normalize-space( string )
               starts-with(haystack needle) 
               string-length( [string] )
               substring(string start [length]) 
               substring-after(haystack needle) 
               substring-before(haystack needle)
               translate( string abc XYZ)


Both the Xpath Context and Xpath String are used for locating elements and does various functions on Selenium. The Functions mentioned below are based on the following URL, http://docs.python.org/2/library/re.html

Note|
For normalize-space() use the following link http://www.bing.com/search?q=asd+++asd&go=&qs=n&form=QBRE&filt=all&pq=asd+asd&sc=8-7&sp=-1&sk=


XPath Context


    count()

    //span[count(*)]
    //p[count(tt)]
    //*[count(*)]
    //dl[count(dt)]
    //div[count(dl)]
    /* all tables with 1 row and 2 cols e.g., //table[count(tr)=1 and count(tr/td)=2] */
    //div[count(dl)=1 and count(dl/dd)=1]

    last()

    //div[@id='module-contents']/dl[@class='function'][last()]
    //div[@id='module-contents']/dl[@class='function'][last()-1]

    position()

    //div[@id='module-contents']/dl[@class='function'][position()=4]    
    //div[@class='button' and position()=2]     Link
    //div[@class='button'][position()=2]



XPath String


    contains()

    //div[contains(@id,'module')]
    //*[@id='regular-expression-syntax']//h2[contains(text(), '7.2.1. Regular Expression Syntax')]

    concat()

    concat(//*[@id='checking-for-a-pair']/h3/text(), //*[@id='simulating-scanf']/h3/text())

    normalize-space()

    //*[@id='sb_form_q'][normalize-space(@value)='asd asd']    

    starts-with()

    //div[starts-with(@id,'module')]


    string-length()

     The string-length returns the number of characters in the string
     string-length(//*[@id='regular-expression-syntax']/h2/text())

    substring()

     substring(//*[@id='regular-expression-syntax']/h2/text(), 2, 30)

    substring-after()

    //div[substring-after(@id,'finding-')]
    //*[starts-with(@id,'finding') and substring-after(@id,'finding-all-adverbs-')]

    substring-before()

    //div[substring-before(@id,'objects')]

    translate()

    //*[@id='raw-string-notation']/h3[contains(translate(., '7.2.5.8. Raw String Notation', '7.2.5.8. RAW STRING NOTATION'), '7.2.5.8. RAW STRING NOTATION')]
    //*[@id='raw-string-notation']/h3[contains(translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), '7.2.5.8. RAW STRING NOTATION')]

Friday 21 March 2014

Page Object Pattern | Selenium - Part II


Note|  Text in Blue [#PYTHON] and Orange [#JAVA] can be edited or mentioned important for the entire blog. All the posts are practically done by me.


PageFactory is used to support PageObject pattern with a Factory class inside the WebDriver's support library. NullPointerExceptions will be thrown if you are not using PageFactory.

In PageFactory, by default you don't need to specify the Locator type for Name and ID;  Instead initialize the weblements using the below simple format.

private WebElement gbqfq; // here, 'gbqfq' is a name
private WebElement q; // here, 'q' is an id

gbqfq.sendKeys("Prashanth Sams");
or|
q.sendKeys("Prashanth Sams");


Lets see with an example,

Google TC | GoogleTest.java


package packagename;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class GoogleTest {
private WebDriver driver; 

@BeforeTest
public void setUp() throws Exception {
 driver = new FirefoxDriver();  
}
    
 @Test
 public void Test01() throws Exception{
             GoogleSearch page = PageFactory.initElements(driver, GoogleSearch.class);
             page.searchFor("Prashanth Sams");
    }
 
@AfterTest
public void Teardown() throws Exception{
driver.quit();
}



Google Search | GoogleSearch.java


package packagename;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class GoogleSearch {

    private WebElement q; // Here's the Element
    public WebDriver driver; 
    
    public GoogleSearch(WebDriver driver) {
this.driver = driver;
driver.get("http://www.google.com/");
}

    public void searchFor(String text) {        
        q.sendKeys(text);
        q.submit();
    }


Working with Annotation | @FindBy

@FindBy and @FindBys lets you find elements using the locators. @FindBys plays a major role in finding elements.

Google Search | GoogleSearch.java

#USING @FindBy

package packagename;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;

public class GoogleSearch {

 @FindBy(how = How.NAME, using = "q") // or use @FindBy(name = "q")
 @CacheLookup // keeps the element in cache for rapid execution
 private WebElement searchme;

 @FindBy(id = "gbqfq") // Less Verbose
 private WebElement submitme;
//Here, both searchme & submitme refers to the same element
    
public WebDriver driver; 
    
  public GoogleSearch(WebDriver driver) {
this.driver = driver;
driver.get("http://www.google.com/");
}

   public void searchFor(String text) {        
    searchme.sendKeys(text);
    submitme.submit();
   }




#USING @FindBys

package packagename;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;

public class GoogleSearch {
   
    @FindBys({@FindBy(id = "gs_lc0"), @FindBy(name = "q")})
    @CacheLookup // keeps the element in cache for rapid execution
private WebElement searchme;

public WebDriver driver; 
    
    public GoogleSearch(WebDriver driver) {
this.driver = driver;
driver.get("http://www.google.com/");
}

    public void searchFor(String text) {        
    searchme.sendKeys(text);
    searchme.submit();    
    }

Thursday 20 March 2014

Page Object Pattern | Selenium - Part I


Page Object Pattern is a good approach of implementing Automation tests. It is a language neutral pattern for representing a complete page or portion of a page in an Object Oriented manner. Pattern is a page object, which encapsulates the behavior of the page in an Object oriented manner. It need some programming skills too.

Why Page Object?

1| Maintenance
2| Readability of scripts
3| Separation of Concerns


Page Object Pattern | Page Factory

Lets start with an example using Google.com

SCENARIO 
1| Open URL
2| Search google
3| Assert page title



TEST CLASS | TC.java


package packagename;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TC {
 private WebDriver driver;
 public ASSERT Task; 

  @BeforeTest
 public void setUp() throws Exception {
  System.out.println("Instantiating Firefox Driver");
  driver = new FirefoxDriver();
 }

  @Test
 public void Test01() throws Exception {
  URL url = PageFactory.initElements(driver,
    URL.class);
  url.geturl();
  
 }

  @Test
 public void Test02() throws Exception {
  Task = PageFactory.initElements(driver,
    ASSERT.class);
  Task.search();  
  
  }

  @Test
 public void Test03() throws Exception {  
  Task = PageFactory.initElements(driver,
    ASSERT.class);  
  Task.assertsearch();

  }
  
  @AfterTest
 public void tearDown() throws Exception {
  driver.quit();
 }

}



Open Google | URL.java


package packagename;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.WebDriverWait;

public class URL{
public WebDriver driver;
private String baseUrl;
private boolean acceptNextAlert = true;
private StringBuffer verificationErrors = new StringBuffer();

public URL(WebDriver driver) {
this.driver = driver;
driver.get("http://www.google.co.in");
}

public ASSERT geturl() {  
System.out.println("URL opened successfully");
return PageFactory.initElements(driver, ASSERT.class);
}


}



Search & Assert | last.java


package packagename;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;

public class ASSERT {

public WebDriver driver;

public ASSERT(WebDriver driver) {
this.driver = driver;
  //driver.get("https://seleniumworkz.wordpress.com/wp-admin/edit.php");
}
 
public void search() throws Exception{
//  search google
driver.findElement(By.name("q")).sendKeys("Prashanth Sams");
driver.findElement(By.name("q")).submit();
Thread.sleep(4000);
}

public void assertsearch() throws Exception{
//  assert google search
Boolean b = driver.getTitle().contains("Prashanth Sams");
System.out.println(b);
}
}

Saturday 8 March 2014

Run tests on specific Firefox version | Selenium



Firefox binary lets you run tests on your favorite Firefox versions. Follow the steps below:

1| Install multiple versions of Firefox in your PC.
2| Make sure the installed Firefox versions on different path locations using Custom installation


import java.io.File;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

private WebDriver driver;

FirefoxBinary binary = new FirefoxBinary(new File("C://Program Files//Mozilla Firefox26//firefox.exe"));
FirefoxProfile profile = new FirefoxProfile();  
driver = new FirefoxDriver(binary, profile);



#PYTHON

from selenium.webdriver.firefox.firefox_binary import FirefoxBinary

driver = webdriver.Firefox(firefox_binary=FirefoxBinary("C://Program Files//Mozilla Firefox26//firefox.exe"))

Friday 7 March 2014

Implicit and Explicit Waits


Explicit Wait is related with certain conditions to wait; Implicit Wait with specific time to wait for an Element.


Explicit Wait

Here, the driver waits for 10 secs till the web element is found;  If not, it simply throws a Timeout Exception.

WebElement element = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.presenceOfElementLocated(By.id("Value")));

or|

WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("Value")));


WebDriverWait can't be declared globally and throw NullPointerException; whereas the below snippets will help you to do so.


// Handles any locator
@Test
public void Test01() throws Exception {
  driver.get("www.xyz.com");
  wait().until(ExpectedConditions.presenceOfElementLocated(By.xpath("Value")));
  }

private WebDriverWait wait()
   {
    return new WebDriverWait(driver, 20);
   }


// Handles any locator [This method works for page object pattern]
private WebDriver driver;
private final Wait<WebDriver> wait;

public Classname(WebDriver driver) { //constructor
   this.driver = driver;
   wait = new WebDriverWait(driver, 20);
 }

@Test
public void Test01() throws Exception {
  driver.get("www.xyz.com");
  wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("Value")));
  }


// Handle the locators by id, name, xpath, css, etc.,
@Test
public void Test02() throws Exception {
  driver.get("www.xyz.com");
  waitForID("Value");
   }

public void waitForID(String id) 
   {         
    WebDriverWait wait = new WebDriverWait(driver, 10);      
    wait.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));      
   }


In Java, Expected Conditions include:
























#PYTHON
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

try:
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "Value")))
except:
    print "Element is not present"
    self.fail()

print "Element is present"

or|

wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID,"Value")))


Following link has entire Python Expected conditions:
http://selenium.googlecode.com/git/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


Fluent Wait

WebDriverWait is an extension of FluentWait. Fluent wait uses a Polling Technique;  i.e, It will be keep on Polling every Fixed interval for a particular Element.


import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.google.common.base.Function;

@Test
public void Test02() throws Exception {
  driver.get("www.xyz.com");
  fluentWait(By.id("Value"));
   }

public WebElement fluentWait(final By locator) {
   FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
           .withTimeout(10, TimeUnit.SECONDS)
           .pollingEvery(2, TimeUnit.SECONDS)
           .ignoring(NoSuchElementException.class);

   WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
       public WebElement apply(WebDriver driver) {
           return driver.findElement(locator);
       }
   });

   return  foo;
};


Thread.sleep()

Thread.sleep() is not an ideal approach on handling Wait. The worst case of Explicit wait is Thread.sleep().

Thread.sleep(3000); // waits for 3 secs

#PYTHON
import time
time.sleep(3// waits for 3 secs

#RUBY
sleep 5 # wait for 5 secs
sleep(1.minutes)
sleep(2.hours)
sleep(3.days)



Implicit Wait

Every timeout depends upon Implicit Wait;  From the start till end, it acts as a master wait.  However, the explicit waits are highly recommended for its ease of use.

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);


#PYTHON
self.driver.implicitly_wait(30)

#RUBY
@driver.manage.timeouts.implicit_wait = 30

Monday 3 March 2014

Getting started with Python | Unittest | Selenium Users

This post lets you learn the basic Python scripting using Unittest framework for Automation testing.





Create a Test_class

1| Create a module with Test_class named, "cool"
2| Now, import a class named, "Calc" from another module
3| To create a method and class from main Test_class, press "Ctrl + 1"

import unittest
from pack.calculator import Calc

class cool(unittest.TestCase):
    def test_add(self):
        calc = Calc()
        Result = calc.add(a = 4, b = 3)
        self.assertEqual(Result, 7, "Test Failed")
        print "Test PASSED"


4| Create a method, "add" in the sub_class

class Calc(object):
        
    def add(self, a, b):
        return a + b
    


5| To execute the test, press "Ctrl + F9"

Sunday 2 March 2014

Run cross browser tests | Selenium | Python | Ruby


Note|  Text in Blue [#PYTHON] and RED [#RUBY] can be edited or mentioned important for the entire blog. All the posts are practically done by me.

1| Download Chromedriver 2.9IEDriverserver, and phantomjs
2| Extract the zipped folders and locate them in code [highlighted in #blue].


Chrome

import os

from selenium import webdriver

chromedriver = "C://Test//chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
self.driver = webdriver.Chrome(chromedriver)

self.driver.get("http://python.org/")

or|

self.driver = webdriver.Chrome("C://Test//chromedriver.exe")


Internet Explorer

self.driver = webdriver.Ie("C://IEDriverServer.exe")
self.driver.get("http://python.org/")


Firefox

self.driver = webdriver.Firefox()

self.driver.get("http://python.org/")


PhantomJS

self.driver = webdriver.PhantomJS("
C://phantomjs.exe")
self.driver.get("http://python.org/")

or|

1| Open cmd prompt
2| Locate the folder C:\Python27\Scripts in cmd and enter
brew install phantomjs

self.driver = webdriver.PhantomJS()
self.driver.get("http://python.org/")




1| Download Chromedriver 2.9 and IEDriverserver
2| Extract the zipped folders and add them in Environment Variables path.
My Computer > (right click) properties > Advanced system settings > Environment Variables
3| Click path under system variables and choose Edit.
4| Paste the Driver locations.



Chrome

require "selenium-webdriver"
@driver = Selenium::WebDriver.for :chrome



Internet Explorer

@driver = Selenium::WebDriver.for :ie
OR|
@driver = Selenium::WebDriver.for :internet_explorer


Firefox

@driver = Selenium::WebDriver.for :firefox



Note:- 
1| 'brew' doesn't work on Windows