2014-06-23 16 views
5

Secondo il Capybara Docs ci sono due strategie distinte per la gestione di problemi con selenio non essere in grado di accedere ai dati generati in un test:È possibile utilizzare Selenium/Capybara Webkit/Poltergeist senza patch ActiveRecord?

  1. toppa Scimmia ActiveRecord:

    classe ActiveRecord :: Base @ @shared_connection = nil def self.connection @@ shared_connection || retrieve_connection fine fine ActiveRecord :: Base.shared_connection = ActiveRecord :: Base.connection

  2. utilizzare la troncatura, piuttosto che le transazioni

ho impostato DatabaseCleaner come sottolineato dal Avdi Grimm here, e anche se osservando i miei registri posso vedere chiaramente DatabaseCleaner sta usando il troncamento, ad esempio:

(7,4 ms) TRUNCATE TABLE "gallerie", "foto", "utenti" RESTART IDENTITY CASCADE;

... quando si esegue la mia funzione, tutti i modelli creati durante la configurazione non sono disponibili per il driver. Posso vedere i modelli esistono all'interno dello scenario, ma se li stampo sulla pagina, non esistono.

L'unico modo che posso ottenere il driver per vedere i modelli è se uso l'ActiveRecord scimmia-patch sopra, ma questo sembra chiamare un sacco di problemi secondari strani - prove di appendere ecc

Perché è che il driver (Selenium o Capybara-Webkit) non può vedere i modelli creati nei test anche quando utilizzo DatabaseCleaner con una strategia di troncamento e come posso far funzionare Capybara con un driver JavaScript?

Nota: Il test viene superato bene con il driver predefinito

La mia configurazione DatabaseCleaner:

RSpec.configure do |config| 

    # Clean DB completely 
    config.before(:suite) do 
    DatabaseCleaner.clean_with(:truncation) 
    end 

    # Set default strategy (non-js/Rack::Test) 
    config.before(:each) do 
    DatabaseCleaner.strategy = :transaction 
    end 

    # Set strategy for tests using JS (slower) 
    config.before(:each, js: true) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    # Wrap DatabaseCleaner around each test (before & after) 
    config.before(:each) do 
    DatabaseCleaner.start 
    end 

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

end 

Ecco un esempio di una caratteristica che vorrei usare JavaScript per prova:

feature "User deletes a photo" do 

    before { 
    as_signed_in_user 
    @gallery = create(:gallery_with_photos) 
    } 

    scenario "successfully deletes a photo from a gallery", js: true do 

    photo_title = @gallery.photos.first.title 
    puts "GALLERY #{Gallery.find(1)}" # <Gallery:0x007f9b928fe8e8> 
    visit gallery_path(@gallery) # JavaScript driver can't find gallery 

    within '.photos-list' do 
     click_link photo_title 
    end 
    click_link('Delete Photo') 

    expect(current_path).to eq(gallery_path(@gallery)) 
    expect(page).not_to have_link(photo_title) 

    end 

end 

Quando si utilizza il driver JavaScript, questo test ha esito negativo con:

1) User deletes a photo successfully deletes a photo from a gallery 
    Failure/Error: Unable to find matching line from backtrace 
    ActiveRecord::RecordNotFound: 
     Couldn't find Gallery with 'id'=1 

Come suggerito da Dave Schweisguth nei commenti, ho cercato di spostare il js:true fuori alla funzione, piuttosto che allo scenario senza avere alcun effetto.

+0

Dove stai mettendo il tag ': js' nelle tue specifiche? Se si trova su 'feature' /' describe', prova a taggare l'allegato 'scenario' /' it'. (Potrebbe essere necessario ristrutturare le specifiche in modo che abbiano senso.) –

+0

@DaveSchweisguth Grazie, ma nessuna differenza. – Undistraction

+0

C'è una ragione particolare per cui stai creando la galleria dopo aver effettuato l'accesso? La mia ipotesi è che il test si muova più rapidamente di quanto il database possa creare la galleria e renderla disponibile per il test. – nowk

risposta

3

Assicurarsi di utilizzare l'ultima versione del pulitore per database, capybara, selenio per web selenio . Assicurati inoltre che tutte quelle gemme siano nel gruppo di prova e siano require: false

Quindi nel file spec_helper.rb puoi controllare l'ordine di caricamento richiedendo le rotaie prima di quelle gemme.Assicurarsi che anche un corretto le impostazioni per RAILS_ENV e use_transactional_fixtures

spec_helper.rb

require 'rubygems' 

ENV['RAILS_ENV'] ||= 'test' 

# Load rails + environment 
require File.expand_path('../../config/environment', __FILE__) 
require 'rspec/rails' 

# Load database cleaner 
require 'database_cleaner' 

# Load capybara and its dependencies 
require 'capybara/rspec' 
require 'capybara/rails' 
require 'selenium-webdriver' 

RSpec.configure do |config| 
    # Do not use transactional, let database_cleaner do the work 
    config.use_transactional_fixtures = false 

    # Database cleaner config 
    config.before(:suite) { DatabaseCleaner.clean_with :truncation } 
    config.before(:each) { DatabaseCleaner.strategy = :transaction } 
    config.before(:each, js: true) { DatabaseCleaner.strategy = :truncation } 

    config.before(:each) { DatabaseCleaner.start } 
    config.after(:each) { DatabaseCleaner.clean } 
end 

Caratteristica spec

Provate ad usare describe ... type: :feature invece, e lo spostamento js: true in alto, in questo modo:

describe "User deletes a photo", type: :feature, js: :true do 
    before { ... } 
    scenario "successfully deletes a photo from a gallery" do 
    ... 
    end 
end 

Il tuo codice

1- Non scrivere puts "GALLERY #{Gallery.find(1)}" anche per un rapido debug. In alcuni casi può generare un errore e causare confusione (ti fa pensare che il problema non si risolva quando effettivamente lo è). Utilizzare questo invece puts "GALLERY #{Gallery.find(@gallery.id)}"

2- Inoltre non è una buona pratica in rspec da usare variabile di istanza, così invece di questo:

before { 
    as_signed_in_user 
    @gallery = create(:gallery_with_photos) 
} 

vostro dovrebbe scrivere questo

before { as_signed_in_user } 
let!(:gallery) { create(:gallery_with_photos) } 

Nota che uso let! con un botto, è equivalente a un before. Quindi nel resto delle tue specifiche devi sostituire @gallery per gallery

+0

Grazie per la risposta completa. In qualche modo non sapevo di "let!", E hai assolutamente ragione riguardo a 'Gallery.find (1) 'hardcoded e alle variabili di istanza. Anche se sono abbastanza sicuro di avere tutto pronto come descriveresti, ci penserò più tardi oggi. – Undistraction

+0

Errore di ortografia: nel tuo file gemma, è 'require: false', senza 's'. Presumo che tu abbia corretto quello – Benj

+0

Inoltre ho dimenticato di menzionare, se hai già qualche patch, assicurati di rimuoverli – Benj

Problemi correlati