I'm trying to test the ability to vote on an event. I've created the event via factory_girl. When the user participated to the event, he should have the ability to vote.
The vote button is visible to capybara as well as visible to me when I manually test for its presence in the browser. When I use click_on "vote", there is no error. Now comes the weird thing. When I manually test the vote button via the browser, I now see the vote form and have a /vote/... path in my browser. When I use click_on "vote" in Capybara and check for the path, the path equals the start page.
I've tried everything I can think of to figure out why Capybara is hitting the wrong path.
My question is, is there a possibility to see some 'advanced' logging or something else? Like why a redirect happened or something else?
You can use byebug to step through your spec. Also, I find chromedriver to be very useful. It runs your tests in chrome environment so you can eyeball your test and confirm that it is doing what it is supposed to.
Byebug:
https://github.com/deivid-rodriguez/byebug
Chrome driver:
http://collectiveidea.com/blog/archives/2011/09/27/use-chrome-with-cucumber-capybara/
Related
I'm working on an advertising application, where there is some cross-domain JS. I'd like to write tests that verify that the cross-domain JS is working as intended.
My first thoughts are that I would need to be able to
visit some_url_thats_not_my_rails_app
However, Capybara throws a "No Route Matches", since it obviously goes to only relative paths, and is intended for testing your OWN website. But I really need to go on ANOTHER page, and verify that things like the serialized token are identical.
Is Capybara the right tool for this? If so, what do I need to do to force non-relative paths?
Yes, Capybara is right tool for it. You can also use Ruby with Selenium webdriver(Would be awesome with page object gem) or Ruby with Watir webdriver.
To visit and test any web application, you can use Ruby and Capybara. For this you need to set app_host. Add this one in support/env.rb:
Capybara.app_host = "http://flipkart.com"
And in hooks.rb
Before do
visit('/')
end
You can use Capybara with Selenium webdriver and you will be good to test any deployed application in production, staging or prep env.
I'm having a hard (but very interesting time) diving into Behavior Driven Development using Cucumber, RSpec, Selenium, and Rails.
I have my setup ready for testing with Selenium, and it's funny to watch Firefox pop up and run automatically through my scenarios. But one thing I'd like to do is pause or stop execution at a certain point, so I can inspect what Selenium sees at a certain point.
I know of the save_and_open_page command, but this only shows me plain HTML without formatting. So maybe there is a stop_execution method or something that stops Selenium without closing the browser?
Install pry, then put binding.pry in your test where you want it to pause. When you're done, press Ctrl+D or type exit in the REPL that gets opened to continue execution.
or just:
visit '/'
sleep(inspection_time=5)
visit '/dreamland'
All the answers need installing new gems or even setting a sleep which is not the best approach. You can put this line anywhere in you step:
ask "Continue?"
It will stop execution until you enter y (Yes)
So, for example it would look like this:
expect(page).to have_button('Submit')
ask "Continue?"
click_button('Submit')
Use Debugger where you want to stop/pause the execution.
or
In Selenium IDE you can right click on the commands line and you can select Set/Clear Start point to stop/pause the execution.
Okay, I got it working by installing ruby-debug19 (for Ruby 1.9.3), and then just setting a breakpoint somewhere in a Cucumber step.
http://rails.vandenabeele.com/blog/2011/12/21/installing-ruby-debug19-with-ruby-1-dot-9-3-on-rvm/
Another option is to use the Capybara-firebug gem which adds a "Then stop and let me debug" step which basically seems to do the same (I don't know whether it relies on the ruby-debug gems).
try to use selenium.sleep(ms)
this will make the test execution wait for the specified amount of time
You can use do this without installing any gems in rails 5 or above by using byebug. Just type byebug on the line that you want the test to pause at.
Example:
visit post_url(id: posts(:one).id)
byebug
click_on "...", match: :first
Doing this will pause the test after the new page loads but before the next button is clicked. If using an older version of rails you may have to install the byebug gem but it is useful for troubleshooting and I recommend using it regardless.
We have a issue on our e-commerce site where users occasionally hit "checkout" twice and have their card charged twice.
It's a common enough bug and easy to fix, but I'd like to test the solution in our capybara setup. Once I've called click_button('checkout'), is it possible for me to pretend I'm a user hitting the browsers back button and then call click_button('checkout') a second time?
You may want to try:
When(/^I go back$/) do
page.evaluate_script('window.history.back()')
end
This will require running the senario in a javascript capable driver (selenium/celerity/akephalos)
You can use page.driver.go_back, if you are using webkit as your capybara javascript driver via the capybara-webkit gem. Also requires :js => true for the scenario.
At least with capybara 2.10 and selenium-webdriver 2.53 this works:
When(/^I go back$/) do
page.go_back
end
It's basically a shortcut for jbarr's answer. For details more see the capybara documentation on go_back .
BTW: The counter part is page.go_forward.
I've used this method in Webrat. I'm sure something similar for Capybara would work.
When(/^I go back$/) do
visit request.env['HTTP_REFERER']
end
Side note: the "redirect_to :back" method didn't work for me for whatever reason.
Thanks! This question and answer helped me a lot!
Just to add to #Jake Mallory's answer, selenium is now part of capybara and you can fairly easily run javascript in the test by adding :js => true (and possibly a couple more tweaks) as described in these two tutorials:
http://www.opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/
http://railscasts.com/episodes/257-request-specs-and-capybara?view=asciicast
I started migrating from cucumber + webrat to cucumber + capybara. Now the behavior of "I should see " seems to be somewhat different. Most of these fail now, although I didn't change anything on the page. I replaced the snippet that should be found with some stuff that is on every page and for some text it works and for other text it doesn't. I can't find any pattern in what is found in the page's content and what is not.
Webrat used to print what the page content is that it found, in case it did not contain the required phrase. Is there anyway to have capybara show what text it got from the page in which it tried to find the text?
Then show me the page calls webrat/capybara's underlying save_and_open_page method. Found that useful when working with steak.
Try adding this step:
Then show me the page
If you want to have the browser open the page when the page fails you use the 'launchy' gem.
Add it to your gem file, and then in /features/support create a file called debugging.rb with contents:
After do |scenario|
save_and_open_page if scenario.failed?
end
If you're using Javascript or Ajax in your pages and want to see what's going on, I've found that the Poltergeist driver is very good at letting you get into the DOM and find out what's going wrong.
If you setup your Capybara driver with the remote debugging option:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, inspector: true)
end
You can then put the following line in your steps:
page.driver.debug
Which fires up a new Chromium browser with the current DOM state set, letting you get at the console. (On my version of Linux, I had to symlink chromium to chromium-browser but it otherwise worked fine).
Source Info: http://jonathanleighton.com/articles/2012/poltergeist-0-6-0/
Then show me the response didn't work for me with cucumber 1.1. I found useful to write a step using capybara's command:
print page.html
This outputs the current state of the DOM
You could also use "Then show me the response" which outputs the HTML to the console if you don't want to use a browser.
You could always have it take a screen shot when something failed. I debug a LOT of failing features that way.
Given I have a rails app
And I'm using cucumber
And I'm using capybara
And I have an action that results in a redirect_to "http://some.other.domain.com/some_path"
When I test this action
Then the in-app portion of the test works fine
But I see this error: No route matches "/some_path" with {:method=>:get} (ActionController::RoutingError)
So capybara is properly redirected to "http://some.other.domain.com/some_path" but for some reason it thinks it should handle the path portion of the url inside my app. NOTE capybara has no problem at all with "http://some.other.domain.com/" -- my tests pass if I redirect to a url without a path portion.
Is this a bug?
I think I had the same problem as you: I just wanted to confirm, that my code redirects to that given URL with the correct status code, but I don't want to do anything on that URL.
The problem is, that the site returns the redirect as expected, but Rack::Test interprets everything to the application under test, and that URL probably doesn't exist. But we can just catch the error and see what the response looked like. This will probably not work with anything else than capybara's default driver.
begin
click_button('Pay with Paypal')
rescue ActionController::RoutingError
end
expect(page.status_code).to eq(302)
expect(page.response_headers['Location']).to include('paypal.com/cgi-bin/websrc')
Here's an example I wrote up about using capybara-mechanize and VCR to test an external redirect.
http://blog.tddium.com/2011/10/04/testing-external-redirects-vcr-capybara-mechanize/
I've found a cool solution for Capybara (which can be adapted into Cucumber).
begin
click_button 'Accept'
rescue ActionController::RoutingError
# Capybara doesn't redirect externally, so matches '/cb' but that route doesn't exist
expect(page.current_url).to eq "https://example.com/cb?param=123"
end
Which driver are you using? The Rack-Test driver isn't going to allow you to request stuff from other domains. If Capybara is doing this with Selenium or Culerity, it's definitely a bug. If you want to help out in getting it fixed, writing a failing spec would be very appreciated :)
#javascript is a currently working solution, though there's also a mechanize driver in the works, which uses rack-test up to the point where you hit an external request.
It's a bit new and I haven't tried it yet, but am meaning to change my external #javascript tests to using it (tagged with #live or #external or similar) for the speed boost.
Using this little snippet:
external_redirect "https://api.twitter.com/oauth/authenticate?x_auth_access_type=read&oauth_token=TOKEN" do
click_link "Continue with Twitter"
end
def external_redirect(url)
yield
rescue ActionController::RoutingError # goes to twitter.com/oauth/authenticate
current_url.must_equal url
else
raise "Missing external redirect"
end
I had a similar situation where I was integrating my app with the company's SSO platform. The way I got around this was to get the site running Selenium via appending the #javascript tag against the scenario.