Thursday 15 May 2014

Cucumber BDD framework with Selenium WebDriver


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.


Cucumber BDD Framework | selenium


1| Add an Eclipse plugin, Cucumber Eclipse feature using the below URL,
http://cucumber.github.com/cucumber-eclipse/update-site
2| Help > install new software... > paste the above url in work with text field and press enter key.
3| After the installation is done, restart Eclipse IDE.



4| Create a Maven project and add the following dependencies in POM.xml file

<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>BDD</groupId>
  <artifactId>Cucumber</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Cucumber</name>
  <url>http://maven.apache.org</url>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

      <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12.2</version>
                <configuration>                
                    <useFile>false</useFile>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
      
 <dependencies>

   <dependency>
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId>
     <version>4.11</version>
     <scope>test</scope>
   </dependency>    

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.41.0</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-core</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-html</artifactId>
<version>0.2.2</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>gherkin</artifactId>
<version>2.11.6</version>
</dependency>

<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>

<dependency>
<groupId>info.cukes</groupId>
<artifactId>gherkin</artifactId>
<version>2.11.6</version>
</dependency>

<dependency>
            <groupId>com.rubiconproject.oss</groupId>
            <artifactId>jchronic</artifactId>
            <version>0.2.6</version>
            <scope>test</scope>
        </dependency>
                    
  </dependencies>
</project>


5| Now, create a test run class file

package BDD.Cucumber;

import org.junit.runner.RunWith;

import cucumber.api.junit.Cucumber;


@RunWith(Cucumber.class)
@Cucumber.Options(format = {"pretty", "html:target/cucumber","json:target/cucumber.json"})
public class RunTest {

}


6| Now, create a test class file

package BDD.Cucumber;

import static org.junit.Assert.assertEquals;

import java.util.concurrent.TimeUnit;

import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import cucumber.api.Scenario;
import cucumber.api.java.After;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;



public class Googlesearch {

public WebDriver driver = new FirefoxDriver();

@Given("^Google page \"([^\"]*)\"$")
public void i_open_google_page_as(String URL) throws Throwable {
driver.get(URL);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

}


@When("^I enter \"([^\"]*)\" in search box$")
public void i_enter_in_search_box(String arg1) throws Throwable {
driver.findElement(By.name("q")).sendKeys(arg1);
}

@When("^I press enter key$")
public void i_press_enter_key() throws Throwable {
driver.findElement(By.name("q")).submit();

}

@Then("^I should get the results of \"([^\"]*)\"$")
public void i_should_see_results_of(String content) throws Throwable {

Thread.sleep(3000L);
boolean b = driver.getPageSource().contains(content);
Assert.assertTrue(b);
}

@After
public void after(Scenario scenario) {
driver.close();
}

}





7| Create a new source folder, "resources" under src/test/
8| Now, create a package, "BDD.Cucumber"
9| Then create a file with extension .feature
Right click BDD.Cucumber under src/test/resources > New > Other > File
10| Name the file with extension .feature; i.e., test.feature

Feature: test

@foo
Scenario: google search

Given Google page "http://www.google.com"
When I enter "Prashanth Sams" in search box
When I press enter key
Then I should get the results of "Prashanth Sams"


11| Right click on the project > Run As > maven clean
12| Again Right click on the project > Run As > maven install


Note: For more info. download my sample project from Github Link

Wednesday 7 May 2014

Selenium Data-driven Text file | @DataProvider


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.


This is the continuation of one my previous topics, #link.  In this method, we are using @dataProvider annotation on TestNG to fetch keywords from a Text file and passing the arguments to Test class. This is our (Prashanth Sams + Karthikeyan) implementation to work with Text file via dataprovider.


Text File | @DataProvider

The below example illustrates on how to work with @dataprovider in-order to fetch values from a text file.

1| Create a Test class file similar to the one given below:


package packagename;

