The Selenium Guidebook

If you’ve somehow stumbled across this lost blog of mine, you are probably interested in Ruby and Selenium WebDriver. If that is the case, I would highly recommend you go check out The Selenium Guidebook written by my internet friend Dave Haeffner.

This is a great guide for starting out learning how to write automated Selenium tests. It also delves into more advanced material as Dave walks the reader through creating Page Objects, developing a framework, and solving tricksey issues that are bound to come your way.

This should be required reading for anyone interested in learning Selenium. What are you waiting for? Go check it out already!


Debugging your scripts with Pry

One cool thing that came out of SelConf 2013 (I wasn’t able to attend … just experienced it online) was Dave Haeffner‘s new Selenium tutorial Elemental Selenium. Its an email newsletter published once a week with a Selenium tip (in Ruby!) focusing on the basic foundations of how to solve certain problems. This is mainly aimed at beginning Selenium users, but anyone using Selenium and Ruby would find the tips useful. I have learned some new ideas and ways to address certain problems that I hadn’t thought of before from some of his tips. You can also browse the repository of archived tips on the website as well.

After Dave posted tip 11 about building a simple REPL to debug your tests, I started up a conversation with him about the benefits of using Pry over writing a simple debugger. The sum total of the conversation resulted in Dave asking me to write a guest tip on the subject.

LOL, I think it turned out pretty well. Go check it out and let me know your thoughts.

Highlighting the element before any clicks: A foray into the AbstractEventListener

Last week I wrote a post about how you can create a highlight method to help you visually find an element that you have selected. In the comments section, wiiniRyan suggested implementing the highlight method before all clicks occur using one of the Abstract Event Listeners hooks provided in the Selenium::WebDriver::Support module. Only thing was, he couldn’t figure out how to use the hooks according to his comments, and suggested that I might be able to provide some insight.

His comments intrigued me, so I did a little bit of research and hands on testing to figure out how these hooks work.

I looked at the documentation, but didn’t see anything real obvious about how to hook into them. My first attempts simply tried to subclass the AbstractEventListeners class, but that did no good, since the driver had no way to interface with the overridden hooks.

It wasn’t until I read a small crucial line after the #for method call on the main WebDriver documentation page that I figured out how these hooks worked:

One special argument is not passed on to the bridges, :listener. You can pass a listener for this option to get notified of WebDriver events. The passed object must respond to #call or implement the methods from AbstractEventListener

Essentially, you need to create a class with either every method hook defined, or use the generic #call method to delegate the hooks as they occur.

# Either
class AbstractDefineEveryMethodTest
  def before_click *args
    # .. do stuff
  def before_#... rest of the hooks defined
# The downside to the above is that every single method
# hook needs to be defined, or else things will blow up
# when the hook tries to be called.
# Or, more efficiently
class AbstractHandleCallMethodTest
  def call *args
    # only need to deal with the hooks you are interested in
    case args.first
    when :before_click
      puts "Clicking #{args[1]}"
      # .. do stuff
    when :before_find
      puts "Finding #{args[1]} => #{args[2]}"
      # .. do other stuff

After creating this class, then we just create a new instance of the class and pass it into the initialization of our WebDriver browser:

ael =
driver = Selenium::WebDriver.for :firefox, :listener => ael

So, now when you find an element and click it, you will see the following output:

driver.find_element(:css => "h1").click # =>
Finding css selector => h1
Clicking #<Selenium::WebDriver::Element:0x000000022f6528>
=> "ok"

So, its a simple matter of adding the highlight method to the AbstractEventListener and using the #call method to call highlight when we want to.

class HighlightAbstractTest
  def highlight element, driver
    orig_style = element.attribute("style")
    driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", element, "style", "border: 2px solid yellow; color: yellow;")
    sleep 1
    driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", element, "style", orig_style)
  def call *args
    case args.first
    when :before_click
      highlight args[1], args[2]
hat =
driver = Selenium::WebDriver.for :firefox, :listener => hat
driver.find_element(:css => "h1").click # => Be sure to watch in your browser window for the highlight to appear!
driver.find_elements(:css => "input[type='button']").each{|b| } # => Be sure to watch in your browser window for the highlight to appear!

