Sprites in the Machine: Selenium Remote Control on Windows
June 15th, 2007 byThe first time I was played with Selenium (the IDE) was a jaw-droppping moment. It was as if little sprites had taken over my computer and were gleefully doing my job. Sitting back and watching a form being filled in, a button selected, links linked — it was an incredible, mafia-man type experience: things were just getting done, and fast. The little guy rushed through my tasks in seconds, cheerfully, leaving green check-marks in his midst, while I sat back and kind of stared, the way you’re supposed to stare at a national monument. These days there are too many hot-dog stands and camera-d tourists at national monuments to merit my awe, but it’s safe to say that my little browser sprite was stepping up to the plate nicely. One could get used to this, I thought. Me, the sprite, and Firefox: what could be wrong in the world?
This didn’t last (amazing how quickly one gets spoiled). The problem with Selenium IDE is that the tests only play back in Firefox. I love Firefox, but the whole gist of my job is that the stuff we do needs to work in all browsers, on all machines (ok, most on most, but you get the idea). At any rate, I went looking for how I could extend the power of Selenium so I could test my web apps cross browser.
There are two approaches: Selenium on Rails (not covered in this article but you can find info here), and Selenium RC (Remote Control). After poking around a bit it seemed that RC was the solution for me. I was testing old apps, not Rails ones, so the Rails solution was overkill — and I had heard a general buzz that RC is a more robust, ‘best-practice’ solution. Whether that’s commonly held wisdom I can’t say (and if anyone wants to do a comparison, I’d love to hear), but it fit my requirements so I dove in.
If you’re not familiar with what Selenium RC lets you do, here: it lets you write tests in most languages (java, perl, python, ruby, php (NOTE: at the time of my testing I could not locate 0.9.1, with php support. It may be available now)) and then run them from the command line. Assuming the selenium server is running (see steps below), a proxy browser is fired up and your script is executed. In short, a browser opens and is interacted with. Each test is run and you’re fed a success or error message. It’s the same process you see when you run tests back using the IDE: your application being lovingly and quickly manhandled by invisible testing men (though based on the current online discussions I should probably make it clear that the gender of the magic sprites is unknown and irrelevant — and that they do not want to have sex with you, even if they are running in heels
)!
To the docs
The openqa docs are great resources. My one caveat is I would suggest a larger font and a clearer navigation scheme. It’s all there though, and it works, so read carefully, try the examples, and be patient.
From here on out I’m going to transcribe the steps I took to get up and running. This is the order I did things, so hopefully this is helpful as a list of steps and guidelines:
STEPS To set up Selenium RC on Windows
- Read the openQA tutorial:
- Download selenium RC here: [NOTE: 0.9.1 says it has php but I couldn't find it anywhere. I got 0.9.0]
- Extract it using winzip
- Put in your c dir (or wherever you keep programs), like so: c:\selenium-remote-control-0.9.0.. I renamed it to selenium, so mine reads c:\selenium. NOTE: make sure you have right java version by typing java –version in your cmd shell. You must have at least 1.5 (1.4???)]. If you don’t, upgrade your java.
- Put selenium.rb in your ruby lib dir so it will be accessible to ruby using require ‘selenium’. If you don’t do this you’ll have to run your scripts from w/in the same directory as selenium.rb: you don’t wanna do that. For me I put it in C:\ruby\lib\ruby\1.8\selenium.rb
- Start Server. You need to run from cmd line from WITHIN your selenium\server dir [ in my case c:\selenium\server] or feed it the path. [NOTE jar is Java Archive: To run an application packaged as a JAR java -jar app.jar]
java -jar selenium-server.jar --interactive.
At this point you can execute commands on the command line or you can execute a standalone script. There are commands in the tutorial that you can follow along with. To do the latter (execute a program), simply navigate to a test (there’s one in ruby/samples called selenium.rb ) and run it. The one that shipped with my ruby opens google and searches for the string “Hello World”.
C:ruby\\samples>ruby selenium.rb
Once this was done, it was time to start working on a real app. I had an 4 y/o php app in a frameset that I decided to use for testing. Motivation: if I got this stuff working, I would never have to manually slog through all the test cases on that app again. Motivation enough!
Making your tests
You can do this one of two ways: Read the API and manually code your tests in your language of choice (I was using Ruby), or, create your test cases by recording your actions in Selenium IDE (in Firefox) and then save as a .rb script. [File-->export tests as...]. The latter is the much more efficient solution: it’s quicker (do instead of write), and it’s a quicker way to learn the API. Not sure what the method for selecting a frameset is? Just select the frameset in the IDE, export, and the script will come out with that method written right in. It’s @selenium.select_frame “framename” btw.
The way I proceeded was to create (record) an individual test for each action. Because it’s a web app and not a unit test, each test has lots of smaller steps in it that create the overall story of what you are doing. Some of my examples are: create_program, create_test_one_question_no_domains, add_evaluation_to_test, add_test_to_program, etc. The same sorts of things we’d give in a list to QA. You can tell what they are by the titles, which is a common-sense way to keep things clear: descriptive naming is the name of the game. When done, I could run each test from my command line, like so:
ruby create_program.rb
and the browser would open and go through all the steps to, in the case above, create a new program in my application. However, this was repetitive: each individual test used the same setup method and only ran itself. So, I created a master suite called createProgramAndTestSuite.rb. I pasted my individual tests as methods into this class, so that in running the suite I’d be executing all the individual actions (tests) necessary to test this part of the app. Now, one line could run my 16 tests at once:
ruby createProgramAndTestSuite.rb
And, bingo: all my previously individual tests: create_program, create_test_one_question_no_domains, add_evaluation_to_test, etc. were all run in one fell swoop.
The other beauty of consolidation it allows you to take advantage of the setup method. The setup method is run before each test so you can start each individual test where it needs to start — rather than backing up to login or some equivalent “setup” (hence the name) actions. You get most of this for free: tests exported from Selenium IDE come with auto-generated setup and teardown methods that you can leave or modify. Also, note that you can customize your variable names and script conventions in the IDE by going to Options->format and choosing the language you’re working with. Putting all my tests in one suite allowed me to DRY up my repetitive setup actions in one place.
My final setup for the suite looks something like this — I added a bunch of stuff to log me in, select the main frame and gets me ready for each individual action.
def setup
@verification_errors = []
if $selenium
@selenium = $selenium
else
@selenium = Selenium::SeleneseInterpreter.new("localhost", 4444, "*firefox", "http://urlofapp.com/", 10000);
@selenium.start
@selenium.open "http://urlofapp.com/admin/admin.php"
@selenium.type "staff_email", "secret@email.com"
@selenium.type "level_passwd", "magic_password"
@selenium.click("login")
@selenium.select_window "main"
@selenium.wait_for_page_to_load "30000"
# more stuff
end
end
the teardown (again run after each test) is the default from the IDE (I did not change this).
def teardown @selenium.stop unless $selenium assert_equal [], @verification_errors end
And my test methods are pretty straightforward — here’s a few lines just to give you an idea of what it looks like:
def test_create_new_program @selenium.click "link=Programs" @selenium.wait_for_page_to_load "30000" @selenium.click "link=create program" # more stuff end def test_create_test_one_question_no_domains @selenium.click "link=Questionnaires" @selenium.wait_for_page_to_load "30000" @selenium.click "link=create questionnaire" @selenium.wait_for_page_to_load "30000" @selenium.click "submit" @selenium.wait_for_page_to_load "30000" @selenium.type "test_name", "Selenium: Test # more stuff end
Testing is verbose and simple. You write a lot, but, like with most tests, I found I relied on a few basic calls again and again. The typical browser work-horses are going to be select, type, click, wait, etc. I found I had to use wait_for_page_to_load a lot. But there’s an API in the contextual menu if you have the IDE installed (right click when you’re recording tests and you’ll see the showAllAvailableCommands submenu that you can insert into your recording tests). Or, you can check out the Selenium API online.
As a result of executing (and recording) all the actions once in the IDE and doing some copy-pasting and rearranging, in a few days you can have a library of test suites for your application, and voila! your app is not only running itself, but, more importantly, testing itself. You no longer have to run these by hand, you can spot errors more quickly, you can test simultaneously on multiple platforms, and you can easily pinpoint, and fix, failures. It’s a beautiful thing.
Of course, there are lots of complicated browser interactions, especially nowadays, that are not easy (or possible) to test in Selenium. Apps using drag-and-drop, for instance. And if you get into RJS or other types of javascript browser effects that we associate with “web 2.0″, you’ll need to look elsewhere. Actually, if folks know resources or have experiences in this domain, please post to the comments so we can build a resource. But, outside of these cases, Selenium RC is great for running acceptance tests. It’s easy to set up, well integrated, and, most importantly, highly addictive.
Happy testing!

