[rc] Selenium RC with user-extensions.js and Python

623 views
Skip to first unread message

Jay

unread,
Jul 30, 2010, 7:52:47 PM7/30/10
to Selenium Users
Can someone write clear steps on how to setup user-extensions.js for
RC?

The Documentation on the SeleniumHQ site only displays instructions
for C# and it is hard for someone new to grasp it. I am writing all of
my scripts in Python so I do not know if that will make a difference
in setup for user-extensions.

I have tried copying the .js file directly into selenium-server.jar
but that does not work for me. The error I keep receiving is:

"Attribute Error: selenium instance has no attribute"

I don't understand why this would work in IDE but will not work in
RC.


Ross Patterson

unread,
Aug 2, 2010, 9:05:56 AM8/2/10
to seleniu...@googlegroups.com
All you should have to do is name the file "whatever/user-extensions.js" and specify it's name on the Selenium RC command line, and Selenium Core will load it up when the browser is started. Here's how we do it:

java -jar selenium-server.jar -userExtensions user-extensions.js -browserSideLog -singleWindow

The error you're describing doesn't sound like a problem with your user extensions.js being unavailable. You'll have to be a little more forthcoming if you want a hand.

Ross

Jay

unread,
Aug 2, 2010, 12:47:23 PM8/2/10
to Selenium Users
Thanks for your response Ross.

I will include the script and user-extension file I have created. I
have been trying to figure this out for the past 2 days and I really
do not understand why it works in IDE but not RC.

Test Case Script:

from selenium import selenium
import config
import unittest, time, re

class UREG(unittest.TestCase):

def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost", 4444, "*firefox",
config.testEnv)
self.selenium.start()

def test_UREG(self):
sel = self.selenium
sel.open(config.testEnv)
sel.click("link=Login/Register")
sel.wait_for_page_to_load("30000")
sel.click("//div[@id='login-right']/div/p[3]/a/img")
sel.wait_for_page_to_load("30000")
sel.type("edit-firstName", config.fName)
sel.type("edit-lastName", config.lName)
sel.type("edit-password", config.pwd)
sel.type("edit-passwordConfirm", config.pwd)
sel.type("edit-organizationCompany", "VMware")
sel.select("edit-jobDescription", "label=Consultant")
sel.type("edit-address1", "3401 Hillview Ave")
sel.type("edit-city", "Palo Alto")
sel.select("edit-state", "label=California")
sel.type("edit-zip", "94304")
sel.select("edit-isoCountryCode", "label=United States")
sel.type("edit-phoneNumber", "650-475-5000")
sel.type("edit-emailAddress", config.email)
sel.click("edit-next")
sel.wait_for_page_to_load("30000")
sel.type("edit-displayName", config.commName)
sel.click("edit-confirm-community-terms-of-use")
sel.ScrollDown("terms-of-use")
sel.click("edit-confirm-marketplace-terms-of-use")
sel.click("edit-next")
sel.wait_for_page_to_load("30000")
sel.click("edit-next")
sel.wait_for_page_to_load("30000")

# def tearDown(self):
# self.selenium.stop()
# self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
unittest.main()

user-extensions.js file

// User extensions can be added here.
//
// Keep this file to avoid mystifying "Invalid Character" error in IE


Selenium.prototype.doScrollDown = function(locator) {
var element = this.browserbot.findElement(locator);

element.scrollTop = element.scrollHeight;
};

And here is the command I am using to start the server:

java -jar selenium-server.jar -userExtensions "C:\SeleniumCore\core
\scripts\user-extensions.js" -browserSideLog -singleWindow -
firefoxProfileTemplate "C:\Firefoxselenium"

Any direction you can provide would be greatly appreciated!

Thanks,
Jay

Ross Patterson

unread,
Aug 3, 2010, 9:46:11 AM8/3/10
to seleniu...@googlegroups.com
>Sent: Monday, August 02, 2010 12:47 PM

>
>I will include the script and user-extension file I have created. I
>have been trying to figure this out for the past 2 days and I really
>do not understand why it works in IDE but not RC.

I'm obviously not in a position to try your test myself, but I would expect it to work, at least up to this point:

> sel.ScrollDown("terms-of-use")

At that point, I wouldn't be surprised if Python gave you an error message telling you that "ScrollDown" doesn't exist. Unless you've done something to define your new command to the Python "selenium" object, there's no way for it to know that it exists. If you take a look at selenium.py in the Selenium Python package, you'll see that almost all the commands are defined very simply as either "self.do_command('...commandname...', [...arguments...])" or "return self.get_...datatype...('...commandname...', [...arguments...])", depending on whether they are "actions" or "accessors" respectively.

You have several options for using your new Selenium command. The cleanest is probably to create your own subclass of "selenium" and implement the command yourself. My Python doesn't get a lot of exercise, but I'd expect something like this would do the job:

class mySelenium(selenium):
def __init__(self, host, port, browserStartCommand, browserURL):
super(mySelenium, self).__init__(host, port, browserStartCommand, browserURL)
def ScrollDown(self, locator):
self.do_command("scrollDown", [locator, ])

Note that the command you send to Selenium RC is "scrollDown", not "ScrollDown". And then to use it:

class UREG(unittest.TestCase):
def setUp(self):
self.verificationErrors = []

self.selenium = mySelenium("localhost", 4444, "*firefox", config.testEnv)


self.selenium.start()
def test_UREG(self):
sel = self.selenium

...


sel.click("edit-confirm-community-terms-of-use")
sel.ScrollDown("terms-of-use")