import java.util.HashMap;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class Google {
    private WebDriver driver;

    @DataProvider(name="keywords")
    public Object[][] data() throws Exception {
        HashMap<String,String[]> dataSet= new Text2TestData(System.getProperty("user.dir")+"\\config.txt").getData();
        
        String search1Strings[]=dataSet.get("search1");
        String search2Strings[]=dataSet.get("search2");
        int size =search1Strings.length;
   
        // modify 2 upon the no. of rows; Here, I used two rows, 'search1' & 'search2'
        Object[][] creds = new Object[size][2];  
        for(int i=0;i<size;i++)
        {
            creds[i][0]=search1Strings[i];
            creds[i][1]=search2Strings[i];
        }
        return creds;
    }


    @BeforeTest
    public void setUp() throws Exception {
        driver = new ChromeDriver();

    }

    @Test(dataProvider = "keywords", description = "Google_Test")
    public void search(String search1, String search2) throws Exception {
   
        driver.get("http://www.google.co.in");

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search1);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search2);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

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

}



Text2TestData

2| Create another java class file, 'Text2TestData' under the same package.


package packagename;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

public class Text2TestData {

    private String fileLocation;

    public Text2TestData(String fileLocation) {
        this.fileLocation = fileLocation;
    }

    public HashMap<String,String[]> getData(){
        FileInputStream fs;
        HashMap<String,String[]> keyValuePair=new HashMap<String,String[]>();
        try (BufferedReader br = new BufferedReader(new FileReader(fileLocation))){
            String stringLine;
            //Read File Line By Line
            while ((stringLine = br.readLine()) != null)   {
                // Print the content on the console
                String[] keyValue=stringLine.split("=");
                keyValuePair.put(keyValue[0],keyValue[1].split(","));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return keyValuePair;
    }


}



3| Create a text data-source file similar to the contents given below separated with comma (,)

search1=Prashanth Sams,bypasshacker
search2=seleniumworks.com,bypasshacker.blogspot.com

4| Now, place the config.txt file inside your project
5| Save the file and run test :)

Selenium Data-driven Properties file | @DataProvider


This is the continuation of one my previous topics, #link.  In this method, we are using @dataProvider annotation on TestNG to fetch keywords from a Properties file and passing the arguments to Test class. This is my implementation to work with Properties file via dataprovider.


Properties File | @DataProvider

The below example illustrates on how to work with @dataprovider in-order to fetch values from a properties file.

1| Create a Test class file similar to the one given below:


package packagename;

import java.util.HashMap;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class Google {
    private WebDriver driver;

    @DataProvider(name="keywords")
    public Object[][] data() throws Exception {
        HashMap<String,String[]> dataSet= new properties2TestData().getData();
        
        String search1Strings[]=dataSet.get("search1");
        String search2Strings[]=dataSet.get("search2");
        int size =search1Strings.length;
   
        // modify 2 upon the no. of rows; Here, I used two rows, 'search1' & 'search2'
        Object[][] creds = new Object[size][2];  
        for(int i=0;i<size;i++)
        {
            creds[i][0]=search1Strings[i];
            creds[i][1]=search2Strings[i];
        }
        return creds;
    }


    @BeforeTest
    public void setUp() throws Exception {
        driver = new ChromeDriver();

    }

    @Test(dataProvider = "keywords", description = "Google_Test")
    public void search(String search1, String search2) throws Exception {
   
        driver.get("http://www.google.co.in");

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search1);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

        // search google via keyword 1
        driver.findElement(By.name("q")).clear();
        driver.findElement(By.name("q")).sendKeys("" + search2);
        driver.findElement(By.name("q")).submit();
        Thread.sleep(4000);

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

}



properties2TestData

2| Create another java class file, 'properties2TestData' under the same package.


package packagename;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.ResourceBundle;

public class properties2TestData {

    public properties2TestData() {
    }

