Showing posts with label Selenium RC. Show all posts
Showing posts with label Selenium RC. Show all posts

Friday, January 03, 2014

Selenium tricks for CSS and Xpath locators

In this post you will learn some CSS rules and how to use CSS selectors and Xpath locators in Selenium.

(1) Id:
An element's id is defined as "[@id='idName']" in Xpath but "#idName" in CSS.
For example, a 'div' element with id 'panel' will be represented as below:
In Xpath locator
//div[@id='panel']
In CSS selector
css=div#panel

(2) Class:
An element's class is defined as "[@class='className']" in Xpath but ".className" in CSS.  
For example, a 'div' element with class 'panelClass' will be represented as below:
In Xpath locator
//div[@class='panelClass']
In CSS selector
css=div.panelClass
For element with multiple class we need to separate with space(" ") in Xpath and dot(".") in case of CSS. See below example,
In Xpath locator
//div[@class='panelClass1 panelClass2']
In CSS selector
css=div.panelClass1.panelClass2

(3) Any Attributes:
For selecting an element by its any of the attribute(say "name" is an attribute of a 'div' element and "type" in an "input" element) is given below:
In Xpath locator
//div[@name='continue']
//input[@type='button'] 
In CSS selector
css=div[name='continue']
css=input[type='button'] 

(4) Direct Child:
A direct child of an element is denoted as "/" in Xpath and ">" in CSS selector. See the example below for a direct child "li" for a "ul" element:
In Xpath locator
//ul/li
In CSS selector
css=ul > li

(5) Child or Subchild:
A direct child of an element is denoted as "//" in Xpath and a wehite-space(" ") in CSS selector. See the example below for a child/subchild "li" for a "ul" element:
In Xpath locator
//ul//li
In CSS selector
css=ul li
Note that "ul li" and "ul > li" are different. If you are confusing please go through this article.

(6) nth Child:
For finding 'nth' child, in Xpath we denote as "[n]" and in CSS we denote as ":nth-of-type(n)". See the below example,
  1. Coffee
  2. Tea
  3. Milk
  4. Soup
  5. Soft Drinks
In Xpath locator
//ul[@id='drinks']/li[5]
In CSS selector
css=ul#drinks li:nth-of-type(5)
Also you can use ":nth-child" but the difference between ":nth-child" and ":nth-of-type(n)" is:
li:nth-child(2)
This means, select an element if It is a paragraph element and the second child of a parent.

li:nth-of-type(2)
This means, select the second paragraph child of a parent. This is less conditional.

See here for more details on difference between the above two.

If we want to select the "fifth li element" (Soft Drinks) in this list, we can use the nth-of-type, which will find the fifth li in the list.
css=ul#drinks li:nth-of-type(5)
On the other hand, if we want to get the "fifth element" only if it is a li element, we can use a filtered nth-child which will select again (Soft Drinks) here.
css=ul#drinks li:nth-child(5)
(7) Parent of an element:
Parent of an element can be represented as "/.." in Xpath and ":parent" in CSS selectors. For example, if you want to indicate parent of the list item of class 'blue'
  • first
  • second
  • third
  • fourth
  • fifth
In Xpath locator
//li[@class='blue']/..
In CSS selector
css=li.blue:parent

(8) Next Sibling:
Next sibling is nothing but next adjacent element which is inside the same parent on the page. An adjacent sibling combinator selector allows you to select an element that is directly after another specific element. For example, If you want to select the sibling of "li" element with class "blue" which is 'second' list item,
In Xpath locator
//li[@class='blue']/../li[2]
In CSS selector
css=li.blue + li
Similarly, if you want to indicate 'third' list item, see the below
In Xpath locator
//li[@class='blue']/../li[3]
In CSS selector
css=li.blue + li + li

(9) Match by Innertext:
There is a javascript methodcontains() which can be used to check the inner text of a web element. For example a link with text "Sign in"
In Xpath locator
//a[contains(text(),'Sign in')]
or
//a[contains(string(),'Sign in')] 
In CSS selector
css=a:contains('Sign in')

(10) Match by Sub-string:
This is interesting and is described below. With this we can match strings with its partial text. E.g. prefix, suffix or any pattern(sub-string)
(i) Match a Sub-string(pattern):
Taking an example of a 'div' with an 'id' that contains the text "pattern"
...
In Xpath locator, we need to use "contains()" to match a sub-string
//div[contains(@id,'pattern')]
In CSS selector, we need to use "*=" for matching a sub-string
css=div[id*='pattern']

(ii) Match a prefix:
Taking an example of a 'div' with an 'id' that starts with the text "prefixString"
...
In Xpath locator, we need to use "starts-with" to match a prefix
//div[starts-with(@id,"prefixString")]
In CSS selector, we need to use "^=" for matching a prefix
css=div[id^='prefixString']

