Tuesday, October 25, 2011

Selenium Grid with WebDriver

I had earlier covered in my blog on how to execute your RC cases in selenium grid. But with the commencement of Selenium-2/Webdriver, grid setup has been changed. In the following blog I will cover how to set-up your grid and the changes that will be required for easy execution of cases.


Following things are required:
1. Selenium 2.xx version server jar and Java library. The latest one can be downloaded from the link: Selenium-2
2. Java 1.6 and above
3. TestNg jar . You can download it from the link: TestNG
4. Eclipse with TestNG plugin installed(optional)
5. ChromeDriver. Can be downloaded from: ChromeDriver


The Test Code
Following is an example of test-class that have a test case to search google for "testing" and verifying after clicking it on a link.

In the above class I am using the TestNG "Parameter" property to provide different data set to the "BeforeClass" method "beforeClass". The beforeClass method accepts two properties "browser" and a "port".
These values are used for initialization of driver and in-turn for initialization of selenium object. In the above code I am using the "WebDriverBackedSelenium" class for creation of the selenium object, so that its easy for guys who had worked on Selenium-1 to understand the code. If you want the code to be purely WebDriver, you can directly use the "driver" object for defining your test-cases.
The main part in this test case is how the driver object is being created:
DesiredCapabilities capability= new DesiredCapabilities();
capability.setBrowserName(browser);
WebDriver driver= new RemoteWebDriver(new URL("http://localhost:".concat(port).concat("/wd/hub")), capability);
The above code creates an object of DesiredCapability and then set the browser value to it. Now using this "capability" object I am creating the webdriver object using the "RemoteWebDriver" class. This tells the selenium on which browser the test-case needs to run and where the server is located. In this example I am assuming the server to be running locally. In case it is on different system the "localhost" needs to be re-placed with the ip of the said system.

TestNG configuration
For parallel execution you need to use the TestNG configuration. Following is an "testng.xml" file for the above said test class. The said configuration executes the test-cases across different browser.


<suite name="Selenium TestNG Suite" parallel="tests"
    thread-count="5">

    <test name="Selenium TestNG - 1">
        <parameter name="browser" value="firefox" />
        <parameter name="port" value="4444" />
        <classes>
            <class name="com.test.testng.Google" />
        </classes>
    </test>
    <test name="Selenium TestNG - 2">
        <parameter name="browser" value="chrome" />
        <parameter name="port" value="4444" />
        <classes>
            <class name="com.test.testng.Google" />
        </classes>
    </test>

</suite>


In the above configuration, I am configuring TestNG to run "tests" in parallel. Also there are two different tests inside a suite. For each test a different "browser" parameter value has been configured.

Selenium-Grid server
Now start your grid using the following commands. Run each command in a seperate terminal or command prompt by going to the directory containing your selenium-server-standalone-2.x.x.jar. In the following example I am using the 2.7.0 version of selenium.

For Hub:

java -jar selenium-server-standalone-2.7.0.jar -role hub


For a firefox based node:

java -jar selenium-server-standalone-2.7.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5556 -browser browserName=firefox


For google-chrome based node:

java -Dwebdriver.chrome.driver=/path/to/chromedriver -jar selenium-server-standalone-2.7.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5555 -browser browserName=chrome

Before running  the above command  you need to provide the chrome-driver path to the property "-Dwebdriver.chrome.driver".

Now run your testng.xml from eclipse by selecting it -> Right click -> Run as -> TestNG suite(this will work only if you have TestNG plugin installed in your eclipse.)
Or you can choose other ways to execute "testng.xml" like from command prompt, using ant or maven.
Once you run the above testng.xml. TestNG will execute the cases from the Google class on grid across different browsers firefox and google-chrome as configured.


You can do configurations for environment like OS (Linux,Windows), browser, browser-version and all and then you can run you cases on particular type of environment by configuring them accordingly. More details can be found at the following URL:
http://code.google.com/p/selenium/wiki/Grid2

51 comments :

Milind Warade said...

Hi,
I am using Webdriver for testing.
In our application there is report, in which
Xpath is same for column. See the below example:
All combo boxes have same Xpath.
All text boxes have same Xpath.
All links have same Xpath.
Then how to handle it.
I want to write the code for selection of the combo box values and relative text for every row.



|Column Name 1 |Column Name 2|Column Name 3|
|Combo box | Text box |Link |
|Combo box | Text box |Link |
|Combo box | Text box |Link |
|Combo box | Text box |Link |
|Combo box | Text box |Link |

