I'm setting up Capybara with Selenium Webdriver in my Rails application, and I keep running into the following error:
Helpdesk Ticketing System assigning a ticket should mark ticket as assigned
Failure/Error: visit tickets_path
Selenium::WebDriver::Error::UnknownError:
unknown error: net::ERR_CONNECTION_REFUSED
(Session info: chrome=85.0.4183.102)
My settings are as follows:
Capybara.server = :puma
Capybara.app_host = 'http://intranet.lvh.me'
Capybara.default_driver = :selenium_chrome_headless
In the logs it shows this before the failure, choosing a different port each time it runs:
Capybara starting Puma...
* Version 4.3.6 , codename: Mysterious Traveller
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:56277
Anyone help?
I solved my problem. I was missing:
Capybara.always_include_port = true
I had set route-level URL defaults inside of config/environments/test.rb and that option pulls through to all parts of the application.
When I removed the line shown below, all my tests passed again.
# config/environments/test.rb
Rails.application.routes.default_url_options = {
host: "server.localhost",
port: 3000
}
Related
My Rails application doesn't output the result of the system tests (no failures, no assertions, nothing). The funny thing is that I can see chrome doing what it was expected to do (filling fields, etc...), but when the test is finished, no output on the shell, just the following:
francesco.mari#MB68D:DemographicsMapper (inline_mapping_editing *) $ bin/rails test:system
Puma starting in single mode...
* Version 4.3.8 (ruby 2.6.6-p146), codename: Mysterious Traveller
* Min threads: 0, max threads: 4
* Environment: test
* Listening on tcp://127.0.0.1:49330
Use Ctrl-C to stop
francesco.mari#MB68D:DemographicsMapper (inline_mapping_editing *)
Apparently the issue was on the file test_helper.rb. After I added the line parallelize(workers: :number_of_processors) it worked as it should.
class ActiveSupport::TestCase
#...
parallelize(workers: :number_of_processors) # added this line
#...
end
macos 10.13.6
jruby 9.2.0.0
rspec 3.8.2
capybara 3.28.0
apparition 0.3.0
chrome 76.0.3809.100
Current configuration (tried various options that had no effect:
require 'capybara/apparition'
Capybara.register_driver :apparition do |app|
Capybara::Apparition::Driver.new(app, { headless: true })
end
Capybara.configure do |config|
config.default_max_wait_time = 10
config.ignore_hidden_elements = true
config.default_driver = :apparition
config.javascript_driver = :apparition
end
I'm getting something like this when I attempt to run using apparition:
Capybara starting Puma...
* Version 4.1.0 , codename: Fourth and One
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:50136
DevTools listening on ws://127.0.0.1:50140/devtools/browser/003bf437-48ff-45f9-ac9e-fa0526d904dc
After which it sits there until I force quit out. If headless mode is off, it pops open a browser window, which I can use to visit the Puma listening port but otherwise doesn't actually do anything.
Am I doing something wrong here?
Disclaimer: The reason I tried this in the first place was that chrome/chromedriver updated and borked my selenium chromedriver setup.
UPDATE: This should be fixed in Apparition 0.4.0
——————————————-
Apparition currently isn't working with JRuby - you'll have to swap to MRI to test using Capybara with Apparition.
I am trying to get capybara to run test puma server over ssl. Need help configuring it, please:
Capybara.register_server :ssl_puma do |app, port, host|
require 'rack/handler/puma'
Rack::Handler::Puma.run(app, Host: host, Port: port, Threads: "0:1") do |server|
ctx = Puma::MiniSSL::Context.new
ctx.key = ENV['SSL_KEY_PATH']
ctx.cert = ENV['SSL_CERT_PATH']
ctx.verify_mode = Puma::MiniSSL::VERIFY_NONE
server.add_ssl_listener host, port, ctx # this line is wrong, but that's the gyst of what needs to happen
end
end
Any ideas?
If you're using a recent version of Capybara I believe you should be able to do something like
Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{ENV['SSL_KEY_PATH']}&cert=#{ENV['SSL_CERT_PATH']" }
Rails 5.1 introduced system testing that uses Capybara with Selenium to test the UI of Rails application.
I'm wondering to how to use this system testing to test the UI of error pages.
For standard controller tests, we can do something like below to assert response to be 404.
test 'should get not_found' do
get errors_not_found_url
assert_response :not_found
end
But for system tests, if I go to a 404 page, exception will be thrown in controller level and tests terminate immediately without rendering the page.
test '404 page should render with the correct title' do
# act.
visit NOT_FOUND_URL
# assert.
assert_equal("#{APP_NAME} - #{TITLE_404}", page.title)
end
Exception is thrown in controller level.
$ rails test test/system/error/error_page_test.rb
Run options: --seed 30076
# Running:
Puma starting in single mode...
* Version 3.9.1 (ruby 2.3.1-p112), codename: Private Caller
* Min threads: 0, max threads: 1
* Environment: test
* Listening on tcp://0.0.0.0:55237
Use Ctrl-C to stop
2017-07-09 11:10:45 +1200: Rack app error handling request { GET /books/12345678 }
#<ActionController::RoutingError: Could not find book '12345678' by id or name>
/myapp/app/controllers/books_controller.rb:7:in `index'
/Users/yze14/.rvm/gems/ruby-2.3.1/gems/actionpack-5.1.2/lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
/Users/yze14/.rvm/gems/ruby-2.3.1/gems/actionpack-5.1.2/lib/abstract_controller/base.rb:186:in `process_action'
...
Under development/test environment, config.consider_all_requests_local can be set to false in order to show error page instead of stracktrace. But this doesn't swallow exception during system tests.
If you don't want Capybara to re-raise server exceptions in the tests you can set Capybara.raise_server_errors = false.
Secondly, you should check your Gemfile and make sure any gems like web-console,better-errrors, etc are only loaded in the development environment (not in the test environment)
Finally, you shouldn't be using assert_equal with title, you should be using the Capybara provided assert_title which includes waiting/retrying behavior and will reduce potential flakiness in tests.
assert_title("#{APP_NAME} - #{TITLE_404}")
I have problems figuring out the good way to set up the host/port for test on CircleCI
EDIT 2 - Requirements :
Rails app running locally on TEST_PORT (if available in ENV variable) or on default port 3000
I have session based tests, so magically switching from localhost to 127.0.0.1 will cause test failures
On my CircleCI environment I mapped host www.example.com to 127.0.0.1 and I'd like Capybara to connect to that website instead of directly localhost/127.0.0.1
On my CircleCI environment the port 80 is reserved so the rails app HAS to run on a different port (like 3042)
Some integration tests need to connect to remote website (Sorry no VCR yet) www.example-remote.com on port 80
Previously my test suite was running fine with localhost:3042 but then I realized I had problems with tests that used session : the rails app itself started on localhost but then emails were sent to the 127.0.0.1 address which caused session-based tests to fail
I changed the following config
# feature/env.rb
Capybara.server_port = ENV['TEST_PORT'] || 3042
Rails.application.routes.default_url_options[:port] = Capybara.server_port
if ENV['CIRCLECI']
Capybara.default_host = 'http://www.example.com/'
end
# configuration/test.rb
config.action_mailer.default_url_options = {
host: (ENV['CIRCLECI'].present? ? 'www.example.com' : '127.0.0.1'),
port: ENV['TEST_PORT'] || 3042
}
# circle.yml
machine:
hosts:
www.example.com: 127.0.0.1
But now I'm getting weird email urls being generated like http://www.example.com/:3042/xxx
Did someone manage a working configuration on circleCI using custom host name ?
EDIT
Capybara 2.13
Rails 5.0
Cucumber 2.4
CircleCI 1.x
Capybara.default_host only affects tests using the rack_test driver (and only if Capybara.app_host isn't set). It shouldn't have the trailing '/' on it, and it already defaults to 'http://www.example.com' so your setting of it should be unnecessary.
If what you're trying to do is make all your tests (JS and non-JS) go to 'http://www.example.com' by default then you should be able to do either
Capybara.server_host = 'www.example.com'
or
Capybara.app_host = 'http://www.example.com'
Capybara.always_include_port = true
My new config which seems to work for session-based tests but fails for remote websites (it tries to reach the remote server with the same TEST_PORT I have defined (eg click on email with http://www.example-remote.com/some_path --> Capybara connects to http://www.example-remote.com:TEST_PORT/some_path)
# features/env.rb
# If test port specified, use it
if ENV['TEST_PORT'].present?
Capybara.server_port = ENV['TEST_PORT']
elsif ActionMailer::Base.default_url_options[:port].try do |port|
Capybara.server_port = port
end
else
Rails.logger.warn 'Capybara server port could not be inferred'
end
# Note that Capybara needs either an IP or a URL with http://
# Most TEST_HOST env variable will only include domain name
def set_capybara_host
host = [
ENV['TEST_HOST'],
ActionMailer::Base.default_url_options[:host]
].detect(&:present?)
if host.present?
# If the host is an IP, Capybara.app_host = IP will crash so do nothing
return if host =~ /^[\d\.]+/
# If hostname starts with http(s)
if host =~ %r(^(?:https?\:\/\/)|(?:\d+))
# OK
elsif Capybara.server_port == 443
host = 'https://' + host
else
host = 'http://' + host
end
puts "Attempting to set Capybara host to #{host}"
Capybara.app_host = host
else
Rails.logger.warn 'Capybara server host could not be inferred'
end
end
set_capybara_host
# config/environments/test.rb
Capybara.always_include_port = true
config.action_mailer.default_url_options = {
host: (ENV['TEST_HOST'].present? ? ENV['TEST_HOST'] : '127.0.0.1'),
port: (ENV['TEST_PORT'].present? ? ENV['TEST_PORT'] : 3042)
}