How to call Selenium methods with defined Capybara driver using Ruby? - ruby

I use Capybara as a driver in my auto tests.
I defined a driver as:
Capybara.default_driver = :selenium
But it is impossible to use Selenium methods in usual way (like: #driver.find_element(:xpath, ::Login_button).send_keys("MY_login")).
I saw on some resources that it is possible to call Selenium methods using construction:
page.driver.browser
For instance: element = page.driver.browser.find_element(:id, ell).
But error occurs that says that "page" is not defined method.
The question is how to use Selenium methods with defined Capybara driver?
May be it is necessary to define Capybara driver in another way in order to successfully use "page.driver.browser" construction?
Please provide little instance to see full picture.

page is just a convenience method in the Capybara DSL for Capybara.current_session. You can use 'page' if you've included Capybara::DSL into the scope of your tests - see https://github.com/jnicklas/capybara#using-capybara-with-testunit
If you don't want to include the Capybara DSL into your tests you can also just use
Capybara.current_session.driver.browser ....
although accessing selenium methods directly should only be done when absolutely necessary and there isn't a cross driver way to do what you want provided by Capybara

Related

How to refresh Capybara URL in Ruby

I've been playing with Capybara and the selenium web-driver to learn about web-automation. I've been trying to refresh a particular page with Capybara. I've seen a few methods but they each have issues that make them not feasible in certain cases.
session.visit link is just doing nothing, as the session is already at that link.
I can do session.reset! but then I lose the login.
The few other methods I've seen - don't use Capybara's inbuilt wait functionality.
This means if there is heavy server load - or in my tests with a restricted DL/UL rate the 'refresh' happens but then it quickly tries to look for a field in the next page that doesn't exist yet because it hasn't loaded.
So my question is specifically - how do I refresh a page in Capybara without loosing the login session using Capybara's inbuilt wait functionality?
you can do something like:
visit current_path
or define an RSpec helper:
def reload_page
visit current_path
end
Capybara now implements a refresh method so you can call it directly in your spec.
Since you're using selenium, you can either use the master branch of Capybara and call
session.refresh
or you can stick with the current release version and call
session.driver.browser.navigate.refresh
If the page you're trying to refresh was a POST it may pop up an "are you sure you want to resbumit" modal, in which case you'd need something like
session.accept_confirm do
session.driver.browser.navigate.refresh
end

How to test Capybara?

I have a script that use Capybara to publish links in Google+. I would like to have tests to cover this functionality. Usually Capybara is using as a tool for writing Integration tests. In may case i need to test Capybara itself.
I see 3 possible ways:
stub capybara's method (but in this case i test nothing but just stubbed methods)
test capybara agains saved HTML/JS page (that will help me understand that i did not break anything during refactoring)
do not test at all (no comments here)
Have you ever faced such a problem?
If you register different drivers for your app and your test code, possibly manage the sessions manually depending on how you're using it in your app, and make sure you're careful with Capybaras setting's you should be able to go with option 2. You have to be careful with Capybaras settings because most of them are global so changing them for your tests will also change them for your app.

Testing a ruby class without the required module files

I'm working on a project in Ruby on Rails. We have a controller action that uses a module within a gem. This gem isn't finished yet and it isn't on the file system.
I was told to mock the module in order to test the controller. Is there a way to test this without the actual gem? Would mocking the 'require' calls work?
We are currently using Mocha for Mocking and Stubbing.
There is a way to mock the imports in python. Maybe there is a similar answer to mocking the requires in ruby.
How to mock an import
Or please let me know what would be the best way to handle this.
Update: The person who told me to mock it, suggested adding a stub file, but that would require adding test code to the controller and I don't want to do that.
Update 2: The controller uses methods declared in the Module.
If you are writing tests to mock the method calls, they would fail. For example,
controller.should_receive(:method_in_non_existent_module).with(args) #=> errors
In a correct Red->Green TDD scenario , this is alright because the next step would be to require the gem/file, include the module and add the method call in the controller and make the test pass. But you'll not be able to make the tests pass since you can't require the file because it doesn't exist yet.
May be the developer who asked you to mock the method meant to do so not in your tests, but in your actual code. For example, he's writing a gem 'dongle-jokes' which has a method that gets the most popular dongle joke from the most recent tech conference. He doesn't want the gem to be a blocker for you to finish the controller and the views so he asks you to use a dummy interface that spits out a dummy response.
Write the tests that fail
Add a file lib/dongle-jokes.rb
Add the following to that file.
module DongleJokes
def joke
"Dongle jokes aren't funny!"
end
end
Require the file and include the module, use the method in the controller.
The test should pass now. You can remove lib/dongle-jokes.rb when you start using the actual gem.
If you're working in Rails you shouldn't need to add a require to the controller anyway, as when you add the gem to your gemfile it will be required automatically on Rails startup.
What your colleague most likely meant was that you should stub the module itself. Are you using rspec for your tests? If so you should be able to use stub_const. Let's say the module is called Payments. You can then write test code like the following:
before do
stub_const("Payments", stub)
Payments.stub(process: "payments successful")
end

How to run cucumber scenario with and without javascript avoiding code duplication

I was wondering if there is any way to run cucumber scenario with and without javascript without duplicating code.
I develop website that utilizes html5 navigation. However it should work find if browser doesn't support html5 features.
I would like to write cucumber test that would test navigation.
I know I can test basic html navigation with simple cucumber scenario. And I can test html5 navigation with same scenario but with #javascript tag.
I would really love to avoid this code duplication.
I was experimenting with around hooks, hoping that I could simple call block, then call same block with
Capybara.using_driver(Capybara.javascript_driver) { block.call }
However this doesn't work.
Anyone have any idea how to implement this?
P.S.
I'm quite new to Ruby, and just started working with cucumber.
It looks like you need two different scenarios. I'd use the Background feature to avoid step definitions but it's a matter of taste.
Based on the solution by Jon M of using the environment variable, you need to set the current_driver before each scenario runs (which seems better than changing the default_driver).
Before do
if ENV['USE_JS_DRIVER']
Capybara.current_driver = Capybara.javascript_driver
end
end
And then running
cucumber .
USE_JS_DRIVER=1 cucumber .
If you don't want to create separate features to deal with both types of browser, then one solution is to use an environment variable to tell cucumber which type of browser driver to use, and invoke cucumber twice.
You'd need to query the environment variable to set the correct driver, probably in env.rb:
if ENV['USE_JS_DRIVER']
Capybara.current_driver = Capybara.javascript_driver
end
And then you could run either/both of:
cucumber .
USE_JS_DRIVER=1 cucumber .
You'd have to find some useful way of merging the results from both cucumber runs, but depending on your needs this could be a simpler solution than duplicating your scenarios.

WATIR/ FireWATIR URL consistency?

We are at the start of a project to test a new web application written in jQuery and are planning to do it using WATIR and FireWATIR.
During the proof of concepts test I've discovered differences in how WATIR and FireWATIR represent URLs, for example a script which passes in FireWATIR generates this error in WATIR.
assert_equal(expandImage.src,"../WebToolKit/images/closed.jpg")
testBrowserGadget2(WebClientHomePage) [002_pub_browser.rb:108]:
<"http://172.24.4.125:8081/WebToolKit/images/closed.jpg"> expected but was
<"../WebToolKit/images/closed.jpg">.
Is there any setting in either WATIR or FireWATIR I can enable so that the URL value is consistent between when running against IE and Firefox?
I use the uri module ...
e.g.
require 'uri'
URI.parse("http://google.com/image/path.jpg").path
=> "/image/path.jpg"
i.e.
assert_equal(URI.parse(expandImage.src).path,"../WebToolKit/images/closed.jpg")
you could use assert_match http://en.wikibooks.org/wiki/Ruby_Programming/Unit_testing

Resources