Add another (This is the link to add new row) >>

Varun Menon said...

You can use the findElements method of webdriver to get the list of the matching elements. Then using this list you can iterate.

kirti chaudhary said...

"Parameter 'browser' is required by @Configuration on method initializeDriver but has not been marked @Optional or defined,,,"what does this error means

Varun Menon said...

It means that you are using a variable/parameter "browser" in your method initializeDriver but forgot to pass the value to it using testng.xml or using @optional configuration of testng.

greatanurag said...

Hi Varun,

I passed the value of browser in testng.xml, but still getting the same error.

can u pls help. thanks in advance.

ankitsablok said...

Hi Varun,

I read your blog post and found it highly informative, but I have a related problem what if I want to find all the available nodes that are available for me to run the tests, I want to write a java code that extracts this information for me to find the nodes in the grid that are free and along with that find their configurations.

I hope you can help me out with this. Thanks, in advance

Ankit Sablok

Varun Menon said...

All these things are taken care by grid itself.. But still if you have to do these things, you may need to take a look at the source code of selenium grid...

vikas said...

Hi varun,
By following above steps i am able to implement selenium grid successfully in my local machine.
But i am getting some node registration error when i am trying to implement selenium grid in my team mate system from my local system.

My team mate ip : 192.168.0.119

For Hub: i am running

java -jar selenium-server-standalone-2.25.0.jar -role hub

For a firefox based node: i am running

java -jar selenium-server-standalone-2.25.0.jar -role webdriver -hub http://192.168.0.119:4444/grid/register -port 5556 -browser browserName=firefox

i am getting following error:

16:46:40.609 INFO - using the json request : {"class":"org.openqa.grid.common.RegistrationRequest","capabilities":[{"platform":"VISTA","browserName":"firefox"}]
,"configuration":{"port":5556,"host":"192.168.0.128","hubHost":"192.168.0.119","registerCycle":5000,"hub":"http://192.168.0.119:4444/grid/register","url":"http:
//192.168.0.128:5556","remoteHost":"http://192.168.0.128:5556","register":true,"proxy":"org.openqa.grid.selenium.proxy.DefaultRemoteProxy","maxSession":5,"brows
er":"browserName=firefox","role":"webdriver","hubPort":4444}}
16:46:40.610 INFO - starting auto register thread. Will try to register every 5000 ms.
16:46:40.611 INFO - Registering the node to hub :http://192.168.0.119:4444/grid/register
16:47:01.622 INFO - couldn't register this node : Error sending the registration request.
16:47:27.626 INFO - couldn't register this node : hub down or not responding.

Srinivas said...

Very good article....:)

Sarika Saxena said...

Hi,
I am trying to execute my framework(keyword driven) which is working fine with Firefox but not working with IE and Chrome.
I found that if i give url inside test instead of @BeforeClass then only it is working.
But it will not work for framework
Can anyone help me on this.

---

Varun Menon said...

There may be some problem with the way the driver object is being initialized and used in your framework, just take a look at it once.

suneet said...

Hi! Varun where do i will find TestNG.xml file.Please help me.M new to selenium.Thanks in advance.

Varun Menon said...

You need to create your own testng.xml file for your test project, depending upon your project requirement.

Keshav said...

Hi Varun

How to run script in Internet explorer with latest selenium file.

Please help.

Regards,
Keshav

Varun Menon said...

In the blog I had used chromedriver in the similar fashion you need to set path of Iedriver and then use it for your execution.
Following link describes about IEdriver

https://code.google.com/p/selenium/wiki/InternetExplorerDriver

Anand Raja.K said...

Hi Varun,

Im getting the below Error,

java.lang.RuntimeException:
http-equiv="Content-Type" content="text/html;charset=ISO-8859-1
Error 500 org.openqa.grid.common.exception.GridException: Cannot extract a capabilities from the request [{"javascriptEnabled":false,"browserName":"firefox","class":"org.openqa.selenium.remote.DesiredCapabilities"}]


HTTP ERROR: 500
Problem accessing /wd/hub/session. Reason:
org.openqa.grid.common.exception.GridException: Cannot extract a capabilities from the request [{"javascriptEnabled":false,"browserName":"firefox","class":"org.openqa.selenium.remote.DesiredCapabilities"}]





at org.openqa.selenium.remote.RemoteWebDriver.throwIfResponseFailed(RemoteWebDriver.java:439)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:401)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:74)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:61)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:69)
at com.selenium.gird.Google.beforeClass(Google.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.access$0(SuiteRunner.java:333)
at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368)
at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