A couple words of caution:

First, if you are going to define each hook instead of using the recommenended #call method, be sure you define each and every hook inside your class. Otherwise, if that hook attempts to be executed, you will get a nasty error message about not being able to find the method.

Second, not all of the hooks provide the same parameters. In fact, the only hooks to include the element and driver, which are needed for the highlight method to work are the before_click, before_change_value_of (still trying to figure out when that one is triggered), after_click, and after_change_value_of. The other hooks have different parameters according to their respective function, which can be found by RTFM. Don’t get burned when you expect before_find to pass the whole element as a parameter. And I wouldn’t recommend trying to get the actual element inside this hook with the by and what parameters, lest you create an infinite loop.

AbstractEventListener seems like an interesting idea, but is a little bit complicated to set up. Also, I am not sure what other use cases might come from implementing these hooks. If you have some ideas, please share them in the comments!

Did I select the right element?

Time and time again, I will find unexpected behavior in my tests (either from an error, or the wrong text being displayed, etc), and I need to fallback to determining if I’m even using the correct element.

Two very handy methods that I created allow me to debug whether I have selected the right element. They are highlight and html:


This method allows me put a temporary bright yellow border around the element in question. This gives me a visual clue of which element is selected when I look at the browser.

  def highlight element, time = 3
    orig_style = element.attribute("style")
    @driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", element, "style", "border: 2px solid yellow; color: yellow; font-weight: bold;")
    if time > 0
      sleep time
      @driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", element, "style", orig_style)
  some_field = @driver.find_element(:css => "input.text") #=> <Selenium::WebDriver::Element ... >
  highlight some_field #=> nil (But look at the browser, and you should see the element get highlighted for three seconds)
  highlight some_field, 10 #=> nil (But look at the browser, and you should see the element get highlighted for ten seconds)
  highlight some_field, 0 #=> nil (But look at the browser, and you should see the element get highlighted, and stay highlighted)


This method allows me to see the actual HTML code of the element in question. I can use it to compare to the DOM of the actual page if I still don’t “see” the element on the page.

  def html element
    @driver.execute_script("var f = document.createElement('div').appendChild(arguments[0].cloneNode(true)); return f.parentNode.innerHTML", element)
  some_div = @driver.find_element(:css => "div.something") #=> <Selenium::WebDriver::Element ... >
  puts html(some_div) #=> "<div class=\"something\" ... </div>"


If you wanted to get really clever, you could open up the Selenium::WebDriver::Element module directly and add those methods in directly:

module Selenium::WebDriver
  Element.module_eval do
    def highlight time = 3
      orig_style = self.attribute("style")
      @driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", self, "style", "border: 2px solid yellow; color: yellow; font-weight: bold;")
      if time > 0
        sleep time
        @driver.execute_script("arguments[0].setAttribute(arguments[1], arguments[2])", self, "style", orig_style)
    def html element
      @driver.execute_script("var f = document.createElement('div').appendChild(arguments[0].cloneNode(true)); return f.parentNode.innerHTML", self)
some_field.highlight #=> nil (But look at the browser, and you should see the element get highlighted for three seconds)
some_div.html #=> "<div class=\"something\" ... </div>"

Using both of these methods in conjunction, I can always figure out which element I have selected during my interactive coding process.

Solving window.onbeforeunload nasty prompts

One of our tests that we run continuously is an iteration over all the pages in our control room app, checking to ensure the page loads without any error keywords. On a particular set of pages, there are Javascript window.onbeforeunload event listeners that generate the nasty prompts that want the user to verify they do indeed want to leave the page (presumably without saving their work).While looking into the application code, I notice that window.onbeforeunload gets set after every autoSave (application) call, which of course happens at random/timed intervals as well as when certain events are fired.

My first attempts at addressing this issue looked something like this:

@driver.execute_script("window.onbeforeunload = undefined;")
@driver.find_element(:css => "a.unload_prompt").click
## Wait for next page ... hope that a race condition doesn't occur

