[ruby] 일부 JS가 실행 된 후 Capybara가 가시성을 확인하도록하는 방법은 무엇입니까?

페이지를로드 한 후 xhr에서 반환 한 데이터를 기반으로 다양한 항목을 실행하고 숨기고 표시하는 코드가 있습니다.

내 통합 테스트는 다음과 같습니다.

it "should not show the blah" do
    page.find('#blah').visible?.should be_true
end

이 테스트가 실행되는 컨텍스트의 페이지로 수동으로 이동하면 #blah가 예상대로 표시 되지 않습니다 . Capybara가 페이지의 초기 상태 (이 경우에는 보이지 않음)를보고 DOM의 상태를 평가하고 JS가 실행되기 전에 테스트에 실패했다고 생각합니다.

예, :js => true포함 설명 블록에 설정했습니다 . 🙂

어떤 아이디어라도 대단히 감사하겠습니다! 나는 여기에 고의적 인 지연을 넣을 필요가 없기를 바라고 있습니다.



답변

find여기에 있는 진술은 묵시적 ​​대기가 있는 진술 이라고 생각 하므로 Capybara는 요소가 페이지에있을 때까지 기다리지 만 표시 될 때까지 기다리지 않습니다.

여기에서 Capybara가 보이는 요소가 나타날 때까지 기다리기를 원할 것입니다. 이는 visible옵션 을 지정하여 달성 할 수 있어야합니다 .

expect(page).to have_selector('#blah', visible: true)

나는 그것을 시도하지 않았지만 항상 보이는 요소를 기다리고 ignore_hidden_elements싶다면 구성 옵션이 여기에서도 유용 할 수 있습니다 find.


답변

이것은 나를 위해 완벽하게 작동하는 또 다른 방법입니다.

find(:css, "#some_element").should be_visible

특히 다음과 같은 더 복잡한 발견의 경우

find(:css, "#comment_stream_list li[data-id='#{@id3}']").should_not be_visible

요소가 숨겨져 있다고 주장합니다.


답변

요소가 페이지에 있지만 표시 visible: false되지 않는지 확인하려면 예상대로 작동하지 않습니다. 내가 약간 당황했다.

방법은 다음과 같습니다.

# assert element is present, regardless of visibility
page.should have_css('#some_element', :visible => false)
# assert visible element is not present
page.should have_no_css('#some_element', :visible => true)


답변

사용 :

 Ruby:     ruby 1.9.3dev (2011-09-23 revision 33323) [i686-linux]
 Rails:    3.2.9
 Capybara: 2.0.3

클릭하면 AJAX 게시 요청을 제출하고 JS 응답을 반환해야하는 링크가있는 Rails 애플리케이션이 있습니다.

링크 코드 :

 link_to("Send Notification", notification_path(user_id: user_id), remote: true, method: :post)

JS 응답 (.js.haml 파일)은 링크가있는 페이지에서 다음과 같은 숨겨진 div를 토글해야합니다.

 #notification_status(style='display:none')

js.haml 파일 내용 :

:plain
  var notificationStatusContainer = $('#notification_status');
  notificationStatusContainer.val("#{@notification_status_msg}");
  notificationStatusContainer.show();

내가 통지를 보내와 오이를 사용하여 사용자에게 알림 상태 메시지를 표시 내 시나리오를 테스트했다 ( 카피 바라 지원에 내장 된 보석 오이 레일 )

id : notification_status 가 있는 요소가 단계 정의에서 성공적인 응답에 표시 되는지 테스트하려고했습니다. 이를 위해 다음 문을 시도했습니다.

page.find('#notification_status').should be_visible
page.should have_selector('#notification_status', visible: true)
page.should have_css('#notification_status', visible: true)
page.find('#notification_status', visible: true)
page.find(:css, 'div#notification_status', visible: true)

위의 어느 것도 나를 위해 일하지 않았고 내 단계에 실패했습니다. 위에 나열된 5 개의 스 니펫 중 마지막 4 개가 다음 오류로 실패했습니다.

'expected to find css "#notification_status" but there were no matches. Also found "", which matched the selector but not all filters. (Capybara::ExpectationNotMet)'

다음 문이 올바르게 전달 되었기 때문에 이상했습니다.

