webrat and selenium

66 views
Skip to first unread message

Alberto Perdomo

unread,
Dec 1, 2008, 2:54:03 PM12/1/08
to webrat
Hi,

I am trying to have a standard setup where i have many cucumber
features that i run with webrat and then the JS features which i run
with webrat and the selenium session.

I could use the selenium API but then i'd have to duplicate all the
step_definitions, which is kind of ugly...

So i finally think i got it running and i get the steps to run on
selenium using webrat. But now i want to do some real testing and
verify that some effects are taking place, e.g. replace a text on the
page.

How can i do such things on webrat? The response body does not reflect
any changes and i haven't seen any methods for testing such things. Is
there a way of doing it?

If not, and i have to switch to the selenium API, is there a mixed way
of doing this? The idea would be to have most of the step_definitions
in webrat and then some special steps using the selenium API...

Any suggestions or comments appreciated! :)

Alberto.

Gary Taylor

unread,
Dec 2, 2008, 5:25:12 PM12/2/08
to webrat
Hi,
I have exactly the same requirements and have had some success.
I have now written a cucumber feature and defined some extra steps in
'common_webrat_steps.rb'
The extra steps are to do things like 'Search for text in a dialog
window' where I use the response_body to get the latest html after the
javascript has run.

I had to do several 'hacks' which I did not think I should have needed
to do - but generally, I have kept the hacks in a seperate file which
I placed in my lib folder.
The hacks include :-
'response_body' was not passed to the selenium driver from the
integration session.
Added 'browser' method to allow direct access to the selenium driver
for those special cases where you need it (not had to use it yet
though)
Changed the javascript files for the 'custom locators' that webrat
uses for selenium to 'find' elements in a 'similar' way to webrat (but
not exactly). The main reason for changing these was to allow clicking
on links which were images.

But, the main thing that got me scratching my head to start with, was
'how do I enable selenium in my tests'. After a bit of reverse
engineering, and reading some docs, I found that I had to require
'webrat/selenium' in my env.rb which is in the steps folder (I think
it has been moved in later releases).
I have just grabbed the latest version of the plugin as it contains
all the latest code relating to selenium. It looks like they are
still working on it, but it is very useable right now.

I am hesitant to post my hacks unless you want me to as I don't want
to spread what may be the wrong way of doing things. I have emailed
the author of the project for advice on this one.

Cheers

Gary

Alberto Perdomo

unread,
Dec 3, 2008, 8:53:43 AM12/3/08
to web...@googlegroups.com
Hi Gary,

i'm glad to find out that other people are dealing with the same
issues and have success to some degree.
I'll expose my facts here.

DISCLAIMER: I'm still working on finding a working setup so don't take
this information as a guideline for your setup

My current setup is the following:

features/features_plain <- here i put all features without JS that are
going to be ran using webrat/rails
features/features_with_ajax <- here i put all features with effects
and ajax that are going to be ran using webrat/selenium
features/step_definitions <- common folder with all step definitions
features/support/webrat_env.rb <- require this in the webrat profile
features/support/selenium_env.rb <- require this in the selenium profile

My profiles look like this:
webrat: --require features/support/webrat_env.rb --require
features/step_definitions --language es features/features_plain
selenium: --require features/support/selenium_env.rb --require
features/step_definitions --language es features/features_with_ajax

I suspect that my selenium_env.rb is dodgy and i should be doing
things differently. Here is the extract:

ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
require 'cucumber/rails/world'
Cucumber::Rails.use_transactional_fixtures

require 'cucumber/rails/rspec'
require 'spec'
require 'selenium'
require 'webrat'

Before do
@browser = Selenium::SeleniumDriver.new("localhost", 4444,
"*chrome", "http://localhost", 15000)
@browser.start
end

After do
@browser.stop
end

Here my problems and thoughts:

* This is the biggest: I have a feature where i have an empty div
inside a view that gets filled with content by ajax when i click on a
button. Everything goes fine until the step where i inspect the
response_body after clicking the link with :wait => :ajax and i expect
to be filled with content, but it is always the original body with no
change reflected and an empty div.

* I expected to switch from the rails session to the selenium session
just by calling require 'webrat/selenium' but it doesn't work for me
at least with the latest gem version 0.3.2. The only way i have found
to switch to selenium session ist to instantiate the driver with the
before and after blocks and it doesn't seem to make a difference if i
require 'webrat/rails' or 'webrat/selenium'

* In order to test rich JS features though you need the browser
instance and mess around with the selenium API. I saw there is a
method browser in the edge version of webrat in github so i decided to
try that out. This version uses selenium-client rather than selenium
and i have seen some hardcoded methods to startup the browser and the
selenium server etc. However i haven't been able to get it running. If
i startup the server in the background it complains about the ports
being in use. I shutdown the server and try without the server running
but then i get a timeout running the features.