June 15th, 2007 at 10:55 pm
sara, you had me at do not. ;p I will definitely try RC.
June 15th, 2007 at 11:39 pm
Sara, thanks for this. I am currently on a freelance assignment, working with one of the Dojo developers, serving Dojo with CherryPy and JSON.
We discussed Selenium, and the Dojo developer thinks that there may be a way to write a js plugin for it. Do you know of anyone doing this? We postponed this for after Alpha, so I don’t know if this would really work or not. I don’t know if Selenium could accommodate even a crude js interface. Can it do this, even if via an API?
Thank you,
Gloria
June 18th, 2007 at 7:56 pm
Hi Gloria, I’ve never heard of that — I haven’t explored plugins for selenium however so I don’t know the range of possibilities that are/not there (beyond what I failed to find on a quick google search). It’s not clear to me what exactly your developer is after in terms of an end-product / end-experience. I’d be curious to hear more. Feel free to post that or any approaches to his goal. thanks – sarah
June 19th, 2007 at 5:57 pm
Here’s a link to a recently released e-Book on testing with Twill and Selenium:
http://www.oreilly.com/catalog/functionalwt/
I haven’t read it, but I suspect it’s worth the $10.
– Dianne
June 22nd, 2007 at 11:41 am
@gloriajw:
I’m not entirely certain what you mean by a “js plugin,” but I should point out that it is already possible to write Selenium RC tests in JavaScript, using Java/Rhino as the JS execution engine.
http://www.openqa.org/selenium-rc/js.html
If you want to write/run your tests entirely within the browser, you’ll have to use HTML Selenese; it’s not possible to write Selenium tests using native browser JS. I’ve written a blog article explaining why:
http://darkforge.blogspot.com/2006/12/implementing-javascript-language.html
June 22nd, 2007 at 12:22 pm
@Dan, thanks for posting the extra info and your blog link.
@Dianne — I’ll check out that book, thanks.
July 17th, 2007 at 1:39 am
Hi Sara,
Thank you for This blog. As you said, though all the information in present in openqa, I found information present in your blog much easier to follow to get started with Selenium. This is my first project in Selenium, and your blog was a good way to start it.
Thanks
July 22nd, 2007 at 2:50 am
Sara,
This is an interesting introduction to Selenium RC. I am wondering why you chose to use the stand-alone Selenium server as opposed to the browser based TestRunner. With the Selenium IDE, it is easy to write your testcases in Selenese. My experience has been with Selenium-on-rails, and it has worked great for apps written in Ruby.
July 23rd, 2007 at 7:16 am
Hi Matthew,
Thanks for your comment. I had a few reasons for my choices. One, I was testing a non-rails app so the selenium-on-rails solution wasn’t appropriate. Two, I wanted to write my tests in Ruby, not selenese (It gave me more flexibilty). Three, I wanted the flexibility of running my tests cross/browser, which I get from RC, w/o installing on the application server (I believe you’re talking about selenium Core when you’re talking about using TestRunner, which needs to be installed on the app server). Here’s a link to “which selenium should I use” that’s helpful in getting a big-picture view of the features / detractions of each iteration: http://wiki.openqa.org/pages/viewpage.action?pageId=763
Let me know if I didn’t answer your question or you have a follow up.
November 16th, 2007 at 4:45 am
I’m finding this article really helpful, thanks a lot!
December 19th, 2007 at 3:29 am
Hi All,
I am an QA engineer, trying to automate my application using Selenium RC plus Ruby.
I have created individual class files which contain different Methods, I am stuck at calling all those different methods from a Main file.
Can you please assist or advice on the same how it works, coz i was able to call first method and it ran successfully but my second method requires the selenium called during first method to be active and start the second method.
Can anyone enrich me on this issue!!
Cheers
December 26th, 2007 at 2:48 am
Hi All,
Very nice presentation from Sarah. It is very useful to beginners as well as intermediate to follow Selenium.
Regards,
P.Raveendran
May 20th, 2008 at 2:17 am
You have explained how to run Server. Its OK. But you did not explain how to execute Java Tests(Commands to execute). Without executing how will you get results? If you run tests from command line where will you get Results of tests?
First of all, If you do every thing from command line,What is the use of Selenium Client?
If you have answers, Please explain me.
July 2nd, 2008 at 7:30 am
Hey Sarah,
That’s one of the best articles on starting with selenium RC I have found on net.
Do write more.
Thanks
-Ankush
July 5th, 2008 at 10:07 pm
selenium for horses…
You must put a lot of work into blogging this much!…