Getting chromedriver to work with Ruby selenium-webdriver under OSX Mavericks

I interrupt my soprano-saxophone-and-bass-guitar-playing evening to write very quickly about something that annoyed me today. I can’t find the fix anywhere else on the internet, so i guess it’s up to me to provide the solution.

Yesterday i upgraded to OS X Mavericks. Which is nice. Free upgrade, woo! Most things work well, though i had a few Java version issues.

Today i found that selenium-webdriver was not able to launch Chrome with chromedriver. It would open and immediately quit.

A quick google reveals that the workaround is to start chromedriver with the --verbose flag and then it magically works again. Which is true in my experience. But all the examples are for selenium wedriver called by Java or Python and i couldn’t find one for Ruby.

The first thing i did was upgrade selenium-webdriver gem to 2.37.0 and chromedriver to 2.4. I checked my version of Chrome; it is 30.0.1599.101 which is apparently up to date. When none of those things made any difference, I investigated the verbose option.

I thought i would just have to pass --verbose to the Capybara::Selenium::Driver via the args or switches option. But no. That will send the flag to Chrome when it launches, but i need the flag to be set on chromedriver.

Ruby open source to the rescue!

I poked around in the source code for service args and found this:

# selenium/webdriver/chrome/bridge.rb

module Selenium
  module WebDriver
    module Chrome

      class Bridge < Remote::Bridge

        # ...

        def extract_service_args(opts)
          args = []

          if opts.has_key?(:service_log_path)
            args << "--log-path=#{opts.delete(:service_log_path)}"
          end

          args
        end

        # ...

      end
    end
  end
end

Hmm, so the only service arg you can set is the --log-path. That’s no good.

Ruby monkey patching to the rescue!

In my cucumber features folder i made a support file to monkey patch that method, and add a possibility of sending any service args i like.

# features/support/selenium_webdriver_monkey_patch.rb

module Selenium::WebDriver::Chrome
  class Bridge
    def extract_service_args(opts)
      args = []
      args += opts.delete(:service_args) if opts.has_key?(:service_args)
      args << "--log-path=#{opts.delete(:service_log_path)}" if opts.has_key?(:service_log_path)
      args
    end
  end
end

Now in my env.rb file i just have to require the monkey patch file and i’m able to send the verbose flag.

# features/support/env.rb

# ...

require 'selenium-webdriver'
require 'selenium_webdriver_monkey_patch'

# ...

Capybara.register_driver :selenium_chrome do |app|
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    service_args: ["--verbose"])
end

# ...

Hey presto, now i can set the verbose flag on chromedriver, and sure enough, it works. I am testing in Chrome again.

It seems a really horrible hack, and i hope a better solution is found soon, either from a Mavericks update, or chromedriver, or maybe selenium-webdriver will add this option for service args in a future version.

I still don’t really know why verbose works when normal mode does not. But there we go. I can test again tomorrow, and that makes me happy!

Now, back to my bass guitar! :)

Alphabetical Pagination, version 0.2.3

Thanks to a few people’s input we’ve got a few improvements and fixes to our alphabetical pagination plugin.

There is now a handy helper you can use for the pagination links:

<%= alphabetically_paginate(@pins) %>

At a request from our user experience guru, it lists all the letters of the alphabet and links the active letters. For example:

New alphabetical pagination helper

The best news is, the old way still works, so it’s backwards compatible. You don’t have to use the helper if you don’t want to.

Rails alphabetical pagination

A common problem we often run into at eden is paginating a list of things alphabetically. I thought it was possible with will_paginate but apparently not, so yesterday we created our own simple solution, and today we rolled it into a plugin.

Here’s a little tutorial of how to use it.

So i have a nice simple view of Gowalla pins ordered by name. Please forgive the scaffolding! ;)

Gowalla pins

This page is quite long. Of course, we could use standard pagination to make it 10 per page or something, but it wouldn’t be very helpful if you were looking for a pin with a particular name. You’d have to click through the pages to find it. Wouldn’t it be neat to list a page for each letter?

Enter paginate_alphabetically!

Simply install it as a plugin:

rails plugin install http://github.com/edendevelopment/paginate_alphabetically.git

Enable pagination in the model:

class Pin < ActiveRecord::Base
  paginate_alphabetically :by => :name
end

Make the controller fetch the right pins:


class PinsController < ApplicationController
  def index
    @pins = Pin.alphabetical_group(params[:letter])
  end
end

Add pagination links in the view:

<ul class='pagination'>
  <strong>Jump to:</strong>
  <%- Pin.pagination_letters.each do |letter| -%>
    <li><%= link_to(letter, pins_path(:letter => letter)) %></li>
  <%- end -%>
</ul>

Perhaps a touch of CSS:

ul.pagination {
  list-style: none;
  color: lightgray;
  padding: 1em 0.5em;
}

ul.pagination strong {
  color: black;
}

ul.pagination li {
  display: inline;
  font-size: 1.1em;
}

ul.pagination li:before {
  content: '| ';
}

And here it is:

Gowalla pins beginning with E

The cool thing is you can add this to any of your models, and paginate by any attribute you wish.

Tested with Rails 2.3.5 and Rails 3 release candidate.

Get it from github: http://github.com/edendevelopment/paginate_alphabetically
or RubyGems: http://rubygems.org/gems/paginate_alphabetically

Thanks to Tom, Enrique and tooky for their help making this.