page.has_selector?('#notification_status')

그리고 사실 저는 페이지 소스를

  print page.html

나타난

<div style='' id='notification_status'></div>

예상했습니다.

마지막으로이 링크 카피 바라는 요소의 속성을 원시 방식으로 검사하는 방법을 보여주는 요소의 속성을 주장합니다 .

또한 Capybara 문서에서 볼 수 있습니까? 메소드 ( http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Element#visible%3F-instance_method ) 다음 정보 :

 Not all drivers support CSS, so the result may be inaccurate.

따라서 요소의 가시성을 테스트 할 때 Capybara의 가시성 결과에 의존하지 않는다는 결론에 도달했습니다. CSS 선택기를 사용하고 링크 카피 바라 에서 제안 된 솔루션을 사용할 때 요소의 속성을 주장하는 방법

나는 다음을 생각 해냈다.

 module CustomMatchers
   def should_be_visible(css_selector)
    find(css_selector)['style'].should_not include('display:none', 'display: none')
   end
 end

 World(CustomMatchers)

용법:

should_be_visible('#notification_status')


답변

보이는 것은 분명하지 않다

이 오류는 눈에 띄는 것으로 간주되는 것이 명확하지 않고, 드라이버가 휴대 가능하지 않으며, 문서화되지 않은 것으로 간주되는 오해로 인해 발생할 수 있습니다. 일부 테스트 :

HTML :

<div id="visible-empty"                                                                   ></div>
<div id="visible-empty-background"      style="width:10px; height:10px; background:black;"></div>
<div id="visible-empty-background-same" style="width:10px; height:10px; background:white;"></div>
<div id="visible-visibility-hidden"     style="visibility:hidden;"                        >a</div>
<div id="visible-display-none"          style="display:none;"                             >a</div>

Rack 테스트가 보이지 않는 것으로 간주하는 유일한 것은 인라인입니다 display: none(선택자를 수행하지 않기 때문에 내부 CSS가 아님).

!all('#visible-empty',                 visible: true).empty? or raise
!all('#visible-empty-background',      visible: true).empty? or raise
!all('#visible-empty-background-same', visible: true).empty? or raise
!all('#visible-visibiility-hidden',    visible: true).empty? or raise
 all('#visible-display-none',          visible: true).empty? or raise

Poltergeist는 비슷한 동작을하지만 내부 CSS 및 Js style.display조작을 처리 할 수 ​​있습니다 .

Capybara.current_driver = :poltergeist
!all('#visible-empty',                 visible: true).empty? or raise
!all('#visible-empty-background',      visible: true).empty? or raise
!all('#visible-empty-background-same', visible: true).empty? or raise
!all('#visible-visibiility-hidden',    visible: true).empty? or raise
 all('#visible-display-none',          visible: true).empty? or raise

셀레늄은 매우 다르게 동작 : 빈 요소가 보이지 판단하는 경우 visibility-hidden뿐만 아니라 display: none:

Capybara.current_driver = :selenium
 all('#visible-empty',                 visible: true).empty? or raise
!all('#visible-empty-background',      visible: true).empty? or raise
!all('#visible-empty-background-same', visible: true).empty? or raise
 all('#visible-visibiility-hidden',    visible: true).empty? or raise
 all('#visible-display-none',          visible: true).empty? or raise

또 다른 일반적인 캐치는 다음의 기본값입니다 visible.

  • 예전에는 false( 보이는 요소와 보이지 않는 요소 모두 참조)
  • 현재는 true
  • Capybara.ignore_hidden_elements옵션에 의해 제어됩니다 .

참조 .

내 GitHub에서 전체 실행 가능한 테스트 .


답변

모든 ajax 요청이 완료 될 때까지 대기하는 샘플 메소드를 제공하는 이 게시물 을보고 싶을 수 있습니다 .

def wait_for_ajax(timeout = Capybara.default_wait_time)
  page.wait_until(timeout) do
    page.evaluate_script 'jQuery.active == 0'
  end
end


답변

허용되는 대답은 ‘should’가 더 이상 사용되지 않는 구문이므로 약간 구식입니다. 요즘 당신은 라인을 따라 뭔가를하는 것이 더 나을 것입니다expect(page).not_to have_css('#blah', visible: :hidden)