Varun Menon said...

Have you registered a webdriver role with firefox browser to the grid?

Tia said...

Hi Varun,

I want to use driver object itself so i am using
@Parameters({"browser","port"})
@BeforeClass
public void setUp(String browser, String port){
DesiredCapabilities capability = new DesiredCapabilities();
capability.setBrowserName(browser);
try{
WebDriver driver = new RemoteWebDriver(new URL("http://10.100.15.24/wd/hub"), capability);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

But in search Test , when i am trying to use driver object its giving error.

Please help me

Varun Menon said...

What is the error? One more thing , I suppose you are not using the port parameter.

Tia said...

Hi Varun,
Thanks for your reply. I am using this code
@Parameters({"browser","port"})
@BeforeClass
public void setUp(@Optional("chrome")String browser, @Optional("4444")String port){

DesiredCapabilities capability = new DesiredCapabilities();
capability.setBrowserName(browser);
try{
WebDriver driver = new RemoteWebDriver(new URL("http://10.100.15.24:4444/wd/hub"), capability);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

ad when i am trying to use this driver object in the search test , it doesn't give the desired function as if driver object is not created in the above line.


Never used sign comes up nest to the this line
WebDriver driver = new RemoteWebDriver(new URL("http://10.100.15.24/wd/hub"), capability);

Plese help. Thanks

Varun Menon said...

Problem is with you webdriver object.
Declare it at class level and then initialize it in setUp.

Tia said...

yeah, that i know. i have declared it at class level and initialise it in setUp but its giving error in serach test (asking to add cast to driver). Can you please tell me what i am doing wrong.

private WebDriver driver;
@Parameters({"browser","port"})
@BeforeTest
public void setUp(@Optional("chrome") String browser,@Optional("4444") String port){
DesiredCapabilities capability = new DesiredCapabilities();
capability.setBrowserName(browser);
try{
driver = new RemoteWebDriver(new URL("http://10.100.15.24:4444/wd/hub"), capability);
//selenium = new WebDriverBackedSelenium(driver, "http://www.google.com");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}

@Test
public void search(){
driver).open("http://google.co.uk");

}

Lakshmi R said...

Hi Varun,

Awesome tutorial.It is working fine in Firefox and Chrome.
Please help me out how to work in Internet Explorer via jar file through command prompt.
Thanks in advance

Varun Menon said...

For ie try setting the property value "webdriver.ie.driver" with the IEDriver.exe similar to the chrome driver configuration

Tia said...

hi Varun,

You havn't replied me, I am waiting for your answer from April 17

Varun Menon said...

Could you please tell me what is the error tht u are facing.
Also I see the following error in your code.

driver).open("http://google.co.uk");

Tia said...

Please ignore that error ..it was just typo error. so if am using the above code its gives me error on the below line

driver.open("http://google.co.uk");
and when you hover over that error, it says
The method open(String) is undefined for the type WebDriver

and gives this solution at clicking on it

((DefaultSelenium) driver).open("http://google.co.uk");

please tell me what am i doing wrong

magnifictraining said...
This comment has been removed by a blog administrator.
magnifictraining said...
This comment has been removed by a blog administrator.
Jagadish k said...

Hi Varun,

I am Executing Below code TestNG Using Selenium Grid2

@BeforeClass
public void beforeClass() throws MalformedURLException {
System.out.println("Before Test Exe");
DesiredCapabilities cap=new DesiredCapabilities().firefox();
/*cap.setBrowserName("firefox");
cap.setPlatform(Platform.WINDOWS);
cap.setVersion("7");*/
System.out.println("After Desired Capabilities");
driver=new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"),cap);
System.out.println("After Remote Webdriver");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

But i am getting below Error
FAILED CONFIGURATION: @BeforeClass beforeClass
org.openqa.selenium.WebDriverException: Error forwarding the new session Empty pool of VM for setup {platform=ANY, browserName=firefox, version=}
Command duration or timeout: 214 milliseconds

Varun Menon said...

Can you check your grid and see what properties our node shows in it.
This issue may occur when the registered nodes dont match with the driver configuration you requested for execution..

>>-----=> said...

Hi Varun,

Can you please explain this in elaborate for android browsers. It would be of a great help

Varun Menon said...

I had worked on simple android driver on a mobile. But haven't integrated it with selenium grid.

Bhanu Prasad said...

Hi Varun

I have some selenium grid related doubts:
Currently we are trying to use GRID with JUNIT and able confgure and run the tests.
My doubts are
1. I observed that my testcases, when one testcase is running my other node is Idle and vice versa.
IS THAT HOW testcases run in selenium grid

2. Our main constraint is to run group of testcases in each node such that we can get the results in quick time. Can to tell how can I achieve that




Varun Menon said...

By default Junit execute the tests in a single thread and that may the reason that you see your tests getting executed on a single node rather than on multiple nodes.
Configure your build tool or Junit to run your tests multi-threaded you will see different nodes being used for execution depending upon the threads you are using.

Bhanu Prasad said...

Hi Varun, Thanks for quick response..
I have not described correctly

For Example : I have 2 test suites TS1 and TS2.

Each test suite has 2 Testcases. TS1 --> TC1, TC2 and other suite TS2 --> TC3, TC4

Below mentioned code I am using in my build.xml file
target name="allTests" depends="se_cmpl"
property name="inTestMode" value="true"
parallel threadCount="2"
antcall target="sel_tests"
param name="unitTestId" value="com/talentplus/test1/*.class" /
/antcall
antcall target="sel_tests"
param name="unitTestId" value="com/talentplus/test2/*.class" /
/antcall
/parallel

junitreport todir="${target.dir}/seleniumTestResults"
fileset dir="${target.dir}/seleniumTestResults"
include name="TEST-*.xml"
/fileset
report format="frames" todir="${target.dir}/seleniumTestResults/${DSTAMP}/report/html"
/junitreport
/target

1. All testcases are running in all configured nodes (currently I am using node1, node2)
Summarizing TC1,TC3 runs on node1 when running node2 will be Idle then TC1 and TC3 runs on node2 that time node1 will be Idle.

But what I expecting is that each test case should run only on one node. Is that possible through selenium Grid.



Varun Menon said...

You need to configure unique nodes in such case and use it for configuring your tests.

Bhanu Prasad said...

Please can you let me know how to configure tests with unique nodes.

Bhanu Prasad said...

I am seeing Testng related build file, please can you let me know what should with Junit
{code}

{code}

Bhanu Prasad said...

Sorry It didn't allow me last time with tags, so I tried with {code}. Below is the code

suite name="Selenium Grid with webdriver" verbose="3" parallel="classes" thread-count="2"

I am seeing Testng related build file, please can you let me know what should with Junit.

Nag said...

Hi Varun,

Please can u address the above issue.
I am facing the same issue

Varun Menon said...

Setup a node by using some constant params given in the Grid2 wiki of selenium. Then configure you driver object to point to a particular node by using the same configuration while creating driver.

https://code.google.com/p/selenium/wiki/Grid2

Bhanu Prasad said...

Thank you very much for the reply..

I will try out let you know about this

Thanks
-Bhanu

Bhanu Prasad said...

I have solved my problem, problem is that - multithread might work when we specify hardcoded/specific junit suites not by *.class(I am expecting to run all testcases). After fixing that Issue of running specific tests on nodes also worked.

Thanks
-Bhanu

Gitesh Garg said...

Hi Varun,

How can i order hub to connect/execute TCs on only Specific node.

sruthi said...

Hi Varun,

I want to read the data from a PDF file and write to the excel using selenium webdriver . Can any one help me out.

Varun Menon said...

I never worked on reading something from pdf but hopefully there will be a utility for that available. Once you do you can use apache poi to write to excel file. And for your FYI there is nowhere selenium webdriver is going to be involved in this case its completely the coding that you need to do. Read from one file and write to another

Parag Dave said...

Can i use selenium for testing in magento?

ganesh n said...

Hi Varun,

I need to develop a Web Application which when clicked on a button should run multiple instances of selenium and run the test.

I tried doing a servlet code for the same but the execution crashes at

FirefoxDriver dr= new Firefoxdriver();

Can i acheive this using Web Driver or grid. Could you please guide?

richard allen said...

I'm for the most part a manual test engineer. I have access only to the GUI of our apps at this point. I've played a bit with selenium 2 / java / TestNG in navigating our apps but I don't have experience designing / architecture of automation. Would this be helpful or is this just for programmers?

Varun Menon said...

What ever you are doing is good for writing automating tests and building a basic framework. But if you learn designing and architecture skills it will help to build robust frameworks. Go through OOPS in java & design patterns it will give a basic idea of coding design. Got through some apis to understand them better.

Post a Comment