In this posting I document extending Selenium server with a custom javascript method, getAllRadios()
, to return all radio button elements in a page. It’s based on the getAllButtons()
that is stock in Selenium.
I will demonstrate two ways to add this custom method. The first strategy is to add the custom method to the native javascript files that ship with Selenium server. This is not the recommended way to extend Selenium but it is an almost guaranteed way to be sure the server picks up my new method and that frees me to focus on getting my client syntax right for calling the new method using the client’s doCommand()
method.
Method 1 – selenium-browserbot.js + selenium-api.js
Unpack the server jar into a temporary directory to get access to the selenium-browserbot.js
and selenium-api.js
files.
$ jar xf ../selenium-server.jar
The new custom method is added to core/scripts/selenium-browserbot.js
. It is a slightly modified version of getAllButtons()
which is defined in the same file.
BrowserBot.prototype.getAllRadios = function() {
var elements = this.getDocument().getElementsByTagName('input');
var result = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].type == 'radio') {
result.push(elements[i].id);
}
}
return result;
};
and then the new method is exposed to the Selenium API in core/scripts/selenium-api.js
, again modeling after getAllButtons()
in selenium-api.js
.
Selenium.prototype.getAllRadios = function() {
return this.browserbot.getAllButtons();
};
Now rebundle the updated javascript into a new server jar, replacing the original.
[21:01 20090906 crashing@server /selenium-server-1.0.1/temp]
$ jar cmf META-INF/MANIFEST.MF ../selenium-server.jar .
Method 2 – user-extension.js
The better way to extend Selenium is to add methods to the user-extensions.js
file. This avoids screwing around with the native server jar. I initiall had some trouble getting this working, hence the Method 1 approach, but after a bit of futzing I finally got this to work.
Selenium.prototype.getAllRadios = function() {
var elements = this.browserbot.getDocument().getElementsByTagName('input');
var result = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].type == 'radio') {
result.push(elements[i].id);
}
}
return result;
};
This is basically the same method used in selenium-browserbot.js
. The important changed bits are (1) the method is attached to the Selenium object instead of the BrowserBot (Selenium.prototype
rather than BrowserBot.prototype
) and (2) calling getDocument()
on the browserbot
instance.
I start the Selenium server with the -userExtensions
option pointing to the user-extensions.js
file.
/selenium-server-1.0.1/selenium-server.jar \
-userExtensions /user-extensions.js
Client Coding
For either of the above methods of extending the Selenium server, I call this new method in my client code with the doCommand()
.
proc = new HttpCommandProcessor(seleniumServerHost,
seleniumServerPort, brower, seleniumServerStartUrl);
selenium = new DefaultSelenium(proc);
selenium.open(url);
// radio buttons returned as comma-delimited strings
String allRadios = proc.doCommand("getAllRadios", null);
// alternatively, get radio buttons as a String array
String[] radios = proc.getStringArray("getAllRadios", null);
for (String radio : radios) {
System.out.println(radio);
}
To call custom doCommand()
‘s, it’s necessary to instantiate with DefaultSelenium(proc)
to inject the HttpCommandProcessor
into the DefaultSelenium
object.
Related:
Select the ids of radio buttons in a page using selenium
User-Extensions
14 comments
Comments feed for this article
July 7, 2010 at 5:17 pm
Santiago
Dude, you just saved me several hours of research.
Thanks and keep up the good work!
Santi
August 9, 2010 at 10:31 am
Loki
After adding custom method to source code and rebundling using jar cmf META-INF/MANIFEST.MF ../selenium-server.jar command – I have observed an error with message “Could not find the main class: org.openqa.selenium.server.SeleniumServer.”
Any advice is my appreciated.
August 10, 2010 at 1:58 am
crashingdaily
Loki, does the original selenium-server.jar work?
Are you replacing the original selenium-server.jar with your custom one – in the same directory?
If you list the contents of your jar, do you see the SeleniumServer.class listed? Something like,
$ jar tvf selenium-server.jar | grep SeleniumServer.class
19066 Tue Feb 23 09:37:14 EST 2010 org/openqa/selenium/server/SeleniumServer.class
October 29, 2010 at 6:28 am
farheen
I liked it a lot…Thanks….I was searching this from so many days.I could find info on extensions in selenium but never understood…Thanks once again
November 11, 2010 at 1:59 pm
Bharath
Hello crashingdaily,
I am planning to create a new click() method by using user extension. Please help me in resolving this issue. Attaching my sample code.
package package1;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.*;
import com.thoughtworks.selenium.*;
public class Sample2
{
private static final String Timeout = “30000”;
private static final String BASE_URL = “http://google.com/”;
private static final String BASE_URL_1 = “/”;
private Selenium selenium;
private HttpCommandProcessor proc;
@BeforeClass
protected void setUp()throws Exception
{
proc = new HttpCommandProcessor(“localhost”, 4444, “*iexplore”, BASE_URL);
selenium = new DefaultSelenium(proc);
selenium.start();
selenium.windowFocus();
selenium.windowMaximize();
selenium.windowFocus();
}
@AfterClass(alwaysRun=true)
protected void tearDown() throws Exception
{
selenium.stop();
}
@Test(groups=”search”)
public void test_ePurchaseTestCase() throws Exception
{
selenium.open(BASE_URL_1);
selenium.type(“name=q”, “Bharath Marrivada”);
//selenium.click(“name=btnG”); //Hit search button
proc.doCommand(“click1”, new String[] {“btnG”}); //user extension
Thread.sleep(10000);
}
}
=============================================
Selenium.prototype.click1 = function(myvalues)
{
this.page().click(“btnG”);
return null;
};
=============================================
Error Message ERROR: Unknown command: ‘click1’
Executing the code through Eclipse.
-Bharath
November 13, 2010 at 3:25 am
crashingdaily
Bharath, I don’t see anything wrong with your code offhand. Are you starting your Se server with the -userExtensions option?
November 15, 2010 at 9:50 am
Bharath
Yes, I use following shell command to make task easy.
Dim oShell
Set oShell = WScript.CreateObject (“WScript.Shell”)
oShell.run “cmd /K CD C:\selenium-rc-103\selenium-server-1.0.3 & java -jar selenium-server.jar -userExtensions user-extensions.js”
Set oShell = Nothing
– Bharath.
November 15, 2010 at 9:54 am
Bharath
Please run the same above code on your machine, so that you can find my mistake.
-Bharath.
April 2, 2012 at 9:39 am
Selenium dt
Hi can u give briefly the step by step procedure including screenshots and code of the files of selenium -browserbot.js and selenium-api.js and userextension.js…
Actually my problem is .I got strucked in the middleof program.Finding the code but am not finding it..can u please send everything
May 19, 2012 at 7:03 pm
kathi
when i m creating jar…i m not getting the jar file..it is 1 kb only…
May 19, 2012 at 7:08 pm
kathir
will user-extension.js working with eclipse ide.
May 29, 2012 at 11:40 am
katieg
there is another alternative using the client drivers, see here, http://www.testinggeek.com/selenium-remote-control-introduction
July 4, 2012 at 11:53 am
Anjana
Hi, I do have user-extensions file & it works fine. My application has ext js framework & my extensions uses some of ext js functions. If I want to pack it with the selenium api with these user-extensions how can I include the external api’s required for those js functions i.e in my case ext-js api
Would be glad if anyone helps in this regard
May 2, 2013 at 12:18 am
http://www.Trustterminix.com/exterminators/nc/charlotte/
Can I just say what a comfort to find somebody that
genuinely understands what they are discussing on the internet.
You definitely realize how to bring an issue to light and make it important.
More and more people need to look at this and understand this side of
the story. I can’t believe you are not more popular because you definitely possess the gift.