2016-04-26 10 views
0

Ich habe eine RSpec-Feature-Spezifikation, die die Anmeldung für meine App testet. Es passiert, wenn ich es in RSpec mit Capybara ausführen, aber wenn ich versuche, es mit js: true mit Capybara-Webkit Flag ausgeführt, schlägt es fehl. Dies ist ein Problem, da sich meine gesamte App hinter dem Login befindet. Wenn ich dieses Bit nicht ausführen kann, weiß ich nicht, wie ich Feature-Spezifikationen für den Rest der App ausführen soll.Ich kann mich nicht mit Capybara-webkit anmelden, aber RSpec/Capybara funktioniert gut

Hier ist, was ich versucht habe:

  • Installation alle Capybara-webkit Abhängigkeiten listed here. Ich verwende meine App in einem Docker-Container, der auf dem Ruby: 2.3-Image basiert, das auf Jessie basiert.
  • Datenbank-Cleaner einrichten per this blog post. Meine database_cleaner.rb Datei ist unten.
  • die Headless gem Verwendung (headless.rb unten)
  • RSpec Rennen wie folgt: xvfb-run -a bin/rspec spec/features/log_in_spec.rb (nicht anders scheint als es normalerweise mit Headless läuft)

Wie erhalte ich meine Login-Spezifikationen unter Capybara zu arbeiten -Webkit? Einige meiner Spezifikationen müssen für JS markiert werden, andere nicht, aber sie müssen alle angemeldet sein. Danke.

log_in_spec.rb

require 'rails_helper' 

RSpec.feature "Log in", type: :feature do 

    scenario "as admin" do 
    user = create(:admin) 

    # Tried this instead of with Capybara, works with Capybara but not capybara-webkit  
    # login_as user, scope: :user, run_callbacks: false 

    visit root_path 
    fill_in 'Email', with: user.email 
    fill_in 'Password', with: user.password 
    find('.btn-primary').click 
    expect(page).to have_content('Admin') 
    end 
end 

spec_helper.rb

require 'capybara/rspec' 
require 'paperclip/matchers' 

RSpec.configure do |config| 

    Capybara.javascript_driver = :webkit 
    Capybara.app_host = 'https://192.168.99.101' 

    config.include Paperclip::Shoulda::Matchers 

    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 
    mocks.verify_doubled_constant_names = true 
    end 

    config.filter_run :focus 
    config.run_all_when_everything_filtered = true 

    config.disable_monkey_patching! 

    if config.files_to_run.one? 
    config.default_formatter = 'doc' 
    end 

end 

rails_helper.rb

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? 
require 'spec_helper' 
require 'rspec/rails' 

require 'capybara/rails' 
require 'devise' 
require 'support/controller_macros' 

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 

# Checks for pending migrations before tests are run. 
# If you are not using ActiveRecord, you can remove this line. 
ActiveRecord::Migration.maintain_test_schema! 

RSpec.configure do |config| 
    config.use_transactional_fixtures = false 

    config.filter_rails_from_backtrace! 

    config.include Warden::Test::Helpers 
    config.before :suite do 
    Warden.test_mode! 
    end 

    config.after :each do 
    Warden.test_reset! 
    end 

end 

# Added headless gem and this code thanks to this post: http://stackoverflow.com/a/28706535/3043668 
if ENV['HEADLESS'] 
    require 'headless' 
    headless = Headless.new 
    headless.start 
    at_exit { headless.stop } 
end 

spec/support/database_cleaner.rb

RSpec.configure do |config| 
    config.before(:suite) do 
    DatabaseCleaner.clean_with(:truncation) 
    end 

    config.before(:each) do 
    DatabaseCleaner.strategy = :transaction 
    end 

    config.before(:each, js: true) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each) do 
    DatabaseCleaner.start 
    end 

    config.after(:each) do 
    DatabaseCleaner.clean 
    end 
end 

spec/support/headless.rb

RSpec.configure do |config| 
    config.around type: :feature do |example| 
    Headless.ly do 
     example.run 
    end 
    end 
end 

spec/support/capybara.rb

Capybara::Webkit.configure do |config| 
    config.debug = true 
    config.allow_unknown_urls 
    config.timeout = 5 
    config.ignore_ssl_errors 
    config.skip_image_loading 
end 

Hier ein Kern der debug output from Capybara-webkit, wenn ich den Test ausführen. Es sieht so aus, als würde es immer und immer wieder dasselbe versuchen.

UPDATE Ich entfernte meine Capybara.app_host Einstellung, und die nicht-JS Test besteht nach wie vor, aber wenn ich es unter Capybara-webkit laufen, sehe ich in der debig Ausgabe:

Received 0 from "https://127.0.0.1:37193/login" 
Page finished with false 
Load finished 
Page load from command finished 
Wrote response false "{"class":"InvalidResponseError","message":"Unable to load URL: http://127.0.0.1:37193/login because of error loading https://127.0.0.1:37193/login: Unknown error"}" 
Received "Reset()" 
Started "Reset()" 
undefined|1|SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent. 

Es versucht zu visit("/login") und es wird auf die https-Version umgeleitet, und dies macht es fehlgeschlagen. Wie kann ich Erfolg haben?

+0

Ihre use_transactional_fixtures und database_cleaner-config sehen für mich aus, als ob es sich um Out-of-Process-Tests handelt, daher denke ich nicht, dass der Verbindungs-Sharing-Hack notwendig sein sollte. Das heißt, ich weiß nicht, was das Problem ist. Ich würde save_and_open_page und save_and_open_screenshot versuchen. –

Antwort

0

Das war ein harter. Aber das Problem war, dass ich in meiner application.rb force_ssl = true gesetzt hatte, dumm, anstatt es in production.rb und development.rb wie eine normale Person zu setzen.

Ich hatte auch Capybara-webkit app_host eingestellt, was, wie sich herausstellte, ich nicht tun musste. Nachdem ich das entfernt hatte und capybara-webkit mit debug gestartet hatte, sah ich, dass es versuchte, von http://localhost:45362/login (oder welchem ​​Port) zu https://localhost:45362/login umzuleiten (beachte die https!) Und dass dies einen DOM 18 Sicherheitsfehler verursachte oder was auch immer, und Das hat es erstickt. Ich habe force_ssl ausgeschaltet und jetzt funktioniert es wie ein Champion. Hoffe, das hilft dir, deine Haare nicht zu zerreißen.

1
  1. Der erste Grund ist, dass der Datensatz nach dem Verfahren c save = hält das Passwort nicht in der normalen Ansicht, scheint aber, dass es in diesem Fall gut ist:

    user = create(:admin) 
    # ... 
    user = User.first # wrong way 
    #... 
    fill_in 'Password', with: 'password' 
    
  2. Der zweite Grund in scheitern Um sich anzumelden, verwendet das Fabrikmädchen und Capybara getrennte Verbindungen, und Daten, die in einer Sitzung erstellt wurden, sind in einer anderen nicht verfügbar. Um es zu beheben, verwenden Sie ein einzelnes Verbindungs-Patch (setzen Sie es auf spec/Unterstützung) wie beschrieben here.

+0

Ich habe das versucht, hat nicht funktioniert. Aber ich denke, dass es den Wert in Ordnung bringt, habe ich 'print 'hinzugefügt E-Mail senden: # {find (' # user_email '). Value} \ n" 'und' print "Passwort senden: # {find (' # user_password ') .value} \ n "' und sah die richtigen Werte in der Debugger-Ausgabe. –

+0

@DavidHam Ah, erinnerte mich, hast du Single Connection Patch? –

+0

Nein, was ist das? –

Verwandte Themen