Ich habe seltsame Probleme mit einigen meiner Feature-Tests mit Capybara mit Poltergeist-Treiber. Der Test sollte einen einfachen Checkout in meinem Online-Shop durchführen. Sie alle gehen gut auf meinem lokalen MacBook sowie auf einer Ubuntu Vagrants Box. Bei CI-Diensten wie Codeship, Wercker oder Semaphore scheitern sie jedoch mit dem gleichen Fehler.Capybara Poltergeist Feature-Test scheitert an CI, aber passiert lokal
Meine spec:
require 'rails_helper'
describe 'Checkout' do
let!(:product) { FactoryGirl.create(:product) }
it 'checks out via CreditCard', js: true do
visit products_path
expect(page.body).to have_link('Test Product 1')
click_link('Test Product 1')
#rest of spec ommitted
end
end
Der Fehler, den ich auf CI bekommen ist:
2) Checkout checks out via CreditCard
Failure/Error: click_link('Test Product 1')
Capybara::ElementNotFound:
Unable to find link "Test Product 1"
Für mich diese super seltsam ist, als die erste Erwartung "erwarten (page.body). to have_link ('Test Product 1') 'scheint zu bestehen, aber dann scheitert es im nächsten Schritt, wo es eigentlich auf den Link klicken sollte, der gerade auf der Seite vorhanden war?
Ich habe dann Poltergeist Treiber wie folgt neu konfiguriert, um mehr Debug-Informationen zu sammeln.
Snippet rails_helper.rb:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {js_errors: false,
#inspector: true,
phantomjs_logger: Rails.logger,
logger: nil,
phantomjs_options: ['--debug=no', '--load-images=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1'],
debug: true
})
end
Capybara.server_port = 3003
Capybara.app_host = 'http://application-test.lvh.me:3003' # lvh.me always resolves to 127.0.0.1
Capybara.javascript_driver = :poltergeist
Capybara.current_driver = :poltergeist
Capybara.default_wait_time = 5
Jetzt kann ich auf CI-Konsole sehen, dass der Test erfolgreich meine products_path und die erwartete HTML-Seite besucht (einschließlich meinem Link sollte es klicken) zurückgegeben wird. ich den Rest der HTML-Antwort entfernt, um es besser lesbar zu machen:
{"name"=>"visit", "args"=>["http://application-test.lvh.me:3003/products"]}
{"response"=>{"status"=>"success"}}
{"name"=>"body", "args"=>[]}
{"response"=>"--- snip --- <div class=\"info\">\n<a class=\"name color-pomegranate\" href=\"/en/products/6\">\nTest Product 1\n</a>\n850,00 \n</div> --- snap ---"}
{"name"=>"find", "args"=>[:xpath, ".//a[./@href][(((./@id = 'Test Product 1' or normalize-space(string(.)) = 'Test Product 1') or ./@title = 'Test Product 1') or .//img[./@alt = 'Test Product 1'])]"]}
{"response"=>{"page_id"=>4, "ids"=>[0]}}
{"name"=>"visible", "args"=>[4, 0]}
{"response"=>false}
{"name"=>"find", "args"=>[:xpath, ".//a[./@href][(((./@id = 'Test Product 1' or contains(normalize-space(string(.)), 'Test Product 1')) or contains(./@title, 'Test Product 1')) or .//img[contains(./@alt, 'Test Product 1')])]"]}
{"response"=>{"page_id"=>4, "ids"=>[1]}}
{"name"=>"visible", "args"=>[4, 1]}
{"response"=>false}
Die letzten Aktionen zwei finden wiederholen, bis Capybara seine Timeout erreicht hat, dann schlägt der Test fehl. Ich überprüfte das Xpath Capybara über einige Online-Xpath-Validatoren, aber wie erwartet entspricht es dem HTML-Link. Ich habe auch capybara-screenshot gem verwendet, um den HTML-Body bei Ausfall zu entleeren und der fragliche Link ist auch vorhanden.
Warum funktioniert der Test noch? Gibt es eine Race Condition, die mir nicht bekannt ist? Warum passiert es lokal, aber auf keinem der CI-Dienste?
Hier sind meine Perle Version:
- Capybara (2.4.4)
- Capybara-Screenshot (1.0.3)
- database_cleaner (1.3.0)
- factory_girl (4.5.0)
- factory_girl_rails (4.5.0)
- poltergeist (1.5.1)
- Schienen (4.1.8)
- rspec (3.1.0)
- rspec-Schienen (3.1.0)
- und PhantomJS 1.9.7
In der Tat, wenn ich 'Capybara.ignore_hidden_elements = true' einstellen, scheitert sogar die erste Erwartung. Das Element scheint also nicht sichtbar zu sein. Wenn ich jedoch 'expect (page) .to have_link ('Test Product 1') 'setze, schlägt es immer noch fehl, da es blockiert, bis der Capybara seine Zeitüberschreitung erreicht. Aus irgendeinem Grund werden die Elemente nie sichtbar. – philkry