This worked most of the time. But one out of ten or fifteen times, the race condition would occur where the autoSave js call would occur just after I cleared the window.onbeforeunload and just before the element actually got clicked. This re-set the unload prompt, and caused the extremely frustrating

Selenium::WebDriver::Error::UnhandledAlertError: Modal dialog present

error to appear, failing my control room tests from that point on. ūüė¶

If you are one of the many users struggling with this, never fear. There is hope!

It all centers around the brilliance of what click returns. If we are just clicking on a regular link that either takes us to a page or executes some javascript, we get this response:

pry> @driver.find_element(:css => ".homepage a").click
=> "ok"

If we click a link that shows this window.onbeforeunload prompt:

pry> @driver.find_element(:css => "a.unload_prompt").click
=> "Are you sure you would like to leave this page?"

Aha! Webdriver is nice enough to detect that this unload is going to throw a nasty prompt and sends it back through the JSON Wire to be returned to the Ruby call to click. So how does this solve our issues? We can just get and accept the alert to continue on in the page!

pry> @driver.switch_to.alert.text
=> "Are you sure you would like to leave this page?"
pry> @driver.switch_to.alert.accept
=> ""

Thus, we can update our code to conditionally take care of the alert if the click returns anything other than an ok response:

click_resp = @driver.find_element(:css => "a.unload_prompt").click
@driver.switch_to.alert.accept unless click_resp.eql?("ok")
## Continue on to the next page, etc...

And that is how you solve this nasty problem!

Headless Gem causes Errno::ECONNREFUSED

Have you ever gotten this error while trying to run simultaneous headless Firefox instances of WebDriver?

Errno::ECONNREFUSED: Connection refused - connect(2)
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `initialize'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `open'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `block in connect'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `connect'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:744:in `start'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:1284:in `request'

This one was plaguing me for a while. I could not understand why Firefox could not run separate instances of itself, when the SWD documentation indicated that each run used an entirely separate temporary Firefox profile, and so the instances would not conflict with each other.

But sure enough, if I started another job while one was already running, I would get the above error on the first job, while the second job hijacked the connection.

After really delving into the issue, I finally realized that the issue was not the Firefox profiles conflicting. Instead, the issues came from my usage of the headless gem to run the jobs headlessly using Xvfb. I was not defining a specific display to use when my scripts ran, and so the headless gem would default to using the :99 display. This was all fine and good when running the scripts individually. But if you run multiple scripts that try to use the same display, the first script gets disconnected from the headless session and the second script takes over.

The solution to this problem is to explicitly define a display number to use for each script that runs. This works especially well if you are running your scripts in a CI environment like Jenkins, where each build is given its own number that you can easily access as an environmental variable such as “BUILD_NUMBER”. Other ideas are to generate a random display number on the fly, or use another means to generate any integer number.

display = ENV['BUILD_NUMBER'] || "99"
@headless = => display)

This will generate a headless session on the display number that is defined by the BUILD_NUMBER environmental variable, and as long as the build numbers are completely different from each other, you will be good.

How did I miss this? Ruby bindings support CSS compound selectors!

I just came across this … but it has saved me from begging a developer to make a simple DOM tweak to a part of the site that no one really cares too much about.

CSS selectors in general web design allow you to specify multiple selectors, called compound selectors, to apply styling to using a comma between each selector. Why shouldn’t SWD?

Well, today I learned that indeed it does (since the 2.24.0 version from 06-19-2012)!

How do you use this? Well, let’s say you have a portion of the DOM that could have either a “p” or an “a” tag, you could write something like this to select one OR the either :

@driver.find_element(:css => "a, p")

This will select the first element that SWD comes across, regardless of which order you write the selectors. Thus, given this HTML

<div id="outer">
  <span id="inner">Foo</span>
<span id="last">Bar</div>

You could write a selector

@driver.find_element(:css => "#last, #outer")

And it would select the div with the id of “outer” because it is the first selector that is found in the DOM. Same goes for child descendents. Writing a selector like this

@driver.find_element(:css => "span#inner, #outer")

will select the “outer” div again.