...

Ross

Jay

unread,
Aug 3, 2010, 5:50:16 PM8/3/10
to Selenium Users
Thanks for your response Ross. I tried the proposed solution above and
I am getting "mySeleniun is undefined"

I copied the code and double checked it and it seemed ok to me. I
might be missing something. I tried this command also to import the
new mySelenium class but it did not work:

from selenium import mySelenium

I receive an "unable to import module" when trying to import the new
class.

On another note, I was under the assumption that I did not need to
declare this command in selenium.py since I have wrote the code
(javascript) in user-extensions.js. Shouldn't RC be able to read the
command from there?

I have also seen the preferred method of using HTTPCommandProcessor in
the selenium tutorial but the code is written only in C#. I am not
sure if this would apply to python nor how to convert it from C# to
python.

If you have another solution to try, please let me know.

Thanks,
Jay

Ross Patterson

unread,
Aug 4, 2010, 8:54:04 AM8/4/10
to seleniu...@googlegroups.com
>Sent: Tuesday, August 03, 2010 5:50 PM
>Subject: [selenium-users] Re: [rc] Selenium RC with user-extensions.js and Python

>
>Thanks for your response Ross. I tried the proposed solution above and
>I am getting "mySeleniun is undefined"
>
>I copied the code and double checked it and it seemed ok to me. I
>might be missing something. I tried this command also to import the
>new mySelenium class but it did not work:
>
>from selenium import mySelenium
>
>I receive an "unable to import module" when trying to import the new
>class.

These all sound like issues a Python programmer ought to be able to solve. I rarely use Python myself, but I know enough to be able to play around with it and answer questions like yours yesterday. Until you get the subclass of "selenium" to be usable by your test script, you'll of course have no luck with Selenium RC and your command. Sorry, but I can't be of any help with this.

>On another note, I was under the assumption that I did not need to
>declare this command in selenium.py since I have wrote the code
>(javascript) in user-extensions.js. Shouldn't RC be able to read the
>command from there?

Nope. Most of the Selenium RC client packages, including the Python client, are built by scanning the Selenium Core "selenium-api.js" file and creating callable wrappers for all the commands that are found. Your command isn't there, so no wrapper was created. And you probably didn't build the Selenium RC Python client yourself, so even if you had put your extension into selenium-api.js, there still wouldn't have been a wrapper because, well, it wasn't there when it was built.

>I have also seen the preferred method of using HTTPCommandProcessor in
>the selenium tutorial but the code is written only in C#. I am not
>sure if this would apply to python nor how to convert it from C# to
>python.

The Python equivalent of the Selenium RC C# client's HTTPCommandProcessor module is so lightweight that it almost doesn't exist. The C# suggestion of 'string[] inputParams = {"Hello World"}; proc.DoCommand("alertWrapper", inputParams);' is essentially the same as the body of what I suggested for your "scrollDown()" method, so I expect this would work: 'sel.do_command("scrollDown", [locator, ])'

Ross

Adam Goucher

unread,
Aug 4, 2010, 5:05:07 PM8/4/10
to seleniu...@googlegroups.com

> Nope. Most of the Selenium RC client packages, including the Python client, are built by scanning the Selenium Core "selenium-api.js" file and creating callable wrappers for all the commands that are found. Your command isn't there, so no wrapper was created. And you probably didn't build the Selenium RC Python client yourself, so even if you had put your extension into selenium-api.js, there still wouldn't have been a wrapper because, well, it wasn't there when it was built.
>
Actually, the 1.x drivers were made from parsing an xml file that had
the api in it with an xsl stylesheet to produce them. (Bit of trivia for
you that might come in handy at some point. Likely not, but you never
know...)

-adam

Adam Goucher

unread,
Aug 4, 2010, 5:11:52 PM8/4/10
to seleniu...@googlegroups.com

> On another note, I was under the assumption that I did not need to
> declare this command in selenium.py since I have wrote the code
> (javascript) in user-extensions.js. Shouldn't RC be able to read the
> command from there?
>
Se is JS at its core wrapped in a java server. By using the
-user-extension option, it will inject your js into the frame/window
running your script. That's all it does.

The Python bindings are convenience wrappers around calls into the Se-RC
server. They are completely disconnected. You will have to define the
scrolldown method yourself and import it into your tests in order to
have it executed on the server. Something like this should do the trick.

def scroll_down(self, locator):
self.do_command("scrollDown", locator)

That function provides the bridge from Python to the Server which knows
about your custom bit of JS.

-adam

Jay

unread,
Aug 5, 2010, 2:07:59 PM8/5/10
to Selenium Users
Thank you for your explanation Adam.

I tried to define the command using the exact same code myself in
selenium.py but it displays the following error:

"selenium instance has no attribute "scollDown"

You mentioned I would need to import this command into my tests. Would
the "from selenium import selenium" code do the trick since I am
defining the new command in the same default "selenium" class in
selenium.py? Would I have to import the command a different way?

Thanks,
Jay Mey

Jay Mey

unread,
Aug 5, 2010, 6:38:48 PM8/5/10
to Selenium Users
Sorry, thats a typo in the error message. I did spell it correctly in
my scripts.

Jay Mey

unread,
Aug 5, 2010, 8:35:09 PM8/5/10
to Selenium Users
My manager helped me figure out the problem I was having. It turns out
that the selenium.py file that was being referenced is in another
location than the one I was changing.

The above works! Thank you for your help!

-Jay Mey
Reply all
Reply to author
Forward
0 new messages