2015-01-18 8 views
5

Mam dziwne problemy z niektórymi testami funkcji przy użyciu Capybara ze sterownikiem poltergeist. Test powinien wykonać proste zakupy w moim sklepie internetowym. Wszystkie one przechodzą dobrze na moim lokalnym MacBooku, a także na pudełku Ubuntu vagrant. Jednak w przypadku usług CI, takich jak Codeship, Wercker lub Semaphore, nie działają one z tym samym błędem.Test funkcji Capybara Poltergeist zawodzi na CI, ale przechodzi lokalnie

Moja specyfikacja:

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 

Błąd pojawia się na CI:

2) Checkout checks out via CreditCard 
Failure/Error: click_link('Test Product 1') 
Capybara::ElementNotFound: 
    Unable to find link "Test Product 1" 

Dla mnie to jest bardzo dziwne, jako pierwszy oczekiwaniu 'spodziewać (page.body). to have_link ('Test Product 1') 'wydaje się przepuszczać, ale potem kończy się niepowodzeniem w następnym kroku, w którym powinien kliknąć link, który zapewnił, że jest obecny na stronie?

Następnie ponownie skonfigurowałem sterownik poltergeist w następujący sposób, aby zebrać więcej informacji na temat debugowania.

fragment 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 

Teraz widzę na konsoli CI że test pomyślnie odwiedza mój products_path i oczekiwaną stronę html (w tym mój link powinien kliknięcie) jest zwracana. usunąłem reszta odpowiedzi HTML aby uczynić go bardziej czytelnym:

{"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} 

Dwa ostatnie znaleźć akcje powtarzać aż Kapibara osiąga limit czasu, a następnie test się nie powiedzie. Sprawdziłem dwukrotnie ścieżkę xpath, którą Capybara używa przez niektóre walidatory online xpath, ale zgodnie z oczekiwaniami pasuje do linku HTML. Użyłem również klejnotu zrzutu ekranu na kapibarze, aby zrzucić treść HTML w przypadku niepowodzenia i obecny jest również link.

Dlaczego test nadal się nie udaje? Czy są jakieś warunki wyścigowe, których nie znam? Dlaczego przechodzi on lokalnie, ale nie w żadnej z usług CI?

Oto moja wersja gem:

  • kapibary (2.4.4)
  • kapibary-screenshot (1.0.3)
  • database_cleaner (1.3.0)
  • factory_girl (4.5.0)
  • factory_girl_rails (4.5.0)
  • poltergeisty (1.5.1)
  • szyny (4.1.8)
  • rspec (3.1.0)
  • rspec-poręcze (3.1.0)
  • i phantomjs 1.9.7

Odpowiedz

0

Chociaż nie mogę odtworzyć tego, pamiętam ten problem wcześniej.Wierzę swoją linię:

expect(page.body).to have_link('Test Product 1') 

przechodzi ponieważ link jest dosłownie na ciele strony html, choć może to być ukryty ze względu na zachowanie CSS lub JS. Jednak linia:

click_link('Test Product 1') 

zdecydowanie sprawdza widoczność przed kliknięciem linku. Należy sprawdzić konfiguracje spec_helper.rb się upewnić:

Capybara.ignore_hidden_elements = true 

jest obecny, tak, że pierwsza linia nie minie. Myślę, że miał również zmienić pierwszą linię Wspomniałem:

# Change page.body to page, to look at the rendered page, not the literal one 
expect(page).to have_link('Test Product 1') 

Gdy to zrobisz, pierwsze bloki liniowe wątek i czeka, aż ogniwo staje się widoczna. Reszta testu przejdzie.

Mam nadzieję, że to rozwiązuje.

+0

Rzeczywiście, jeśli ustawię 'Capybara.ignore_hidden_elements = true' nawet pierwsze oczekiwanie nie powiedzie się. Tak więc element nie wydaje się być widoczny. Jednak jeśli wstawię 'expect (strona) .to have_link ('Test Product 1')' nadal nie działa, ponieważ blokuje się, aż Capybara osiągnie swój limit czasu. Z tego powodu elementy nigdy nie stają się widoczne. – philkry

Powiązane problemy