Tuesday, September 29, 2009

Using UI-Elements user-extension with Selenium RC

Please refer to my post UI-Elements - All about it to understand what UI-Elements are. In this post I wish to describe how UI-Elements can be used with Selenium RC.

There are a few things that are different here from how it is used with selenium ide
1) In Selenium IDE the UI-Map file is added to the IDE environment as selenium core extension. You may add any number of such files from the IDE->options->Selenium core extensions.
In Selenium RC the UI Map file is added either programatically or added as command line parameter when invoking selenium-server.

2)In Selenium IDE you may add as many map files as you wish. However in
Selenium RC you can add only one UI-Map file and that file must be in the same directory as selenium-server.jar. Also the name of ui-map file must be 'user-extensions.js'.

Below is code for attaching the ui-map file to the selenium server. The 'getConfiguration()' method of seleniumserver object is used to get the configuration object and the 'setUserExtension()' method is used to set the uimap file as the user-extension.

.
.
.
SeleniumServer seleniumserver;
seleniumserver=new SeleniumServer();
RemoteControlConfiguration a= seleniumserver.getConfiguration();
File uimap=new File("lib\\user-extensions.js");
a.setUserExtensions(uimap);
seleniumserver.boot();
seleniumserver.start();
.
.
.

Now what if you have multiple ui-map files? In that case you must combine all of them together to create one consolidated 'user-extension.js' file. I have written a function that does this for me.
Please note that you must remove the instruction

var myMap = new UIMap();

from the individual map files as the function adds it automatically in the combined file.
public static void createUIMAP(String masterUIMAPfilePath) throws java.io.IOException{              
RandomAccessFile file = null;
RandomAccessFile fileui = null;
String line = null;
String lineui = null;


File oldFile=new File("lib\\user-extentions.js");
if (oldFile.exists())
oldFile.delete();

FileWriter fstream = new FileWriter("lib\\user-extensions.js",true);
String theFirstLine="var myMap = new UIMap();";
fstream.write(theFirstLine, 0, theFirstLine.length());
file = new RandomAccessFile(masterUIMAPfilePath, "r");
while ((line = file.readLine()) != null) {
System.out.println(line);
fileui = new RandomAccessFile(line, "r");
while ((lineui = fileui.readLine()) != null) {
System.out.println(lineui);
fstream.write(lineui, 0, lineui.length());
fstream.write(System.getProperty("line.separator"));

}
}
fstream.close();
}
This function deletes any file with the name 'user-extension.js' that may be there in the \lib folder within your java project and creates a new 'user-extension.js' file by combining any number of child ui-map file(s) whose location(s) is mentioned in the text file masterUIMAPfile whose path is supplied as a parameter to this function.
The masterUIMapFile may look something like this (all paths are relative to the java project).
test\\Resources\\UIMaps\\admin\\uimap1.js
test\\Resources\\UIMaps\\admin\\uiMapGoogle.js
I have placed the 'uiMaster.txt' in test\Resources\UIMaps\admin\uiMaster.txt within my java project.
Now I will put this all together with the script that was created in my last post. The createUIMAP() function is to be called before calling the setUserExtensions() method.

import org.junit.AfterClass;
import org.junit.Test;
import org.openqa.selenium.server.RemoteControlConfiguration;
import org.openqa.selenium.server.SeleniumServer;
import com.thoughtworks.selenium.*;
import java.io.File;
import java.io.FileWriter;
import java.io.RandomAccessFile;


