Sunday, May 2, 2010

Extending the Default Selenium

What the heck is Default Selenium?
Calm down!, DefaultSelenium is the base class that you instantiate early on in your test class to get the selenium object which you later use in almost every line of you test script.

 

.
.
Selenium selenium=new DefaultSelenium("localhost",4444,"*chrome","http://www.google.com/");     
selenium.start();
selenium.open("/");
.
.
.
                  OR               

/*Creates a new DefaultSelenium object and starts it using the specified baseUrl and browser string*/                        
 setUp("http://www.imdb.com/", "*firefox");
selenium.open("/");
selenium.click("nb15go_image");
.
.
.
does that ring a bell? 


What do you mean by extending the default selenium?
Extending the default selenium means enhancing or customizing or modifying the existing features of selenium class. We are reusing the existing class after adding some enhancements so as to customize the existing features to our taste and requirement. Programming languages such as JAVA provide the facility of extending/modifying the behavior of a class without having to re-write the entire class. We can create a new class that inherits the attributes and methods of another. We don't need a copy of the original source code (as is the case with many other languages) to extend the usefulness of a class/library.

Why do I need to extend selenium?

If you want certain operations to be done every time before a step is executed then you would have to extend the default selenium. For example let’s say that you wish to wait 5 seconds after every step or you want to highlight the element before clicking on it or you want to record every step in log file or you want to poll for a element’s existence for a certain amount of time before performing an operation (click, type) on it. For all these to happen you would have to extend the default selenium class that you use in your RC test script.

Below is a simple example that demonstrates this concept. The class MySelenium extends the class DefaultSelenium. The methods click and type of the base class have been over-ridden in such a way that the target element (which is to be clicked on or typed into) is highlighted thrice before the click or type operation. The class UsingMySelenium by the means of a simple example demonstrates the usage of our extended class.

Class MySelenium
package seleniumExtention;

import com.thoughtworks.selenium.DefaultSelenium;

public class MySelenium  extends DefaultSelenium{

public MySelenium(String seleniumSeverHost, int port,String browserString,String autURL){        
super(seleniumSeverHost, port,browserString, autURL);  
}

@Override
public void click(String target) {
try {
for (int i=0;i<3;i++){
super.highlight(target);  
Thread.sleep(500);
}

super.click(target);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void type(String target, String value){
try{
for (int i=0;i<3;i++){
super.highlight(target);
Thread.sleep(500);
}
super.type(target,value);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}



Class UsingMySelenium
package seleniumExtention;

import org.junit.Test;
import org.junit.BeforeClass;
import org.openqa.selenium.server.SeleniumServer;

import com.thoughtworks.selenium.SeleneseTestCase;

public class UsingMySelenium extends SeleneseTestCase{
public MySelenium selenium;

@BeforeClass
public void setUp() throws Exception {

SeleniumServer seleniumserver=new SeleniumServer();
seleniumserver.boot();
seleniumserver.start();

/*using the customized selenium class that we created earlier instead of the default selenium*/  
selenium=new MySelenium ("localhost",4444,"*iexplore","http://www.google.com/");
selenium.start();
selenium.windowMaximize();

}

@Test
public void testSimpleGoogleSearch() throws Exception {
selenium.open("/");
selenium.waitForPageToLoad("5000");
selenium.type("q", "Aston Martin volante");
selenium.click("//input[@value='Google Search']");
selenium.waitForPageToLoad("5000");
selenium.click("xpath=/descendant::a[text()=' - The Cars']/em[text()='Aston Martin']/parent::a");   
selenium.waitForPageToLoad("25000");
Thread.sleep(5000);
}
}



To make this work you need to do the following
1) Create a package seleniumExtention inside the java project.
2) Create the classes MySelenium & UsingMySelenium and copy paste the content as given above.
3) Run the testSimpleGoogleSearch() given in the class UsingMySelenium (right click Run As-->JUnit Test).

*Following jars need to be referenced
selenium-server.jar
selenium-java-client-driver.jar
junit.jar

good luck with this and keep the questions coming!

9 Comments:

Karthik said...

hi Mahesh,
Thanks for your time in creating these valuable posts. I am using Selenium RC and I have some pages where there is Auto complete feature based on AJAX. When I click inside the text box, after a little delay, a container is displayed below the text box, which has a list of items that can be selected by clicking on one of them and the selected list item is displayed in the text box. I am not able to automate this in Selenium IDE/ RC. Do you have any suggestions on how such components can be automated?

Thanks, Karthik

Mahesh Narayanan said...

Hi Karthik,

I remember no to long ago working with an infragistic textbox control that displayed a drop down list while you type into the textbox. I used the strategy as follows
1) type the full and exact value into the text box; at the drop down list box displays only one item
2)place the mouse cursor using robot just below (some fixed percentage) the textbox where the first (the only one) element is visible. Use getElementPosition getElement Height to figure out the mouse coordinate.
3)Do a robot.mousepress and release.

Daz said...

This seems really useful but, do you have the examples in C# ?

Anonymous said...

Simply Awesome !

Bharath Marrivada said...

Hello Mahesh,

Need your help on User-Extension.

Planning to calculate page response time using "Timer Extension" using http://wiki.openqa.org/display/SEL/Timer+Extension.
I have copied the code in "User-Extension.js" and specified the path in the Selenium RC.
When I execute following code using eclipse, I am getting following error message "method timerStart(string) is undefined".
System.out.println("Test Strated");
timerStart("LoginPage");
selenium.open(BASE_URL_1);
selenium.waitForPageToLoad(MAX_WAIT_TIME_IN_MS);
timerStop("LoginPage");

How to make eclipse recognize this new method ?

- Bharath

Farheen Khan said...

Hi Bharath,

If u add a code in user-extensions.js file then that command can be used only in Selenium IDE,not in RC.

Suryakant said...

BROTHER MAHESH,

I WANT YOUR NEED, PLEASE CONTACT ME ON SAPATEL5758@GMAIL.COM

THANKS

Ramesh kudikala said...

hi,
i need a small help. how to read the data from excel in selenium webdriver. please send me the script for that..

i created an object for excel .. file inputstream.. and how to enter the data in sendkeys .. after reading the data..

rameshkudikala83@gmail.com

Shruti Ramalingam said...

Thanks for the great information in your blog Selenium Training in Chennai