    public HashMap<String,String[]> getData(){
    HashMap<String,String[]> configMap=new HashMap<String,String[]>();
    try{
    ResourceBundle bundle = ResourceBundle.getBundle("config");
        Enumeration<String> keys = bundle.getKeys();
        while(keys.hasMoreElements()){
        String aKey = keys.nextElement();
        String aValue = bundle.getString(aKey);
        configMap.put(aKey, aValue.split(","));
        }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return configMap;
    }

}



3| Create a properties data-source file similar to the contents given below separated with comma (,)

search1=Prashanth Sams,bypasshacker
search2=seleniumworks.com,bypasshacker.blogspot.com

4| Now, place config.properties file inside your project's Source folder[src]
5| Save the file and run test :)

Friday 25 April 2014

Getting started with Ruby | Selenium Users


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


Ruby Installation


In Windows, you can use either RubyInstaller or pik.

1| Download rubyinstaller
2| Check Ruby version
Start > Interactive Ruby
RUBY_VERSION



3| Install Selenium WebDriver library for Ruby
selenium-webdriver-2.41.0.gem
INSTALL > gem install selenium-webdriver



4| Download Devkit before installing json
5| Extract DevKit to path C:\Ruby200\DevKit
6| Open cmd prompt
> cd C:\Ruby200\DevKit
> ruby dk.rb init
> ruby dk.rb review
> ruby dk.rb install


INSTALL > gem install json



7| Download Ruby DLTK plugin for Eclipse IDE [Go to Eclipse Marketplace and search Ruby DLTK]



8| Go to Windows > Preferences > Ruby - Interpreters



9| Click on 'Add' and Locate Ruby.exe  "C:\Ruby200\bin\ruby.exe"



10| Create a New Ruby Project
Right click on package Explorer > New > others 

11| Type 'Ruby'.
12| Select 'Ruby Project' and press Finish.



13| Create a new Ruby module.
Right click on package > New > Ruby module

14| Develop your Ruby selenium script like sample given below

require "selenium-webdriver"

driver = Selenium::WebDriver.for :firefox
driver.navigate.to "http://google.com"

element = driver.find_element(:name, 'q')
element.send_keys "Prashanth Sams"
element.submit

driver.quit

15| Rick click on program Run > Ruby Script



Note| 
1| Rack is a web server interface used for developing web applications in Ruby; Rack is used by almost all Ruby web frameworks and libraries, such as Ruby On Rails and Sinatra.
2| RubyGems is a package manager for Ruby programming language.

Monday 7 April 2014

Handle Download popup using Firefox Browser Profile


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.


Firefox Browser Profile [Download Files]

This is the continuation of my previous topics, #link1 and #link2.  The simplest way to ignore Browser pop-up and save files is to make use of Browser profiles;  There are couple of ways to do this [can be done either manually or using scripts]

Advantages of using Browser Profile
    1| Skip download pop-up and save the files on specific folder
    2| No need of 3rd party tools like AutoIT or Java Robot



#Method1

Before you start working with pop-ups on Browser profiles, make sure that the Download options are set default to Save File.

(Open Firefox) Tools > Options > Applications





#Method2


Make use of the below snippet and do edits whenever necessary.


FirefoxProfile profile = new FirefoxProfile();

String path = "C:\\Test\\";
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", path);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/msword, application/csv, application/ris, text/csv, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream");
profile.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.manager.focusWhenStarting", false);  
profile.setPreference("browser.download.useDownloadDir", true);
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.download.manager.closeWhenDone", true);
profile.setPreference("browser.download.manager.showAlertOnComplete", false);
profile.setPreference("browser.download.manager.useWindow", false);
profile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
profile.setPreference("pdfjs.disabled", true);
       
driver = new FirefoxDriver(profile);

Friday 4 April 2014

Java AWT Robot | Selenium Uses


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.


Java Robot

This is the continuation of one my previous topics, link here.  Selenium doesn't give support on automating or handling Browser pop-ups and Native OS pop-ups.

There are 3 ways to make it work.
     1| Java.awt.Robot Toolkit
     2| 3rd party tools like AutoIT [check link here]
     3| Browser Profile [check link here]




