I'm trying to use Capybara as a front-end test suite (Vue) and I'm getting the following error from Puma:
Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
ActionController::RoutingError:
No route matches [GET] "/login"
What is the cause of this and how can I fix this? Is it something to do with the config? Let me know if I should include more code in my question.
rails_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require "pundit/rspec"
require "capybara/rails"
require "capybara/rspec"
require "capybara/poltergeist"
require 'database_cleaner'
require 'factory_girl'
require 'shoulda/matchers'
require "paperclip/matchers"
require 'support/spec_helpers/warden_controller_helpers'
require 'webmock/rspec'
require 'support/spec_helpers/webmock_helper'
Capybara.javascript_driver = :poltergeist
login_spec.rb:
require 'rails_helper'
RSpec.feature "User login", type: :feature, js: true do
before :each do
#user = User.create!(
first_name: "Bob",
last_name: "Brown",
email: "bob#email.com",
password: "bob1",
has_accepted_terms: true
)
end
scenario "User logs in with correct credentials" do
visit root_path
save_screenshot
click_on 'Log In'
sleep 1
save_screenshot
end
end
So if I run the dev server and go to 'localhost:3000 (which is basically what you're telling Capybara to do) then there is a broken 'Log In' link on the page that points to app.localhost:3000/login which the app doesn't handle. This is because visiting a URL without the app subdomain uses the application.html.haml layout which includes no JS (and therefore no Vue router to handle the /login path). If however I go to app.localhost:3000 in the browser then there's a page with a working Log In link since all the JS is loaded on that page (including the Vue router) because it uses the app.html.haml layout (BaseController)
You need to fix the main homepage link to function correctly and/or configure Capybara to connect to the app subdomain by default
Capybara.app_host = 'http://app.localhost' # hostname with ‘app’ sub domain that resolves to interface the AUT is being run on
Capybara.always_include_port = true
Basically Capybaras telling you your apps main page is broken because it is broken.
Related
I have a Rails App, testing with RSpec and Capybara
I have following test:
context 'destroy user' do
scenario "should be successful" do
user = User.create(first_name: 'John', last_name: 'Doe', email: 'john.doe#example.com')
visit users_path
click_link 'Destroy'
# expect { click_link 'Destroy' }.to change(User, :count).by(-1)
expect(page).to have_content 'User was successfully destroyed'
end
end
I have following link in the browser:
<%= link_to "Destroy", user_path(user), method: :delete, data: { confirm: "Are you sure?" } %>
I run the test, and the test passes. It shouldn't pass, since I have the alert window before calling the action.
I installed
brew cask install chromedriver
because I wanted to test JS, but unfortunately test is not failing.
rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
# Add additional requires below this line. Rails is not loaded until this point!
require 'rspec/rails'
require 'capybara/rails'
# Capybara.default_driver = :selenium_chrome ### not working
# require "support/factory_bot"
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
end
Once the test fails, I would improve the test with:
accept_confirm do
click_link 'Destroy'
end
I think my problem is, I don't know where to put the line:
Capybara.default_driver = :selenium_chrome ### not working
Where do I create the file for the config of Capybara? In the official documentation, they say in the lib/capybara.rb
I tried there, and I get the error:
An error occurred while loading ./spec/models/user_spec.rb.
Failure/Error: require File.expand_path('../../config/environment', __FILE__)
Bundler::GemRequireError:
There was an error while trying to load the gem 'capybara'.
Gem Load Error is: uninitialized constant Capybara
Backtrace for gem load error is:
/Users/albert/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:74:in `block in load_missing_constant'
/Users/albert/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/active_support.rb:8:in `without_bootsnap_cache'
You don't show your Capybara config (default_driver/javascript_driver), and you also don't have js metadata on your test which would imply you're possibly using the rack_test driver to run your tests. The rack_test driver doesn't support JS and therefore would completely ignore the JS confirm. If you want to test JS behaviors you need to make sure you're using a driver that actually supports JS - see https://github.com/teamcapybara/capybara#drivers and https://github.com/teamcapybara/capybara#using-capybara-with-rspec
I've been trying to create a feature spec with "js: true" for a https page.
I'm using Rails4.2 + rspec + capybara + poltergeist.
I can test http pages with capybara + poltergeist without any problem. However, I can't find a way to test https pages with capybara + poltergeist.
Can anyone guide me on how to accomplish this?
spec/rails_helper.rb
require 'capybara/rspec'
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(
app,
phantomjs_options: [
'--debug=no',
'--load-images=no',
'--ignore-ssl-errors=yes',
'--ssl-protocol=TLSv1'
],
debug: false
)
end
https_spec.rb
require 'rails_helper'
RSpec.feature 'https' do
let(:admin) { create(:admin) }
scenario 'display admin dashboard', js: true do
login_as(admin, scope: :user)
visit admin_dashboard_index_path
expect(page).to have_text('TEST')
end
end
I get this message
Failures:
1) https display admin dashboard
Failure/Error: Unable to find matching line from backtrace
RuntimeError:
tried to create a new session when on http, but https is required
Maybe this is the solution to your problem:
http://cowjumpedoverthecommodore64.blogspot.com/2013/09/if-your-website-runs-under-ssl-than.html
I just started playing with Capycabra+poltergeist and after execution of my Capy test rspec ./spec/features/test_spec.rb
I got the following error:
Failure/Error: visit '/item/new'
ArgumentError: rack-test requires a rack application, but none was given
Also I have a few standard rspec tests and whenever I try to excute all tests, rspec tests are passed successfully, but only the capy test fails with weird error
ActionView::Template::Error: couldn't find file 'jquery.min' (in app/assets/javascripts/application.js:13)
Which leads me to the confusion.
I have viewed several similar threads on stackoverflow in some cases the error is about missing config.include Capybara::DSL in the spec_helper.rb or incorrect location of tests. I made appropriate changes, but it doesn't work, the error is still the same.
My spec_helper.rb file
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
RSpec.configure do |config|
config.include Capybara::DSL
end
Full Version of spec_helper: http://pastebin.com/qkANfu39
Test file:
#spec/features/test_spec.rb
require 'spec_helper'
describe 'accessibility of webpage' do
it 'should access web page' do
visit '/item/new'
expect(page).to have_content("Something")
end
end
Thoughts?
Update
This workaround is no longer needed according to the report(see in comments), but I haven't checked it yet.
Found workaround..
I had to specify the app host url and a default driver..
#spec/spec_helper.rb
require 'capybara'
require 'database_cleaner'
require 'capybara/dsl'
require 'capybara/poltergeist'
Capybara.configure do |c|
c.javascript_driver = :poltergeist
c.default_driver = :poltergeist
c.app_host = "http://localhost:3000"
end
Update 1
In order to fix error:
Failure/Error: visit '/item/new'
ArgumentError: rack-test requires a rack application, but none was given
I included rails_helper file into my Capy test. the final version of test:
require 'rails_helper'
require 'spec_helper'
describe 'accessibility of webpage' do
it 'should access web page' do
visit '/item/new'
expect(page).to have_content I18n.t("form_input.item.item_s")
end
end
After that for some reason specified app_host url no longer needed and it can be removed from the spec_helper helper file. The final version:
Capybara.configure do |c|
c.javascript_driver = :poltergeist
c.default_driver = :poltergeist
end
The full version of spec_helper.rb http://pastebin.com/DKgF1uQA
Error
ActionView::Template::Error: couldn't find file 'jquery.min' (in app/assets/javascripts/application.js:13)
Occurred because gem 'jquery-rails' wasn't available in the test scope in my Gemfile, It was available only in :development & :production environment. I moved the gem 'jquery-rails' out to the global scope. The full version of a Gemfile: http://pastebin.com/dt4KrHGG
I have a question with RSpec testing. I am using FactoryGirl, Capybara 2.* and trying to testing my website behavior.
Scenario of testing:
User clicking on sign_in button (devise controller), he is redirected to root_path (managed by MyController). After his redirection before_filter :setup_params should assign to #app variable (in action :find_apps in MyController) some values. I would like to ensure that #app is not nil and that values were assigned.
here is my sign_in_spec.rb
require "spec_helper.rb"
require "mymodel.rb"
describe MyContoller, :type => :feature do
before do
visit '/users/sign_in'
end
it "Shall redirect to user and ensure that #app is not nil" do
user = FactoryGirl.build(:user_monit)
fill_in "user[email]", with: user.email
fill_in "user[password]", with: user.password
#expect {click_button "Sign in"}.to change {#myapp}.from(nil)
click_button "Sign in"
get :find_apps
assigns(:myapp).should_not be_nil
end
end
require section in my spec_helper.rb
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'
require 'mocha/setup'
require 'factory_girl'
....
config.include RSpec::Rails::RequestExampleGroup, type: :feature
I have got several mistakes:
1) result should have changed, but is still nil
2) bad argument error for get :find_apps (ArgumentError: bad argument (expected URI object or URI string))
What am I doing wrong?
Thanks in advance!
You have to create User before you can login so :
user = FactoryGirl.create(:user_monit)
second issue you can resolve adding normal uri instead :find_apps the same like you make in before block
So I've been struggling with this for quite some time now and I can't seem to figure our what's going wrong, and couldn't find much on what could possibly cause this issue.
I'm relatively new to Ruby and Rails, as well as test/behavior driven development and am trying to write some acceptance (browser) tests using PhantomJS through Poltergeist, using Rspec and Capybara. I believe some people also call this integration tests (they may be from some perspective), but that's a whole other discussion.
I have a really simple feature that I can't get to do what I want:
require 'feature_helper'
feature 'Logging in', :js => true do
scenario 'with incorrect credentials' do
visit '/login'
puts page.html
save_and_open_page
page.driver.render('_screenshot.png', :full => true)
page.html.should have_selector("title", :text => "hi")
end
end
So. Simple, right. It should just go to /login and throw the HTML content at me, as well I want to see the page using save_and_open_page, and I want it to take a screenshot. I added a simple should have_selector in order to have the test fail in an attempt to get more feedback.
The relative contents of my feature_helper.rb:
require 'spec_helper'
require 'capybara/rspec'
require 'capybara/rails'
require 'capybara/poltergeist'
include Capybara::DSL
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
:debug => true,
:inspector => true
})
end
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
FakeWeb.allow_net_connect = %r[^https?://(127.0.0.1|localhost)] # allow phantomjs/poltergeist requests
DatabaseCleaner.strategy = :truncation
RSpec.configure do |config|
config.before :each do
# Set the hostname to something with test
#host = "test.iome:3003"
host! #host
Capybara.default_host = Capybara.app_host = "http://#{#host}/"
Capybara.server_port = 3003
Capybara.reset_sessions!
# Start the database cleaner
config.use_transactional_fixtures = false
DatabaseCleaner.start
end
config.after :each do
DatabaseCleaner.clean
end
end
And also my spec_helper.rb:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'pry'
require 'fakeweb'
FakeWeb.allow_net_connect = false
It's all fairly simple.
Now, in my console I see the following:
{"name"=>"visit", "args"=>["http://test.iome:3003//login"]}
{"response"=>{"status"=>"fail"}}
{"name"=>"body", "args"=>[]}
{"response"=>"<html><head></head><body></body></html>"}
<html><head></head><body></body></html>
{"name"=>"body", "args"=>[]}
{"response"=>"<html><head></head><body></body></html>"}
{"name"=>"render", "args"=>["_screenshot.png", true]}
{"response"=>true}
{"name"=>"body", "args"=>[]}
{"response"=>"<html><head></head><body></body></html>"}
Also, the screenshot is just a white and empty page. When I tail my log/test.log file, I don't see that a request is being performed. I've tried changing the method visit to get, and that'll make the request, but won't change any of the results.
I've completely run out of ideas of what this could be and it's rather frustrating :(
Final information then about versions:
rspec 2.10.0
capybara 1.1.4
poltergeist 1.0.3
ruby 1.8.7
rails 3.2.13
Unfortunately we're still at ruby 1.8.7, but are working on bumping that version up. Still, I think this shouldn't influence the tests.
Any help would be greatly appreciated!
So eventually I got help from a colleague, and we managed to fix it. We used the lvh.me domain for this, as any request to that domain will resolve in localhost, allowing you to use subdomains without a problem. You could probably also use hostname.127.0.0.1.xip.io for this.
Our spec_helper.rb now looks like this:
# Use capybara in combination with poltergeist for integration tests
require 'capybara/rails'
require 'capybara/rspec'
require 'capybara/poltergeist'
require 'rack_session_access/capybara'
Capybara.default_driver = :poltergeist
Capybara.always_include_port = true
Capybara.app_host = 'http://application-test.lvh.me' # Any lvh.me domain resolves to localhost
Capybara.default_wait_time = 8 # How long capybara should look for html elements
require 'vcr'
VCR.configure do |config|
config.cassette_library_dir = 'spec/vcr_cassettes'
config.hook_into :fakeweb
config.ignore_localhost = true
config.configure_rspec_metadata!
config.ignore_hosts 'codeclimate.com'
end
require 'fakeweb'
FakeWeb.allow_net_connect = false
Because we hooked in VCR to record any requests going out during the first run of the integration tests, all your integration tests, or features, should contain this code:
before(:all) do
FakeWeb.allow_net_connect = true
end
after(:all) do
FakeWeb.allow_net_connect = false
end
If you want to change the subdomain during your specs, you can use the following:
before(:each) do
#original_host = Capybara.app_host
Capybara.app_host = 'http://does-not-exist.lvh.me'
visit '/login'
end
after(:each) do
Capybara.app_host = #original_host
end
Making screenshots can now be done using page.save_screenshot during specs. Hope this helps.