public class testGoogleUIMapNew extends SeleneseTestCase {
public void setUp() throws Exception {
createUIMAP("test\\Resources\\UIMaps\\admin\\uiMaster.txt");
SeleniumServer seleniumserver;
seleniumserver=new SeleniumServer();
RemoteControlConfiguration a= seleniumserver.getConfiguration();
File uimap=new File("lib\\user-extensions.js");
a.setUserExtensions(uimap);
seleniumserver.boot();
seleniumserver.start();

setUp("http://www.google.com/", "*firefox");
}



@Test public void testGoogleuimap() throws Exception {
selenium.open("www.google.co.in");
verifyTrue(selenium.isElementPresent("ui=googleSearch_page::theBigGoogleLogo()"));
selenium.type("ui=googleSearch_page::search_Textbox()", "wikipedia");
selenium.click("ui=googleSearch_page::search_button()");
selenium.waitForPageToLoad("30000");
verifyTrue(selenium.isElementPresent("ui=googleSearch_page::searchwikipedia_textbox()"));
selenium.type("ui=googleSearch_page::searchwikipedia_textbox()", "selenium");
selenium.click("ui=googleSearch_page::searchwikipedia_button()");
selenium.waitForPageToLoad("30000");
verifyTrue(selenium.isElementPresent("ui=googleSearch_page::seleniumSearchResult_Link()"));
selenium.click("ui=googleSearch_page::seleniumSearchResult_Link()");
selenium.waitForPageToLoad("30000");
verifyEquals(selenium.getTitle(), "Selenium (software) - Wikipedia, the free encyclopedia");
verifyTrue(selenium.isElementPresent("ui=wikipediaArticle_page::wikipediaGlobe_image()"));
}


@AfterClass
public void tearDown(){
selenium.close();
selenium.stop();
} //end of tearDown()

public static void createUIMAP(String masterUIMAPfilePath) throws java.io.IOException{
RandomAccessFile file = null;
RandomAccessFile fileui = null;
String line = null;
String lineui = null;


File oldFile=new File("lib\\user-extentions.js");
if (oldFile.exists())
oldFile.delete();

FileWriter fstream = new FileWriter("lib\\user-extensions.js",true);
String theFirstLine="var myMap = new UIMap();";
fstream.write(theFirstLine, 0, theFirstLine.length());
file = new RandomAccessFile(masterUIMAPfilePath, "r");
while ((line = file.readLine()) != null) {
System.out.println(line);
fileui = new RandomAccessFile(line, "r");
while ((lineui = fileui.readLine()) != null) {
System.out.println(lineui);
fstream.write(lineui, 0, lineui.length());
fstream.write(System.getProperty("line.separator"));

}
}
fstream.close();
}
}


To run this just right click and choose option 'Run As junit test'. Please remember that in my case the 'selenium-server.jar' fie is in the /lib folder.

You should ideally tuck away the createUIMAP() function and the code to start the selenium-server in a utility class in your project and just be calling them in your test script.

Also note that the testGoogleuimap() test method in this example is from my last post. You can derive this java equivalent of the IDE recording by doing Options-->format-->Java (Junit) - Selenium RC from Selenium IDE. I have just replaced the awfully big while constructs in the script with
selenium.waitForPageToLoad("30000");
As always junit, selenium-server and selenium-client-driver are in the classpath.

Please feel free to post any queries here.

17 Comments:

mgharikrishnan said...

Hi mahesh,

This is hari krishnan from chennai. I am new to selenium testing tool. I dont know where to start. I went thru the basic documents in Selenium site and set up selenium RC setup with JUnit in Eclipse. Do you have any document or study material to carry forward from here?!?!?!

Thanks in advance.

~ Hari...

Mahesh Narayanan said...

Hi hari,
now that you have setup selenium RC with junit you must get into the habit of recording scripts in IDE and then exporting them into the RC environment. Th more you use it the more you learn.

As such I don't have any document but i would say openqa.com and seleniumHQ are good places to start.

best of luck

Unknown said...

Hi Mahesh,

Good blog. one clarfication related to location of userextension.js ? Why it so that ?
regards,
Satyadev

Mahesh Narayanan said...

satyadev, I guess that's how they have made it. I believe this issue will be addressed in the next release of RC. However this does not effect work in any way as we can create this combined map file at runtime from all the child files.

Anonymous said...

I'm just picking up Selenium and want to use ui-element locators but have run into a problem using them with the Selenium RC.

I created a simple ui map file for the login page of my AUT and plugged it into the IDE. When recording, the IDE correctly uses the ui-element locators for the elements within my map file. Note that this only works with my map file as-is, if I combine the ui-element.js file with my map file as described above it stops working.

I also have a java project that performs the same actions on the same controls, only I originally set it up using just xpath locators. I use the selenium server RemoteControlConfiguration setUserExtensions method to load in the same map file I used in the IDE and then I copy the IDE recorded java commands into the java project, replacing the same commands that use the xpath identifiers. However when I run the project I get an error on the first control saying that the element was not found. I even combined the ui-element.js file with my map file (manually) to see if that helped, but no luck.

I'm not sure why my actions in the java project work using the xpath locator strings but not with the ui-element locator strings. I know the map file I am loading works since I can use it correctly in the IDE. I also know the ui-element locator strings are correct since I am getting them directly from the recorded IDE code.

Can anyone tell me what I might be missing? Is there another step to getting ui-elements working with Selenium RC other than loading a working map file and providing valid locator strings? Thanks!

Mahesh Narayanan said...

Hi Anonymous,
In RC

1) the name of the file must be 'user-extension.js'

2)It must be in the same folder as the selenium-server.jar

Try this out and post any queries you may have.