Here some comments on your hacks:

> 'response_body' was not passed to the selenium driver from the
> integration session.

Is this the problem i am experiencing with the outdated response_body?

> Added 'browser' method to allow direct access to the selenium driver
> for those special cases where you need it (not had to use it yet
> though)

Yeah, i think that is really important. As i said this is already in
the head version on github but unfortunately i didn't get it to run.

> But, the main thing that got me scratching my head to start with, was
> 'how do I enable selenium in my tests'. After a bit of reverse
> engineering, and reading some docs, I found that I had to require
> 'webrat/selenium' in my env.rb which is in the steps folder (I think
> it has been moved in later releases).

Yeah, the 'how do I enable selenium in my tests' was a hard one too for me.
Unfortunately doing the require 'webrat/selenium' didn't seem to work
for me. Maybe it has to do with the before and after blocks.

> I have just grabbed the latest version of the plugin as it contains
> all the latest code relating to selenium. It looks like they are
> still working on it, but it is very useable right now.

How do you get the selenium-client thing running?

> I am hesitant to post my hacks unless you want me to as I don't want
> to spread what may be the wrong way of doing things. I have emailed
> the author of the project for advice on this one.

Well, i have taken the first step and already posted my stuff here. I
think it's good practice to put a disclaimer or something to warn
people, but i think right now, given the fact there is almost no
document or any other resources, it's positive to post such things.
Discussions will take place and we will all find out better ways of
doing things. That can only happen if we all share our hacks and
different ways of doing things.

Once we have settled on these things we could share them with the
others i would be happy to put it somewhere in a github wiki page or
whatever as a resource to gelp people get started with
webrat/selenium.

Cheers!
Alberto.

Alberto Perdomo

unread,
Dec 5, 2008, 6:09:30 PM12/5/08
to webrat
Reading through the newest documentation in
http://github.com/brynary/webrat/tree/master/lib/webrat/selenium.rb i
got the stuff running with the newest version of webrat and selenium-
client.
However i am having following problem:

If i call response_body within a step_definition i get:
Entonces debería ver "Confirm Password" # features/step_definitions/
common_webrat.rb:56
undefined method `response_body' for
#<ActionController::Integration::Session:0x7f8e1abe31d8>
(NoMethodError)
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.0/lib/
action_controller/test_process.rb:470:in `method_missing'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.0/lib/
action_controller/integration.rb:498:in `__send__'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.0/lib/
action_controller/integration.rb:498:in `method_missing'
./features/step_definitions/common_webrat.rb:57:in `Entonces /
^debería ver "(.*)"$/'
features/features_with_ajax/sorpresa.feature:9:in `Entonces
debería ver "Confirm Password"'

However if i call selenium.get_html_source it works.

Any clues why it doesn't find the method?
These are my requires inside env.rb:
require 'cucumber/rails/rspec'
require 'spec'
require 'selenium'
#require 'webrat/rails'
require 'webrat/selenium'
require 'webrat'

Cheers!

Bryan Helmkamp

unread,
Dec 6, 2008, 5:01:09 PM12/6/08
to webrat
Hey Alberto,

What's the line at features/step_definitions/common_webrat.rb:56 ?

Inside your env.rb, you shouldn't have to do "require 'selenium'" or
"require 'webrat'". Having the "require 'webrat/selenium'" should take
care of everything for you.

-Bryan

Alberto Perdomo

unread,
Dec 7, 2008, 1:21:45 PM12/7/08
to web...@googlegroups.com
Hi Bryan,

> What's the line at features/step_definitions/common_webrat.rb:56 ?

Entonces /^debería ver "(.*)"$/ do |text|
response_body.should =~ /#{text}/m
end

I have aliased the methods When, Then, etc. inside the env.rb file as well:
module Cucumber::StepMethods
alias_method :Dado, :Given
alias_method :Cuando, :When
alias_method :Entonces, :Then
end


> Inside your env.rb, you shouldn't have to do "require 'selenium'" or
> "require 'webrat'". Having the "require 'webrat/selenium'" should take
> care of everything for you.

Ok, makes sense. I think i was trying out different requires to see if
the method was included...

It's really strange because i can drop down to the selenium api and
call selenium.get_html_source and that works but if i call
response_body it throws out an undefined method error.

If you want i can upload my last changes on to my github project so
you can take a look. Let me know.

Alberto.

Bryan Helmkamp

unread,
Dec 7, 2008, 2:31:33 PM12/7/08
to web...@googlegroups.com
Hey Alberto,

