Integrate Capybara in SInatra app with rspec result always in 504 tests - ruby

I don't get capybara working with my modular sinatra app. I created a small test app and have the same issue. I get always a 504 Timeout Error and i think that the app isn't really loaded by Capybara regardless the Line Capybara.app = Testapp in the acceptance_helper.
Browser Firefox opens when test is running but don't go to any URL and shows always a blank site.
When i do the same test only with rspec it works (second one).
What i'm doing wrong?
My Setup:
OS: Win 7 Professional 64-bit
Ruby version: ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]
Firefox version: 40.0.3
gem versions
- sinatra (1.4.6)
- rspec (3.3.0)
- capybara (2.7.1)
- selenium-webdriver (2.53.4)
- thin (1.5.1)
- rack (1.6.4)
- rack-test (0.6.3)
App structure:
test_sinatra_capybara
|
|- testapp.rb
|- spec
| |- spec_helper.rb
| |- acceptance_helper.rb
| |- testapp_spec.rb
|- views
| |- index.slim
testapp.rb
require 'sinatra'
require 'sinatra/base'
require 'slim'
class Testapp < Sinatra::Base
get '/' do
slim :index
end
end
index.slim
#test-id
| Willkommen
spec_helper.rb
require 'rspec'
require 'rack/test'
require_relative '../testapp'
Testapp.environment = :test
module RSpecMixin
include Rack::Test::Methods
def app() Testapp end
end
RSpec.configure do |config|
config.include RSpecMixin
# Use color in STDOUT
config.color = true
# Use the specified formatter
config.formatter = :documentation
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
acceptance_helper.rb
require File.dirname(__FILE__) + '/spec_helper'
require 'capybara'
require 'capybara/rspec'
Capybara.default_driver = :selenium
Capybara.app = Testapp
RSpec.configure do |config|
config.include Capybara::DSL
config.include Capybara::RSpecMatchers
end
testapp_spec.rb
require File.dirname(__FILE__) + '/acceptance_helper'
describe 'URLs that require login' do
it "start page capybara" do
# I tried both
visit '/'
# visit 'http:localhost:4567'
page.should have_content("Willkommen")
end
it "start page rspec" do
get "/"
expect(last_response.body).to include("Willkommen")
end
end
So as i said, last test is working:
Finished in 12.91 seconds (files took 2.54 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/testapp_spec.rb:4 # URLs that require login start page capybara
Error on First test:
Selenium::WebDriver::Error::WebDriverError:
unexpected response, code=504, content-type="text/html"

Running the exact code posted works fine for me, which I'm guessing means one of two things. Either the version of Firefox you're using is outdated (make sure you're using 47.0.1) or you're on a machine that has a proxy server or firewall that is interfering with requests to 127.0.0.1:<some random port>. The default Capybara config starts up a server on 127.0.0.1:<random port> to handle requests for the app under test. If those connections are blocked or proxied elsewhere it will obviously prevent things from working properly. If you need to bind to a different interface or set a fixed port to get around corporate firewall/proxy restrictions you can do that by setting Capybara.server_host and Capybara.server_port

Related

Sinatra I18n Fallbacks using Rack::Locale

I'm trying to set up a simple Sinatra app with I18n, following the recommended Sinatra recipe, and using Rack:Locale to determine the language.
My app.rb:
require 'rubygems'
require 'sinatra'
require 'rack/contrib'
require 'i18n'
require 'i18n/backend/fallbacks'
require 'tilt/haml'
use Rack::Locale
configure do
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
I18n.load_path = Dir[File.join(settings.root, 'locales', '*.yml')]
I18n.backend.load_translations
end
helpers do
def t(*args)
I18n.t(*args)
end
end
get '/' do
haml :index
end
My locales/en.yml:
en:
welcome: "Welcome!"
When I run rackup and visit the root path of my Sinatra app, I get the following:
I18n::InvalidLocale at /
"en-US" is not a valid locale
file: i18n.rb location: enforce_available_locales! line: 284
I thought that the I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks) would handle this, by not finding en-US and falling back to en (which I have), but apparently not. What am I missing?
Add:
I18n.enforce_available_locales = false

How to embed a screenshot with minitest-reporters

I am using minitest with Jenkins to produce test reports. At the moment I am using Minitest::Reporters::JUnitReporter - https://github.com/kern/minitest-reporters. This seems to give nice concise results.
The only thing missing is an embedded screenshot, specifically from failed tests.
How can I produce a Jenkins friendly test report that includes a screenshot? I am open to use one of the other Minitest::Reporters if it helps.
Thanks
You can use the capybara-screenshot gem for this: https://github.com/mattheworiordan/capybara-screenshot
Gemfile:
group :test do
gem 'capybara', '2.6.0'
gem 'selenium-webdriver', '2.49.0'
gem 'poltergeist', '1.8.1'
gem 'capybara-screenshot', '1.0.11'
end
test_helper.rb:
# default rails test configuration
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
# configure webtests with capybara and poltergeist (headless)
require 'capybara/rails'
require 'capybara/poltergeist'
require 'capybara-screenshot/minitest'
if ENV['HEADLESS'] == 'true'
# headless driver configuration
Capybara.default_driver = :poltergeist
else
Capybara.default_driver = :selenium
end
Capybara::Screenshot.prune_strategy = :keep_last_run # keep screenshots only from the last test run
Capybara.save_and_open_page_path = File.join(Rails.root, "test/screenshots") # where to save screenshots
# default test class for unit tests
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
end
# default test class for webtests
class ActionDispatch::IntegrationTest
include Capybara::DSL
include Capybara::Screenshot::MiniTestPlugin
end

Running rspec in Sinatra app just starts the server

I'm using rspec to test my Sinatra app. The app is super simple, and so are the tests, but when I run rspec from the CLI, it just starts the app server. I've never had this happen.
Here's what my spec_helper.rb looks like:
#spec/spec_helper.rb
require File.expand_path '../../app.rb', __FILE__
ENV['RACK_ENV'] = "test"
require 'rspec'
require 'rack/test'
set :environment, :test
set :run, false
set :raise_errors, true
set :logging, false
module RSpecMixin
def app
App.new
end
end
RSpec.configure do |config|
config.color_enabled = true
config.tty = true
config.formatter = :documentation
config.include Rack::Test::Methods
config.include RSpecMixin
end
And my spec is just
require 'spec_helper'
describe "My Sinatra Application" do
it "should allow accessing the home page" do
expect(1).to eq(1)
end
end
I can't get rspec to run.
What I've tried:
I've tried the recommendations in this Sinatra testing guide. Also the rspec Sinatra test recipe. In this blog post, the set :run, false looked promising, but no dice. Then I thought, I'll just define a rake task. Putting the rspec gem in the test group and setting the RACK_ENV to test. All these things just start the app server:
$ rake spec
[2014-03-08 22:06:38] INFO WEBrick 1.3.1
[2014-03-08 22:06:38] INFO ruby 2.0.0 (2013-02-24) [x86_64-darwin11.4.2]
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from WEBrick
[2014-03-08 22:06:38] INFO WEBrick::HTTPServer#start: pid=21538 port=4567
Halp?
Try removing the new() from your def app:
module RSpecMixin
def app
App
end
end
An other way to create your app for testing is something like this:
APP = Rack::Builder.parse_file('config.ru').first
module RSpecMixin
def app
APP
end
end
Obvious this works only if you use config.ru.
I found the answer. It's embarrassing, but I was switching back and forth between the modular and classic style deciding which I liked best, and I had left an errant App.run! call at the bottom of my app.rb file.

No perfomance gains from using em-http-request

I'm trying to understand how to use various non-blocking IO libraries in Ruby and made a simple app for testing using Sinatra,
# proxy.rb
require 'bundler/setup'
require 'sinatra/base'
require 'sinatra/synchrony'
require 'faraday'
class ProxyApp < Sinatra::Base
register Sinatra::Synchrony
get "/proxy" do
conn = Faraday.new("http://mirror.yandex.ru") do |faraday|
faraday.use Faraday::Adapter::EMSynchrony
end
conn.get "/ubuntu-releases/precise/ubuntu-12.04.1-alternate-i386.iso"
"Hello, world"
end
get "/" do
"Hello, world"
end
end
As far as I understand, downloading a file using non-blocking IO should allow other requests to execute, but it doesn't - if I'm using ab to open /proxy path (I'm using Thin as an app server), request to / takes a very long time. Am I doing something wrong?
Sinatra::Synchrony? Why?
config.ru:
require File.join Dir.pwd, 'proxy.rb'
run Proxy
Gemfile:
source 'https://rubygems.org'
gem 'sinatra'
gem 'thin'
gem 'faraday'
gem 'em-synchrony'
gem 'em-http-request'
gem 'rack-fiber_pool'
proxy.rb:
require 'bundler'
Bundler.require
class Proxy < Sinatra::Base
use Rack::FiberPool
get "/proxy" do
conn = Faraday.new("http://mirror.yandex.ru") do |faraday|
faraday.use Faraday::Adapter::EMSynchrony
end
conn.get "/ubuntu-releases/precise/ubuntu-12.04.1-alternate-i386.iso"
"Hello, world"
end
get "/" do
"Hello, world"
end
end
Start:
thin start -d
wget localhost:3000/proxy
In another terminal:
wget localhost:3000/
The reply is immediate for /, no matter how many requests to /proxy you do in parrallel.

deploy a sinatra app with passenger gives only 404, page not founds. Yet a simple rack app works

I have correctly (or prbably not) installed passenger on apache 2. Rack works, but sinatra keeps giving 404's.
Here is what works:
config.ru:
#app = proc do |env|
return [200, { "Content-Type" => "text/html" }, "hello <b>world</b>"]
end
run app
Here is what works too:
Running the app.rb (see below) with ruby app.rb and then looking at localhost:4567/about and /
restarting the app, gives me a correct hello world. w00t.
But then there is the sinatra entering the building:
config.ru
require 'rubygems'
require 'sinatra'
root_dir = File.dirname(__FILE__)
set :environment, ENV['RACK_ENV'].to_sym
set :root, root_dir
set :app_file, File.join(root_dir, 'app.rb')
disable :run
run Sinatra::Application
and an app.rb
require 'rubygems'
require 'sinatra'
get '/' do
"Hallo wereld!"
end
get '/about' do
"Hello world, it's #{Time.now} at the server!"
end
This keeps giving 404s.
/var/logs/apache2/error.log lists these correctly as "404" with something that worries me:
83.XXXXXXXXX - - [30/May/2010 16:06:52] "GET /about " 404 18 0.0007
83.XXXXXXXXX - - [30/May/2010 16:06:56] "GET / " 404 18 0.0007
The thing that worried me, is the space after the / and the /about. Would apache or sinatra go looking for /[space], like /%20?
If anyone knows what this problem relates to, maybe a known bug (that I could not find) or a known gotcha?
Maybe I am just being stupid and getting "it all wrong?"
Otherwise any hints on where to get, read or log more developers data on a running rack, sinatra or passenger app would be helpfull too: to see what sinatra is looking for, for example.
Some other information:
Running ubuntu 9.04, apache2-mm-prefork (deb), mod_php5, ruby 1.8.7, passenger 2.2.11, sinatra 1.0
You are not loading the routes in app.rb. To do this, replace require 'sinatra' with require File.join(File.dirname(__FILE__), 'app.rb') in config.ru.
root_dir = File.dirname(__FILE__)
app_file = File.join(root_dir, 'app.rb')
require app_file
set :environment, ENV['RACK_ENV'].to_sym
set :root, root_dir
set :app_file, app_file
disable :run
run Sinatra::Application
set :app_file won't load them for you.
Just substitute the require sinatra with a require 'app' and you're set to go.

Resources