Rspec fails when let(:base_title) added while refactoring - ruby

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)

Related

Getting Frozen Error-Can't modify frozen string

Getting frozen error while running below mentioned cod. Also find the helpers files. Below is the main file:
require 'spec_helper.rb'
require 'rspec_capybara_assignment_helper.rb'
describe 'Open the automationpractices site' , :type => :request do
it 'Test: Page Content', :page do
visit "http://automationpractice.com/index.php"
expect(page).to have_xpath(".//img[contains(#src,'automationpractice.com/img/logo')]")
expect(page).to have_xpath(".//input[#id='search_query_top']")
expect(page).to have_link("Contact us")
expect(page).to have_link("Sign in")
within('div#block_top_menu') do
expect(page).to have_link("Women")
expect(page).to have_link("Dresses")
expect(page).to have_link("T-shirts")
end
within('div#center_column') do
expect(page).to have_link("Popular")
expect(page).to have_link("Best Sellers")
end
expect(page).to have_content("Automation Practice Website")
end
end
Spec_Helper file:-spec_helper.rb
require 'rspec'
require 'capybara/rspec'
require 'capybara/dsl'
require "selenium-webdriver"
require "capybara"
require 'capybara/rspec/matchers'
RSpec.configure do |config|
config.include Capybara::DSL , :type => :request # to include capybara DSL methods
config.include Capybara::RSpecMatchers,:type => :request # to include Rspec matchers available.
end
Capybara.configure do |config|
config.run_server = false
config.default_driver = :selenium # which driver to use (selenium / chrome /internet explorer)
config.default_selector = :css #(by default css selector) # if user want to use xpath, he has to write find(:xpath, <xpath>).click
config.app_host = "http://automationpractice.com/index.php" # host app
config.default_max_wait_time = 5 # wait for 4 seconds.
config.app_host = #url
config.ignore_hidden_elements = true # will ignore hidden elements on page.
config.match =:prefer_exact # check for exact match.
end
Rspec Capybara Assignmnet Helper File:
rspec_capybara_assignment_helper.rb
def click_on(value)
find(value).click
end
def link_click(value)
click_link(value)
end
def button_click(value)
click_button(value)
end
def login_application
link_click('Sign in')
fill_in('email', :with => 'test.test#testing.com')
fill_in('passwd', :with => 'testtest')
button_click('SubmitLogin')
end
def sign_out
link_click('Sign out')
end
def search_product(value)
fill_in('search_query_top', :with => value)
button_click('Search')
sleep(2)
end
def add_product(value)
page.find(:css,'.product-image-container').hover
sleep(2)
first("a", :text => "More").click
sleep(4)
fill_in('quantity_wanted', :with => '2', visible: false)
select('M', :from => 'group_1')
find('button.exclusive').click
sleep(2)
first("span", :text => "Continue shopping", wait: 3).click
sleep(2)
end
def check_locator(value)
expect(page).to have_selector(value)
end
Error as below:
Open the automationpractices site
Test: Page Content (FAILED - 1)
Failures:
Open the automationpractices site Test: Page Content
Failure/Error: visit "http://automationpractice.com/index.php"
FrozenError:
can't modify frozen String
./spec/tests/rspec_capybara_assignment.rb:6:in `block (2 levels) in <top (required)>'
Finished in 0.7789 seconds (files took 3.61 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/tests/rspec_capybara_assignment.rb:5 # Open the automationpractices site Test: Page Content
This appears to be related to selenium-webdriver, not capybara itself.
There's an issue about this at https://github.com/SeleniumHQ/selenium/issues/7365
To fix, specify in your gemfile that you want 3.142.4 as a minimum: gem 'selenium-webdriver', '~> 3.142.4'
And then run bundle update selenium-webdriver
That should get this specific issue resolved.

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

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

Why am I getting FactoryGirl wrong number of arguments error?

Having strange behavior from FactoryGirl in non-rails app. getting wrong number of arguments error...don't know why.
gideon#thefonso ~/Sites/testing (master)$ rspec spec
/Users/gideon/.rvm/gems/ruby-1.9.3-p194/gems/factory_girl-4.1.0/lib/factory_girl/syntax/default.rb:6:in `define': wrong number of arguments (1 for 0) (ArgumentError)
from /Users/gideon/Sites/testing/spec/factories.rb:1:in `<top (required)>'
Here are the files involved...
login_user_spec.rb
require_relative '../spec_helper'
require_relative '../lib/login_user'
describe "Existing User Log in Scenario", :type => :request do
before :all do
#user = FactoryGirl(:user)
end
xit "should allow user to select login from top nav" do
visit "/"
within("#main-header")do
click_link 'Log In'
end
page.should have_content('Log in to your account')
end
it "and fill in login form" do
visit "/login"
within("#login-form")do
fill_in 'user-email', :with => #user.email
fill_in 'user-password', :with => #user.password
end
#FIXME - the design crew will make this go away
within("#login-form") do
click_link '#login-link' #this gives false failing test...geek query...why?
end
page.should have_content('Manage courses')
end
end
Factories.rb
FactoryGirl.define :user do |u|
u.email "joe#website.com"
u.password "joe009"
end
user.rb
class User
attr_accessor :email, :password
end
spec_helper.rb
require 'rubygems'
require 'bundler/setup'
require 'capybara'
require 'rspec'
require 'capybara/rspec'
require 'json'
require 'capybara/dsl'
# Capybara configuration
Capybara.default_driver = :selenium
Capybara.app_host = "http://www.website.com"
require 'factory_girl'
# give me ma stuff
FactoryGirl.find_definitions
require "rspec/expectations"
include Capybara::DSL
include RSpec::Matchers
ANSWER: :user is a reserved word..changed it to :stuff...works fine now.
Try to use new syntax from readme
FactoryGirl.define do
factory :user do
email "joe#website.com"
password "joe009"
end
end
If this is a non-rails app you will have to create a Userclass first. I'm not sure if you have to have instance vars with name, password and email but you definitely will have to have that class defined somewhere.
See the Getting Started file on Github for more on that.
Try this
FactoryGirl.define do
factory :user do |u|
u.email "joe#website.com"
u.password "joe009"
end
end

Resources