The problem is that Webrat doesn't expose the response_body method in the session object. If you're using the latest Webrat code, you should be able to do:

response.body.should =~ /#{text}/m

Instead of using regexp matching by hand, I'd recommend you use Webrat's #contain matcher, which now works with Selenium. So try:

response.body.should contain(text)

I'd like to get it to where we can omit the ".body", and simply write response.should contain(text), but it requires a small patch to RSpec which is a work in progress. Once it's finished and merged in, you should be able to just say:

response.should contain(text)

-Bryan

Alberto Perdomo

unread,
Dec 7, 2008, 2:55:45 PM12/7/08
to web...@googlegroups.com
Hi Bryan,

thanks a lot!


> session object. If you're using the latest Webrat code, you should be able
> to do:
> response.body.should =~ /#{text}/m

I have changed the step_definition to response.body.should =~
/#{text}/m and now it works! Hoorray!


> Instead of using regexp matching by hand, I'd recommend you use Webrat's
> #contain matcher, which now works with Selenium. So try:
> response.body.should contain(text)

I have tried response.body.should contain(text) but it returned
undefined method for contain.

Then i pulled the latest webrat code and tried again and got:

undefined method `session' for #<String:0x7f4ba3232df0> (NoMethodError)
/home/alberto/git/bort/vendor/plugins/webrat/lib/webrat/selenium/matchers.rb:73:in
`matches?'
./features/step_definitions/common_webrat.rb:58:in `Entonces
/^debería ver "(.*)"$/'


features/features_with_ajax/sorpresa.feature:9:in `Entonces
debería ver "Confirm Password"'

> I'd like to get it to where we can omit the ".body", and simply write


> response.should contain(text), but it requires a small patch to RSpec which
> is a work in progress. Once it's finished and merged in, you should be able
> to just say:
> response.should contain(text)

I tried this with the latest webrat code and it worked!

Cheers!

Bryan Helmkamp

unread,
Dec 7, 2008, 3:25:47 PM12/7/08
to web...@googlegroups.com
Glad it helped. Ack, I forgot that "response.body.should contain()" won't work.

Are you saying "response.should contain()" is working for you?

-Bryan

Alberto Perdomo

unread,
Dec 7, 2008, 3:35:01 PM12/7/08
to web...@googlegroups.com
Well, i have been doing more tests now:

response.body.should contain() did not work at all
response.should contain() worked but only within the selenium session,
not within rails session and i want my step_definitions to be session
agnostic at least such generic steps...

So i defaulted back to using response.body.should =~ /#{text}/m

Bryan Helmkamp

unread,
Dec 7, 2008, 4:45:00 PM12/7/08
to web...@googlegroups.com
Alberto,

I just made a change that should make response.should contain() work
in your non-Selenum code. Can you update Webrat and give that a try
and let me know how it goes?

I actually have no idea how "response.should contain()" is working for
you with Selenium without the RSpec patch I'm working on, but I'll
have to dive into that a bit.

-Bryan
--
Bryan Helmkamp
http://brynary.com -- My blog

Alberto Perdomo

unread,
Dec 7, 2008, 5:32:10 PM12/7/08
to web...@googlegroups.com
On Sun, Dec 7, 2008 at 9:45 PM, Bryan Helmkamp <br...@brynary.com> wrote:
>
> Alberto,
>
> I just made a change that should make response.should contain() work
> in your non-Selenum code. Can you update Webrat and give that a try
> and let me know how it goes?

It works fine both with and without selenium.
I am using rspec and rspec-rails as gems:
rspec (1.1.11)
rspec-rails (1.1.11)

-Alberto

Mike Gaffney

unread,
Dec 7, 2008, 5:37:52 PM12/7/08
to web...@googlegroups.com
I would think that the body is a specific part of the response that you
would want to check, response.should contain(text) seems to me that it
would search everything in the response including headers and cookies.

-Mike

Bryan Helmkamp

unread,
Dec 7, 2008, 6:00:07 PM12/7/08
to web...@googlegroups.com
Interesting point, Mike. The "response.should" syntax was what I copied from rspec-rails. Might be interesting to start a discussion on the RSpec list if that makes the most sense.

-Bryan

Luismi Cavallé

unread,
Dec 9, 2008, 8:25:42 PM12/9/08
to web...@googlegroups.com
In the project I'm working, we've been developing using Story Runner /
Cucumber + Webrat + Selenium for 6 months now. After our last upgrade
to the edge version of webrat (last monday), these are the config
files and hacks that make everything work together for us:

http://gist.github.com/34167

As someone said before, it should be considered highly experimental
code.

Any comments/suggestions/questions are appreciated/welcome

-- Luismi Cavallé
Reply all
Reply to author
Forward
0 new messages