2017-02-26 2 views
1

Ich erhalte den folgenden Fehler in rspec + Capybara + Poltergeist:Capybara nicht Ajax-Request warten

given!(:user_owner) { create(:user) } 
given!(:second_user) { create(:user) } 
given!(:question) { create(:question, user: user_owner) } 

describe 'as not question owner' do 
    before do 
    login_as(second_user, scope: :user, run_callbacks: false) 
    visit question_path(question) 
    end 

    scenario 'can upvote just one time', js: true do 
    first('a#question-upvote').click 
    expect(first('div#question-score').text).to eq '1' 
    first('a#question-upvote').click 
    expect(first('div#question-score').text).to eq '1' 
    end 

Ausfall/Fehler: erwarten (page.first ('div # Frage-score') Text.) .to eq '-1'

expected: "-1" 
     got: "0" 

Wenn ich einfügen Schlaf 1:

scenario 'can upvote just one time', js: true do 
    first('a#question-upvote').click 
    sleep 1 
    expect(first('div#question-score').text).to eq '1' 
    first('a#question-upvote').click 
    sleep 1 
    expect(first('div#question-score').text).to eq '1' 
end 

Test.

Ich habe verstanden, dass Seite nicht auf asynchrone Anfrage gewartet. Wie kann ich den Test umschreiben, damit er gut funktioniert, ohne zu schlafen?

P.S. Entschuldigung für Englisch.

Antwort

3

Mit dem eq Matcher können Sie jedes Warteverhalten beenden. Der Grund dafür ist, dass Sie nach dem Aufruf von .text für ein gefundenes Element eine Zeichenfolge haben und es keine Möglichkeit gibt, diese Zeichenfolge erneut zu laden/erneut abzufragen, wenn sie mit dem -Matcher verwendet wird. Wenn Sie warten/wiederholen wollen, müssen Sie die von Capybara mit Capybara-Elementen zur Verfügung gestellten Matcher verwenden.

Also statt expect(first('div#question-score').text).to eq '1' sollten Sie

expect(first('div#question-score')).to have_text('1', exact: true) # you could also use a Regexp instead of specifying exact: true 

Eine andere Sache tun ist zu beachten, dass all/first disable Nachladen von Elementen, so dass, wenn die gesamte Seite verändert (oder das Element, das Sie für Text warten auf wird komplett ersetzt) ​​und die Startseite hatte ein Element, das mit dem Selektor übereinstimmt, aber Sie möchten, dass das Element von der zweiten Seite (oder dem ersetzten Element) geprüft wird, sollten Sie nicht verwenden first/all - In diesem Fall würden Sie möchte find mit einer Abfrage mit dem css verwenden: first-child /: first-of-type usw. typ e Dinge (oder ein äquivalenter XPath), um Ihr Element eindeutig zu identifizieren, anstatt Multiples zurückzugeben und eines davon auszuwählen. Wenn nur der Wert des Elements asynchron auf der Seite ersetzt wird, müssen Sie sich keine Gedanken darüber machen.

+0

Danke Thomas. Du hast mir wieder geholfen. –

Verwandte Themen