(iii) Match a suffix:
Taking an example of a 'div' with an 'id' that starts with the text "suffixString"
...
In Xpath locator, we need to use "ends-with" to match a suffix Note that "ends-with()" is a standard XPath 2.0 function only, it won't work if you are using Xpath 1.0 engine
//div[ends-with(@id,"suffixString")]
In CSS selector, we need to use "$=" for matching a suffix
css=div[id$='suffixString']
The summary of sub-string match is listed out in the following table:
Match a Sub-string Match a Prefix Match a Suffix
Xpath contains() starts-with() ends-with()
CSS *= ^= $=

Saturday, December 21, 2013

Format string for locators

There are many locators for web elements which are of same kind, only they vary with a small difference in index or string such as 
"//div[@id='one']/span[text()='jack']" and 
"//div[@id='one']/span[text()='john']"

For these web elements we should find a common locator with an input span text.
Let's take an example of a web element,
  1. Coffee
  2. Tea
  3. Milk
  4. Soup
  5. Soft Drinks
The locator for the above list items 'Soft Drinks' can be represented as below:
private final String DRINK_ITEM = "ul#drinks li:nth-of-type(5)";// using CSS selector
or
private final String DRINK_ITEM = "//ul[@id='drinks']/li[5]";// using Xpath
For finding 5th 'li' item we can directly use the above locator, but when we want to use 2nd 'li' item or some other item or all 'li' items at a time, then we need to represent the locator in a common way.
  • By direct use: 
For a list item,
WebElement element= driver.findElement(By.xpath(DRINK_ITEM));
element.doSomething();
Or, for all list items,
for (int i = 1; i < count; i++) {
 WebElement element = driver.findElement(By.xpath("//ul[@id='drinks']/li[" + i + "]"));
 element.doSomething();
}
  • By formatting the locator:
For a list item,
String drinkItem = String.format(DRINK_ITEM, 5);
WebElement element = driver.findElement(By.xpath(drinkItem));
element.doSomething();
For multiple list items,
for (int i = 1; i < count; i++) {
 String drinkItem = String.format(DRINK_ITEM, i);
 WebElement element = driver.findElement(By.xpath(drinkItem));
 element.doSomething();
}
If you are still not clear about how to use format string, please see the below examples:
private final String GRID_TABLE_VIEW = "div#panel2content div.table.%s";
private final String RESULT_TABLE_VIEW = "//div[@id='panel1content']//div[%d]/span[text()='%s']";
private final String SPACE_TOGGLE_MENU_OPTION = "ul#spacing_toggle li:nth-of-type(%d)";

String gridTableView = String.format(GRID_TABLE_VIEW, "filterByName");
String resultTableView = String.format(RESULT_TABLE_VIEW, 2, "bill");
String spaceToggleMenuOption = String.format(SPACE_TOGGLE_MENU_OPTION, 3);

/** It will print "div#panel2content div.table.filterByName" */
System.out.println(gridTableView);

/** It will print "//div[@id='panel1content']//div[2]/span[text()='bill']" */
System.out.println(resultTableView);

/** It will print "ul#spacing_toggle li:nth-of-type(3)" */
System.out.println(spaceToggleMenuOption);

Tuesday, November 26, 2013

Get name of test method in teardown

Sometimes we need name of the test method that has just executed in the tear down method for various purposes such as:
  • If you take screenshot in tear down and want to give last executed method name as a part of screenshot name.
  • May be someone want to track something in the log with the test method information.
  • If you have different classes containing test methods and tear down method, and you want to use test method information in tear down method.
