Ruby capybara Unable to find link or button "search" - ruby

I have the problem with a simple script:
Given(/^I am on the main home page$/) do
visit 'xxx.se'
end
When(/^I search for "(.*?)"$/) do
|search_term|
fill_in 'q', :with => search_term
click_on 'search'
end
Then(/^videos of large rodents are returned$/) do
expect(page).to have_content 'Samsung'
but I got an error
Capybara::ElementNotFound: Unable to find link or button "search"
./features/step_definitions/steps.rb:7:in `/^I search for "(.*?)"$/'
link to inspect element here:
http://imgur.com/GLbbg7e

try find("button[aria-label='Search']") it probably can help
you can read about clicks here
http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions

As click on does not support css selectors you can use find instead
find(:css, "button.search-form-button").click

Related

RubyMIne capybara example from book does not work - syntax error

When running an example from the book "Application testing with Capybara", I got the error
step_definitions/steps.rb:5: syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('
... :with => search_term click_on 'search-btn'
... ^
My steps.rb looks like this:
Given(/^I am on the YouTube home page$/) do
visit 'http://www.youtube.com'
end
When(/^I search for "(.*?)"$/) do
|search_term| fill_in 'search_query', :with => search_term click_on 'search-btn'
end
Then(/^videos of large rodents are returned$/) do
page.should have_content 'Largest Rodent'
end
now I have new problem
according to:
betterspecs .org/#expect
I changed "then line" for..
Then(/^videos of large rodents are returned$/) do
expect(page).to have_content 'Largest rodents'
And I got:
Spec::Expectations::ExpectationNotMetError: expected to find text "Largest rodents" in "Remind me later Review A privacy reminder from YouTube, a Google company PL UploadSign in Search Home Trending BEST OF YOUTUBE
./features/step_definitions/steps.rb:10:in `/^videos of large rodents are returned$/'
./features/youtube_search.feature:5:in `Then videos of large rodents are returned'
fill_in and click_on are two distinct methods. Your code should look like this:
When(/^I search for "(.*?)"$/) do |search_term|
fill_in 'search_query', :with => search_term
click_on 'search-btn'
end
thanks it helped but..another issue occurs:(
./features/step_definitions/steps.rb:10:in /^videos of large rodents are returned$/'
./features/youtube_search.feature:5:inThen videos of large rodents are returned'
DEPRECATION: Using should from rspec-expectations' old :should syntax without explicitly enabling
i changed line:
Then(/^videos of large rodents are returned$/) do
page.should have_content 'Largest rodents'
end
page.sould on page.expect but did not help
i changed also text "Largest rodents" foe another:( and not helped:(

How to get a detailed error message in Capybara unit tests

How do I get a detailed error message in Capybara unit tests?
describe "About" do
it "should have the h1 'About Us'" do
visit '/static_pages/about'
page.should have_selector('h1',
:text => "About Us")
end
it "should have the title 'About'" do
visit '/static_pages/about'
page.should have_title("About")
end
This tests for title to be "About".
How do I add a custom error message like:
Expected "About" but found "ABT". Please Rectify the mistake.
You can add a custom error message described in "Customized message" like this:
it "should have the title 'About'" do
visit '/static_pages/about'
expect(page).to have_title("About"), lambda { "Expected 'About' but found '#{page.first("title", visible: false).native.text}'. Please Rectify the mistake."}
end
You can add custom error messages as shown below, also you should add to take screenshot to debug the issue.
describe "About" do
it "should have the h1 'About Us'" do
visit '/static_pages/about'
page.should have_selector('h1',
:text => "About Us")
end
it "should have the title 'About'" do
visit '/static_pages/about'
textToSearch="About"
begin
page.should have_title("#{textToSearch}")
rescue Exception => e
puts "Expected '#{textToSearch}' but found '#{page.first("title", visible: false).native.text}'. Please Rectify the mistake."
randomNumber=rand(100000)
page.save_screenshot("abc-#{randomNumber}.png",:full=>true)
raise e
end
end
Hope this will Helps :)

how to run capybara commands once, then run some tests

I have the given testing code:
describe 'A new user', js: true do
before do
#new_user = Fabricate.build(:user)
end
it 'should sign up' do
#login code
visit '/'
click_link 'Login'
fill_in 'user[email]', :with => #new_user.email
fill_in 'user[password]', :with => #new_user.password
click_button 'Login now'
#login code end
page.should have_content("Hello #{#new_user.first_name}!")
current_path.should == dashboard_path
end
it 'should receive a confirmation mail' do
#same login code again
visit '/'
click_link 'Login'
fill_in 'user[email]', :with => #new_user.email
fill_in 'user[password]', :with => #new_user.password
click_button 'Login now'
mail = ActionMailer::Base.deliveries.last
assert_equal #new_user.email, mail['to'].to_s
end
end
Now I want to add more tests.
To avoid code doubling, how can I run the capybara login code once before all tests?
One solution would be to put the login code in the before method. Another would be to create a method do_login, put the code in it and run every test like this:
it 'should do something after login' do
do_login
#test code here
end
But for both solutions, the code is run for every test and thats not what I want. Putting the login code in a before(:all) doesn't work, too.
How can I run some capybara code once and then do all the tests after this?
You can't run capybara code once and then run all the tests. You always start from scratch. Your proposed solution with before(:each) or helper method is the only posibility. (It's possible to run some ruby before(:all) e.g. create objects outside the transaction check here but not Capybara)
To speed up your specs you can test login feature in separate spec and then somehow stub the authentication but it depends on your implementation.
If you are using Devise check devise wiki: https://github.com/plataformatec/devise/wiki/How-To:-Controllers-tests-with-Rails-3-(and-rspec)

Rspec fails when let(:base_title) added while refactoring

I am following Ruby on rails tutorial by Michael Hartl.
Refactoring a simple test using rspec is failing it, I will paste first what works, then i will paste what works ....
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the h1 'Sample App'" do
visit '/static_pages/home'
page.should have_selector('h1', :text => 'Sample App')
end
it "should have the title 'Home'" do
visit '/static_pages/home'
page.should have_selector('title',
:text => "Ruby on Rails Tutorial Sample App | Home")
end
end
describe "Help page" do
it "should have the h1 'Help'" do
visit '/static_pages/help'
page.should have_selector('h1', :text => 'Help')
end
it "should have the title 'Help'" do
visit '/static_pages/help'
page.should have_selector('title',
:text => "Ruby on Rails Tutorial Sample App | Help")
end
end
end
Now I will paste what fails in rspec
require 'spec_helper'
describe "Static pages" do
let(:base_title) { "Ruby on Rails Tutorial Sample App |" }
describe "Home page" do
it "should have the h1 'Sample App'" do
visit '/static_pages/home'
page.should have_selector('h1', :text => 'Sample App')
end
it "should have the title 'Home'" do
visit '/static_pages/home'
page.should have_selector('title', :text => "#{base_title} Home")
end
end
describe "Help page" do
it "should have the h1 'Help'" do
visit '/static_pages/help'
page.should have_selector('h1', :text => 'Help')
end
it "should have the title 'Help'" do
visit '/static_pages/help'
page.should have_selector('title', :text => "#{base_title} Help")
end
end
end
Also i am new to this so i would like to ask what more information might be required ... the change is obviously
let(:base_title) { "Ruby on Rails Tutorial Sample App |" }
Thanks for any help !
Failing error being ....
Failures:
1) Static pages Home page should have the title 'Home'
Failure/Error: page.should have_selector('title', :text => "#base_title} Home")
expected css "title" with text "#base_title} Home" to return something
# ./spec/requests/static_pages_spec.rb:16:in `block (3 levels) in '
2) Static pages Help page should have the title 'Help'
Failure/Error: page.should have_selector('title', :text => "#{base_title} Help")
expected css "title" with text "Ruby on Rails Tutorial Sample App | Help" to return something
# ./spec/requests/static_pages_spec.rb:29:in `block (3 levels) in '
It has been a while since this question was asked. If it's still relevant:
There are two spaces after #{base_title}.
Delete a space and it should work.
it looks like you missed a { in the first example:
"title" with text "#base_title} Home"
this string is just not interpolated and has nothing to do with let
and other error should not occur if your code and test work properly.
Just be ahead of changing Capybara and Webrat syntaxes. This should work for your example:
page.should have_selector('h1', text: "#{base_title} Help")
or you can replace it with class like that:
page.should have_selector("h1[class='title']", text: "#{base_title} Help)

Capybara spec failing when using attach_file with Dragonfly

I'm writing a spec for a form page which uses DragonFly gem to handle attachments, here is my spec (relevant part of it)
fill_in "Subject", :with => 'My message'
fill_in "Title", :with => 'My image title'
fill_in "Content", :with => 'Message content'
attach_file 'Title image', Rails.root.join('spec', 'factories', 'test-image.png')
click_button "Create Message"
page.should have_content("Message was successfully created.")
However it fails on the click_button step with the following error
Failure/Error: click_button "Create Message"
ArgumentError:
Dragonfly::TempObject must be initialized with a String, a Pathname, a File, a Tempfile, another TempObject, something that responds to .tempfile, or something that responds to .path
I tracked down this error and I've found that it's raised in this line; I've put some debug instruction before that line and I found out that obj is an Array which contains binary data of the image, here are the first data returned by p obj.inspect
"[\"\\x89PNG\\r\\n\", \"\\u001A\\n\", \"\\u0000\\u0000\\u0000\\rIHDR\\u0000\\u0000\\u0003s\
What I'm doing wrong? Is it my fault or there is some incompatibility with Capybara and Dragonfly?
P.S. When I access the application using a real browser it works like a charm.
I was using an old version of Capybara, I've updated it to version 1.1.2 with bundle update capybara and the problem is gone.

Resources