How to get a detailed error message in Capybara unit tests - ruby

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 :)

Related

Ruby capybara Unable to find link or button "search"

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

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:(

RSpec - testing multiple expectations across routes

I'm attempting to use shared_examples as a way to repeat expectations across multiple routes. In particular, I want to test whether some static assets in my header and footer are loading. However, I get an error saying that:
RSpec::Core::ExampleGroup::WrongScopeError: `it_behaves_like` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).
Now, I'm not sure how to remedy this. This is my current setup.
shared_examples_for 'a page' do
describe 'should load static assets' do
it 'header, footer and icons' do
expect(page).to have_css 'footer.footer'
expect(page).to have_css '#navbar-brand'
brand = page.first(:css, '#navbar-brand')
visit brand[:src]
expect(page.status_code).to be 200
end
end
end
describe 'site pages should load static assets on requests', { :type => :feature } do
after :all do
it_behaves_like 'a page'
end
it 'home page' do
visit '/'
expect(page).to have_css 'div#main-menu a', count: 5
page.all('link[rel~="icon"]').each do |fav|
visit fav[:href]
page.status_code.should be 200
end
expect(page).to have_css 'div#main-menu'
...
end
it 'about page should have icons, footer and a header' do
visit '/about'
...
end
end
Another attempt was this:
describe 'home page' do
it_behaves_like 'a page'
end
Both fail for the same reason above. So, if I want to check the same things on every page, what is a better solution?
In RSpec 3 this should work
require 'spec_helper'
shared_examples 'a page' do
it 'has a header' do
expect(page).to have_css 'footer.footer'
end
it 'has a brand' do
expect(page).to have_css '#navbar-brand'
end
it 'points out to brand page' do
brand = page.first(:css, '#navbar-brand')
visit brand[:src]
expect(page.status_code).to be 200
end
end
describe 'home page' do
before { visit '/' }
it_behaves_like 'a page'
it 'does something else' do
# ...
end
end
Alternatively you could use a block
describe 'home page' do
it_behaves_like 'a page' do
before { visit '/' }
end
end

How to test whether an element is displayed on the page

The following code checks whether an element is displayed and if the element is present runs a specific action, else the test continues normally:
require "selenium-webdriver"
require "rspec"
require 'rspec/expectations'
describe "Current Expense" do
before(:all) do
#driver = Selenium::WebDriver.for :firefox
#base_url = "http://the-internet.herokuapp.com/disappearing_elements"
#driver.manage.window.maximize
end
after(:all) do
#driver.quit
end
it "Check icon" do
#driver.get(#base_url)
if expect(#driver.find_element(:xpath, "//*[#href='/gallery/']").displayed?).to be_truthy
#driver.find_element(:xpath, "//*[#href='/gallery/']").click
sleep 2
puts "element appears"
else
puts "element NOT appears"
end
end
end
When the element is present, the message appears, but when the element is not present in the page, an error occurs and the else block is not executed. What is causing this error?
I think the problem is that you're using expect when you should just have the conditional #driver.find_element(:xpath, "//*[#href='/gallery/']").displayed?. If the conditional is true you will see the expected message; likewise if it evaluates to false you will see `"element NOT appears".
As currently constructed, if the find_element method returns false then the spec should fail. Please post the error or exception you're seeing so that we can know for sure.
On a side note, what you have right now is fine for a quick and dirty test of whether or not the page is functioning correctly, but you'll probably want to give two cases in your test file: one where you know the icon will be on the page, and one where it shouldn't be on the page, and then test the outcome for each. For example:
#Code omitted
it "has the icon when x is the case" do
# make x be the case
#driver.get(#base_url)
#driver.find_element(:xpath, "//*[#href='/gallery/']").displayed?
#driver.find_element(:xpath, "//*[#href='/gallery/']").click
sleep 2
# code that verifies that the element is on the page
end
it "doesn't have the icon when y is the case" do
# make y be the case
#driver.get(#base_url)
expect {
#driver.find_element(:xpath, "//*[#href='/gallery/']").displayed?
}.to be_false
end
#code omitted
expect is the reason for test failure. Find the below snippet for solution.. Cheers!
it "has the icon when x is the case" do
#driver.get(#base_url)
begin
#driver.find_element(:xpath, "//*[#href='/gallery/']")
#driver.find_element(:xpath, "//*[#href='/gallery/']").click
rescue Selenium::WebDriver::Error::NoSuchElementError
raise 'The Element ' + what + ' is not available'
end
end
it "doesn't have the icon when y is the case" do
#driver.get(#base_url)
begin
#driver.find_element(:xpath, "//*[#href='/gallery/']")
raise 'The Element ' + what + ' is available'
rescue Selenium::WebDriver::Error::NoSuchElementError
expect(true).to be_truthy
end
end

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)

Resources