@AfterMethod
public void yourTearDownMethod(ITestResult result) {
  System.out.println("method name:" + result.getMethod().getMethodName();
}
Similar way, you can get other information about the test method by result.getMethod().getXXX()

Saturday, September 22, 2012

Dealing with web elements by different locators

Let’s consider the following sample HTML code snippet as a reference point.
  1. <!DOCTYPE HTML>
  2. <html>
  3.     <head>
  4.         <script type="text/javascript">
  5.             function jsFunction(){
  6.                 alert("Welcome to Selenium UI Automation Testing !");
  7.             }
  8.         </script>
  9.     </head>
  10.     <body>
  11.         <input type="submit" id="webButton" onclick="jsFunction()" value="Click It" />
  12.     <a href="http://aksahu.blogspot.in/">Go Home</a>
  13.     </body>
  14. </html>
Lets start by taking example of any of the selenium command say "click"
You can use same fashion for any of the selenium command like i am using for click.
The click command emulates a click operation for a link, button, checkbox or radio button. It takes a locator (an identifier for which HTML element the command refers to) as an argument.

Using Selectors with Click Command:

xpath

This allows clicking on an element using an XPath expression. Example

selenium.click("xpath=//input[@name=webButton' and @type='submit']");

css

CSS locator is used with Selenium commands to uniquely identify an object or element on a web page. Example,

selenium.click("css=input[name=webButton]”);

name

The name selector is used to click the first element with the specified @name attribute. Example,

selenium.click("name=webButton”);
or
selenium.click("webButton");

id

This allows click on an element with the specified @id attribute. Example,

selenium.click("id=webButton”);

link

This allows clicking on a link element which contains text matching the specified pattern. Example,

selenium.click("link=Go Home”);


Check if selenium server is running in background

When we run selenium RC test cases sometimes we faces this issue saying "java.net.BindException: Selenium is already running on port 4444. Or some other service is." 
When you check the port 4444 no service is running. We change the port and run the program even that too is not working. 
In these cases we need to shutdown the selenium server on this port.
Use below command to shut down the server.

http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer

If selenium server is already running on port 4444 then it will shut down the server and says
OKOK
if selenium is not running on this port 4444 then by hitting above url will give you 
"Unable to connect"
Now you can run your test cases i am sure will run smoothing.

You can also do an alternative way to handle this i.e you can and some code to check whether the selenium server in a specific port is running or not before starting the server like below:

//ServerControl.java
  1. package test.example;
  2. import java.net.HttpURLConnection;
  3. import java.net.URL;
  4. import org.openqa.selenium.server.RemoteControlConfiguration;
  5. import org.openqa.selenium.server.SeleniumServer;
  6. import org.testng.annotations.AfterClass;
  7. import org.testng.annotations.AfterSuite;
  8. import org.testng.annotations.BeforeClass;
  9. import org.testng.annotations.BeforeSuite;
  10. import com.thoughtworks.selenium.DefaultSelenium;
  11. import com.thoughtworks.selenium.Selenium;
  12. /**
  13.  * This class contains methods to control selenium server
  14.  *
  15.  * @author aksahu
  16.  */
  17. public class ServerControl {
  18.     protected Selenium selenium;
  19.     protected SeleniumServer seleniumServer;
  20.     private static String host = "localhost";
  21.     private static int port = 4444;
  22.     @BeforeSuite
  23.     public void startSeleniumServer() {
  24.         if (!isSeleniumServerRunning()) {
  25.             try {
  26.                 RemoteControlConfiguration rc = new RemoteControlConfiguration();
  27.                 seleniumServer = new SeleniumServer(rc);
  28.                 seleniumServer.start();
  29.             } catch (Exception e) {
  30.                 e.printStackTrace();
  31.             }
  32.         }
  33.     }
  34.     @BeforeClass
  35.     public void startSelenium() {
  36.         selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com");
  37.         selenium.start();
  38.         selenium.windowMaximize();
  39.     }
  40.    
  41.     @AfterClass
  42.     public void stopSelenium() {
  43.         selenium.stop();
  44.     }
  45.     @AfterSuite
  46.     public void stopSeleniumServer() throws Exception {
  47.         seleniumServer.stop();
  48.     }
  49.     /**
  50.      * Check whether the selenium server in the given port is running or not
  51.      * @return
  52.      */
  53.     public static boolean isSeleniumServerRunning() {
  54.         try {
  55.             String baseUrl = "http://" + host + ":" + port;
  56.             System.out.println("Checking selenium server status [" + baseUrl + "]");
  57.             URL url = new URL(baseUrl + "/selenium-server/driver/?cmd=testComplete");
  58.             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  59.             if (connection.getResponseCode() == HttpURLConnection.HTTP_OK)
  60.                 return true;
  61.         } catch (Exception e) {
  62.             System.err.println("Could not check selenium server status: " + e.getMessage());
  63.         }
  64.         return false;
  65.     }
  66. }

In the above the method isSeleniumServerRunning() returns a boolean value true if the server is running in the given port and host and returns false otherwise.

Thursday, March 15, 2012

Selenium RC with TestNG

Here is an example explaining how to use TestNG with Selenium RC i.e using TestNG  to run selenium rc tests.

//GoogleTestTestNG.java
  1. package test.example;
  2. import org.testng.annotations.AfterClass;
  3. import org.testng.annotations.BeforeClass;
  4. import org.testng.annotations.Test;
  5. import com.thoughtworks.selenium.DefaultSelenium;
  6. import com.thoughtworks.selenium.Selenium;
  7. /**
  8.  * Search Google example.
  9.  *
  10.  * @author aksahu
  11.  */
  12. public class GoogleTestTestNg {
  13.    
  14.     Selenium selenium;
  15.    
  16.     @BeforeClass
  17.     public void startSelenium(){
  18.         selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com");
  19.         selenium.start();
  20.         selenium.windowMaximize();
  21.     }
  22.    
  23.     @Test
  24.     public void testGoogleSearch(){    
  25.         selenium.open("/");
  26.         selenium.type("id=lst-ib", "selenium");
  27.         selenium.click("name=btnK");
  28.         selenium.click("link=Selenium - Web Browser Automation");
  29.         selenium.waitForPageToLoad("30000");
  30.     }
  31.    
  32.     @AfterClass
  33.     public void stopSelenium(){    
  34.         selenium.stop();
  35.     }
  36. }

          This test launches firefox browser and executes the google search test.The selenium session is started in startSelenium() method which is called before any test run in the test class and ends with stopSelenium() method which 'll call after the tests run.