Nearing the End

Selenium Confusion

Selenium-RC

I just want to write a Python script to test a web site. I would use twill but it's a Javascript-enabled site so I'll need Selenium instead.

I know a little bit about Selenium already. I tried it weeks ago. It's a Javascript librray that runs under a browser. The mode I tried allows for tests to be created interactively via the web interface. That much worked and was impressive. But now I want to go to the next level, to write a Python script to perform the same sort of testing. Now I will need Selenium-RC (Selenium Remote Control, formerly known as "Driven" Selenium).

I got the latest Selenium-RC code from the official page. The good news is that the selenium-remote-control-0.7.1.zip file unzips and I see that it contains directories of code for Python (as well as dotnet, Java and Ruby).

The python/ directory contains

  • selenium.py - Selenium-RC API
  • doc/ - API doc extracted from selenium.py
  • test_google.py - Example test case against google.com
  • a few other example scripts

The test_google.py script is exactly what I need. If I can just get this to work then I'll be in business.

Selenium Server

From the Selenium-RC page:

Selenium Remote Control provides a Selenium Server, which can automatically start/stop/control any supported browser.

Hmm, Selenium Server? It does! There's a selenium-remote-control-0.7.1/server/ directory that contains a jar file. Wow, I had heard that Selenium-RC required a local web server (e.g. Twisted, specifically Twisted 1.3.0) but maybe this is all I need.

Yes, this seems to eliminate the need for using Twisted. There's a large section of javadoc generated documentation. Here's a high level description of the "server" from the docs.

SeleniumServer: Provides a server that can launch/terminate browsers and can receive Selenese commands over HTTP and send them on to the browser.

Selenium Core

Again, from the Selenium-RC page:

It works by using Selenium Core, a pure-HTML+JS library that performs automated tasks in JavaScript.

"It" is either the Selenium Server and/or Selenium-RC. In either case I should expect to see some js code. As advertised the js is in the Selenium Core archive, selenium-0.6.0.zip.

The install-readme.txt says

Copy the "selenium" folder to a web accessible directory in the same web server as the application you want to test. In Apache, this would mean a subdirectory of "htdocs".

That's simple enough. But I'm not interested in testing apps served by my local Apache server. I want to test web apps running on remote servers such as google.com.

These instructions seem to be for the non-RC mode of Selenium. How do I make Selenium Core accesible to Selenium-RC??

Blog to the Rescue?

I found Grig Gheorghiu's blog entry: Running the Selenium Twisted server on Linux.

This is a revised explanation of how to install and run Selenium in "Driven Mode"... oh, but with Twisted. That might be a step backwards. Plus, I had to leave a comment for Grig saying that I ran into a dead end.

Help!

I just found these links in the left margin of the Selenium-RC page.

Using Selenium Remote Control

It looks impressive but both links take you to the same tutorial page. Still, I'm grateful for the help.

Finally, How To run Selenium-RC, on Linux with Python and Firefox

Interactive mode:

  • Install the JRE
    • Verify: java -version
  • Add the Firefox directory to your PATH and LD_LIBRARY_PATH
    • PATH=$PATH:~mudd/pkgs/firefox
    • LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~mudd/pkgs/firefox
  • Start the Selenium Server
    • cd selenium-remote-control-0.7.1/server
    • java -jar selenium-server.jar -interactive
    • Be patient. You'll get the following exception if you enter a blank command, or even any leading whitespace in front of a valid command. And it's very easy to get an extra leading blank when the command is copied from the Selenium Tutorial page via cut-n-paste.
---> Requesting http://localhost:4444/selenium-server/driver?
java.io.IOException: Server returned HTTP response code: 403 for URL: http://localhost:4444/selenium-server/driver/
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
        at java.net.URLConnection.getContent(Unknown Source)
        at org.openqa.selenium.server.SeleniumServer$3.run(SeleniumServer.java:263)
        at java.lang.Thread.run(Unknown Source)

Note: Selenium Server uses 3.3 GB of memory on my PC. Thanks, Java!

Python driven Selenium-RC

Switch to the python/ directory. Run the same test of google.com by executing the test_google.py script. Here's what I got back.

======================================================================
ERROR: test_google (__main__.TestGoogle)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_google.py", line 24, in setUp
    self.selenium.start()
  File "/home/mudd/pkgs/selenium-remote-control-0.7.1/python/selenium.py", line 110, in start
    result = self.get_string("getNewBrowserSession", [self.browserStartCommand, self.browserURL])
  File "/home/mudd/pkgs/selenium-remote-control-0.7.1/python/selenium.py", line 139, in get_string
    result = self.do_command(verb, args)
  File "/home/mudd/pkgs/selenium-remote-control-0.7.1/python/selenium.py", line 127, in do_command
    conn.request("GET", commandString)
  File "/usr/local/lib/python2.4/httplib.py", line 801, in request
    self._send_request(method, url, body, headers)
  File "/usr/local/lib/python2.4/httplib.py", line 824, in _send_request
    self.endheaders()
  File "/usr/local/lib/python2.4/httplib.py", line 795, in endheaders
    self._send_output()
  File "/usr/local/lib/python2.4/httplib.py", line 676, in _send_output
    self.send(msg)
  File "/usr/local/lib/python2.4/httplib.py", line 643, in send
    self.connect()
  File "/usr/local/lib/python2.4/httplib.py", line 627, in connect
    raise socket.error, msg
error: (111, 'Connection refused')

----------------------------------------------------------------------
Ran 1 test in 0.242s

FAILED (errors=1)

This only failed because I didn't already have the Selenium Server up and running. Once I started it back up the Python script worked as expected.

$ python test_google.py
.
----------------------------------------------------------------------
Ran 1 test in 42.870s

OK
$

Amazing. No Selenium Core required. No Twisted required. (Not that there's anything wrong with Twisted! IMO, Guido missed the boat when he passed over Twisted Web + Nevow.) I have arrived at web testing nirvana.

Note: The sample .py files are formatted with \r\n at the end of each line. This may cause some confusion if you're running on Linux.

FAQ

How to open a URL with subdirectories?

Example URL: http://10.41.29.72:9001/console

First, open the main url by instantiating the selenium class.

sel = selenium('localhost', 4444, '*firefox', 'http://10.41.29.72:9001')

Then, use the open() method to open pages relative to the main url.

sel.open('/console')

How to click a button without an Id?

Example HTML for button labeled as "Sign In":

<TD>&nbsp;</TD>
<TD align="right" nowrap><input type="submit" class='buttons' value="Sign In"></TD>
<TD width="100%">&nbsp;</TD>

Selenium-RC code:

sel.click("//input[@value='Sign In']")

From Selenium-RC User Forum.

getbodytext()

getbodytext() doesn't give me what I expect. I was hoping for the same thing I get from the browser when I select View/Page Source. In some cases getbodytext() returns just an empty string. Is there a way to get the real page source?

The only reason I want the page source is so I can parse it and manually navigate the frames. Any suggestions on how to use Selenium-RC to navigate frames? I just need to select the second frame so I don't mind a hard coded solution.

Frame support isn't officially available in Selenium Core or Selenium RC, but any workaround you can devise may be good enough.

In this case, you may be encountering a problem with long command results, e.g. SRC-43. http://jira.openqa.org/browse/SRC-43

We've fixed SRC-43 for 0.7.2, which I hope to release as soon as I have the time. In the meantime, you might try using the nightly snapshot build available here.

-Dan

Links