Fig. Browser PopUp

Java Robot handles Mouse Actions and Keyboard Actions. For example, some of the most important functions are as follows:

      1| keyPress()
      2| keyRelease()
      3| mousePress()
      4| mouseRelease()
      5| Mousemove()




Handle Browser Pop-up


Note| 
1| The below snippet is used to save a file from Download Browser Pop-up shown above in Fig.
2| The below co-ordinates are set for Screen resolution | 1920 x 1080
3| Window status | Maximized
4| Customize the xy co-ordinates in-case if you are using different screen resolution


Robot r = new Robot();
// click Save File 
r.mouseMove(787, 544); // move to co-ordinate Location
r.mousePress(InputEvent.BUTTON1_MASK); // Left Mouse click - Press
r.mouseRelease(InputEvent.BUTTON1_MASK); // Left Mouse click - Release 
r.delay(5); // wait for 5 millisecs
// click ok
r.mouseMove(1032, 641); // move to co-ordinate Location
r.mousePress(InputEvent.BUTTON1_MASK); // Left Mouse click - Press
r.mouseRelease(InputEvent.BUTTON1_MASK); // Left Mouse click - Release





Robot Functions


InputEvent.BUTTON1_MASK // Left button
InputEvent.BUTTON2_MASK // Middle button
InputEvent.BUTTON3_MASK // Right button



Middle click | Press & Release
Robot r = new Robot();
r.mousePress(InputEvent.BUTTON2_MASK); 
r.mouseRelease(InputEvent.BUTTON2_MASK);


Right click | Press & Release
r.mousePress(InputEvent.BUTTON3_MASK); 
r.mouseRelease(InputEvent.BUTTON3_MASK);


Scroll Mouse
r.mouseWheel(7);


Pixel Color | RBG
System.out.println(r.getPixelColor(923, 87));
OUTPUT|
java.awt.Color[r=142,g=209,b=224]


Get Current Mouse position [location]
System.out.println(MouseInfo.getPointerInfo().getLocation());
OUTPUT|
java.awt.Point[x=735,y=633]


Get Screen Resolution | Dimension
System.out.println(Toolkit.getDefaultToolkit().getScreenSize());
OUTPUT|
java.awt.Dimension[width=1920,height=1080]


Screen Capture
java.awt.Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
Robot r = new Robot();
BufferedImage img = r.createScreenCapture(new Rectangle(size));
File path = new File("C://screen.jpg");
ImageIO.write(img, "JPG", path);
or|
Robot r = new Robot();
BufferedImage img = r.createScreenCapture(new Rectangle(0, 0, 100, 100));
File path = new File("C://screen.jpg");
ImageIO.write(img, "JPG", path);


Enter/Type Text
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;

Robot r = new Robot();     
driver.findElement(By.id("Value")).click();  
typeKeys("Prashanth Sams", r);

public static void typeKeys(String str,Robot r)
{
 for(int i=0;i<str.length();i++)
{
  typeCharacter(r, ""+str.charAt(i));
}
}
public static void typeCharacter(Robot robot, String letter)
{
 try
{
  boolean upperCase = Character.isUpperCase( letter.charAt(0) );
  String variableName = "VK_" + letter.toUpperCase();
  Class clazz = KeyEvent.class;
  Field field = clazz.getField( variableName );
  int keyCode = field.getInt(null);

  robot.delay(1000);

  if (upperCase) robot.keyPress( KeyEvent.VK_SHIFT );

  robot.keyPress( keyCode );
  robot.keyRelease( keyCode );

  if (upperCase) robot.keyRelease( KeyEvent.VK_SHIFT );
 }
 catch(Exception e)
 {
  System.out.println(e);
 }
 }


Keyboard Actions
r.keyPress(KeyEvent.VK_ENTER); // Press Enter Key

Find all/rest of the Java Robot keyboard actions here
Refer| Robot


PS|
Mofiki's Coordinate Finder will help you to get the screen coordinates.

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')]