Unknown said...

hi mahesh

i am very impressed with your postings about selenium.
I have experience in QTP but in my current project we are planning to use selenium. Please help me if u have any tutorial to understand selenium integration with eclipse and running selenium IDE tests in selenium RC.

thanks
venkat

Rashmi R Ray said...

Hi Mahesh,

Thanks for such a good blog.

rashmi

Anonymous said...

Hi Mahesh,

many thanks for such a useful post.

Am new to selenium, just started exploring.

i have a mxml where as function is there & registered the same for js call. ExternalInterface.addCallback("getColor", getColor);

Then am calling the same from selenium RC :
flashApp.call("getColor"); flashApp.call("click"));

getColor is returning the default value.
But in click function am getting "Object doesn't support the property " error.

should i register it in user-extension.js?
Plz help me to resolve the issue

Yogendra said...

Mahesh,

Can you please provide us video of above post(selenium rc with ui mapping) like u have given for data driven.I am really not able to start any thing from your above post.

Please help me.

Thanks,
Yogendra.Joshi

Unknown said...

Hi Mahesh,

i trigger selenium server through my ANT build file. Now i want to create object repository on the lines u have explained - UI Mapping. But am facing 2 probs here.
1. UI mapping doesnt seem to work for Selenium-server 1.0.3
2. I am not able to pass user-extension argument in my ant build file for the selenium-server.

Any help would be greatly appreciated

Anil Shekhar said...

Hi Mahesh,

Thanks for the excellent blog.

I am trying to use user-extensions.js with RC. I copied "user-extensions.js" into the same folder as "selenium-server.jar". I still get this error.

User extensions file MUST be called "user-extensions.js"

My command line is
java -jar selenium-server.jar -userExtensions user-extentions.js

Can you please help?

Thanks
Anil

Prabu said...

Mahesh,
Could you please explain how "getLocator" works in selenium RC. I would like to parameterize my XPATH. Is it possible with UImap. if so, how I can do that?

Anonymous said...

HI,I am newbie for selenium RC.i have installed java and selenium RC & eclipse on ubuntu linux.When i add new project on eclipse and do next process but at the time of adding .jar files from lib it is not showing jar files.please guide me its urgent.

Anonymous said...

HI,I am newbie for selenium RC.i have installed java and selenium RC & eclipse on ubuntu linux.When i add new project on eclipse and do next process but at the time of adding .jar files from lib it is not showing jar files and not running created project please guide me its urgent.

please guide me on this line
1.Add the selenium-java-.jar files to your project as references.
i am not finding .jar files when i am trying to add .jar files as references i have already put selenium-java-.jar files in same folder of eclipse.

2.Add to your project classpath the file selenium-java-.jar
How to add classpath in Ubuntu linux.

Anonymous said...

Hi,

I have followed your code and steps as such.But, got the below exception. Could you help me to resolve it?

Thanks in advance.
Sara S

com.thoughtworks.selenium.SeleniumException: Element ui=googleSearch_page::theBigGoogleLogo() not found
at org.openqa.selenium.internal.seleniumemulation.ElementFinder.findElement(ElementFinder.java:96)
at org.openqa.selenium.internal.seleniumemulation.GetText.handleSeleneseCommand(GetText.java:42)
etc etc

Anonymous said...

My Code is:


import com.thoughtworks.selenium.Selenium;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.*;
import org.junit.*;
import static org.junit.Assert.*;
import java.io.File;
import org.openqa.selenium.server.RemoteControlConfiguration;
import org.openqa.selenium.server.SeleniumServer;
//import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;

public class Sample {

WebDriver driver;
Selenium selenium;

@Before
public void startSelenium() throws Exception {
SeleniumServer seleniumserver;
seleniumserver = new SeleniumServer();
RemoteControlConfiguration a= seleniumserver.getConfiguration();
a.setPort(8080);
File uimap=new File("/home/Documents/user-extension.js");
a.setUserExtensions(uimap);
seleniumserver.boot();
seleniumserver.start();
driver = new FirefoxDriver();
selenium = new WebDriverBackedSelenium(driver, "http://www.google.co.uk/");
}

@After
public void stopSelenium() {
selenium.close();
selenium.stop();
}

@Test
public void testSample() {
selenium.open("/");
assertEquals("UK", selenium.getText("ui=googleSearch_page::theBigGoogleLogo()"));
selenium.type("ui=googleSearch_page::search_Textbox()", "selenium");
assertEquals("selenium", selenium.getValue("ui=googleSearch_page::search_Textbox()"));
// selenium.();
}

}