कुछ JS चलने के बाद दृश्यता के लिए Capybara की जाँच कैसे करें?


82

पृष्ठ लोड करने के बाद मेरे पास एक कोड है जो चलता है और छुपाता है और एक xhr द्वारा लौटाए गए डेटा के आधार पर विभिन्न वस्तुओं को दिखाता है।

मेरा एकीकरण परीक्षण कुछ इस तरह दिखता है:

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

जब मैं मैन्युअल रूप से इस परीक्षण के संदर्भ में पृष्ठ पर जाता हूं , तो #blah दिखाई नहीं देता जैसा कि मुझे उम्मीद है। मुझे संदेह है कि Capybara पृष्ठ की प्रारंभिक स्थिति (इस मामले में अदृश्य) को देख रहा है, DOM की स्थिति का मूल्यांकन कर रहा है और JS रन से पहले परीक्षण को विफल कर रहा है।

हाँ, मैंने :js => trueयुक्त वर्णन ब्लॉक पर सेट किया :)

किसी भी विचार की बहुत प्रशंसा की जाएगी! मैं उम्मीद कर रहा हूं कि मुझे यहां जानबूझकर देरी नहीं करनी है, यह भड़कीला लगता है और चीजों को धीमा कर देगा।


1
ड्राइवर क्या है? XHR समाप्त होने के बाद अपेक्षित HTML क्या है?
सिरो सेंटिल्ली 郝海东 i iro i 法轮功 '15

जवाबों:


132

मुझे लगता है कि findयहाँ बयान निहित प्रतीक्षा के साथ एक है, इसलिए Capybara तब तक इंतजार करेगा जब तक कि तत्व पृष्ठ पर नहीं है, लेकिन इसके दृश्यमान होने की प्रतीक्षा नहीं करेगा।

यहाँ, आप चाहते हैं कि Capybara दिखाई देने वाले तत्व के आने की प्रतीक्षा करे, जिसे visibleविकल्प निर्दिष्ट करके प्राप्त किया जाना चाहिए :

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

मैंने इसे आज़माया नहीं है, लेकिन ignore_hidden_elementsकॉन्फ़िगरेशन विकल्प यहाँ भी उपयोगी हो सकता है, यदि आप findहमेशा दृश्य तत्वों की प्रतीक्षा करना चाहते हैं।


6
अगर किसी को शुरू में @ केविन का नोट याद आता है (मेरे जैसा), तो आपके पास js:trueइस काम के लिए ब्लॉक होने पर होना चाहिए ।
क्रिस बेक

3
यह कमाल का है। इसने मुझे पाने में मदद की: expect(page).to have_selector('#flash-message', visible: false, text: "Signed in Successfully")- इस उत्तर को पोस्ट करने के लिए धन्यवाद
चक बर्जरॉन

दृश्य विकल्प का मेरे लिए कोई प्रभाव नहीं पड़ा जब एक jquery स्लाइड डाउन तत्व की दृश्यता का परीक्षण किया गया। मुझे उम्मीद (bl # ब्ला ’) का उपयोग करना था।
सचिनविसो

मुझे कुछ ऐसा चाहिए जो अदृश्य है? फिर कुछ और करते हैं
user1735921

37

यह ऐसा करने का एक और तरीका है जो मेरे लिए बिल्कुल ठीक काम करता है:

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

विशेष रूप से अधिक जटिल पाता है, जैसे कि

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

जो यह बताता है कि एक तत्व छिपा हुआ है।


1
should_not be_visibleCapybara रन के रूप में मेरे लिए अच्छा नहीं दिखता है wait_until { base.visible? }जब तत्व # दिखाई? आह्वान किया जा रहा है।
न्गुयेन

1
@ phng-nguyn, #wait_until Capybara के हाल के संस्करणों से हटा दिया गया है।
18

3
यह वास्तव में "page.should has_selector ..." की तुलना में एक बेहतर संस्करण है, क्योंकि यदि कोई विफल पाठ है, तो यह कहेंगे कि तत्व वास्तव में अदृश्य रूप से अदृश्य है, जबकि उल्लेख किया गया संस्करण अभी स्पष्ट नहीं है 'कोई मिलान त्रुटि नहीं थी , यह एक छोटी सी निराशा है।
installero

यह स्वीकृत समाधान के समान नहीं है। इस कोड के लिए, Capybara केवल तब तक प्रतीक्षा करेगा जब तक कि तत्व DOM में नहीं है, और फिर तुरंत दृश्यता की जांच करें। यदि आप दृश्यता को बदलने की उम्मीद कर रहे हैं, तो यह ऐनक में एक दौड़ की स्थिति जोड़ सकता है।
23

1
क्या किसी को पता है कि .should_not be_visibleकवर display: nonejQuery द्वारा सेट किया गया है? यह मेरे लिए काम नहीं लगता है।
अंतीक्षि

20

यदि आप जांचना चाहते हैं कि कोई तत्व पृष्ठ पर है, लेकिन दिखाई नहीं दे रहा है, 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)

1
should_notअजाक्स के कारण आप
काप्यारा का

@ मार्क-आंद्रेलाफोर्ट, कैपजेबरा के साथ अजाक्स का परीक्षण करने के लिए Capybara.javascript_driver का उपयोग करें।
जुबिन

1
javascript_drive के साथ, have_cssछोड़ने से पहले अपनी पूरी टाइमआउट अवधि की प्रतीक्षा करेंगे, क्योंकि यह तत्व को खोजने की उम्मीद करता है। जैसे आपको should have_no_contentइसके बजाय उपयोग करना है should_not have_content
मार्क-एंड्रे लाफ्यून

1
expect(page).not_to have_selector("#some_element", visible: true)javascript_driverपूरे टाइमआउट की प्रतीक्षा किए बिना, मेरे उपयोग के लिए ठीक काम किया ।
जेसन स्विट

1
दरअसल, मेरी टिप्पणी के बाद से, यह बदल दिया गया है और आप should_notअभी (का उपयोग करें और कर सकते हैं ) , क्षमा करें!
मार्क-आंद्रे लाफ्यून

9

का उपयोग करते हुए:

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

मेरे पास एक रेल एप्लिकेशन है जिसमें एक लिंक है जिसे क्लिक करने पर एक AJAX पोस्ट अनुरोध सबमिट करना चाहिए और एक जेएस प्रतिक्रिया वापस करनी चाहिए।

लिंक कोड:

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

जेएस प्रतिक्रिया (.js.haml फ़ाइल) लिंक मौजूद है पृष्ठ पर निम्नलिखित छिपा div टॉगल करना चाहिए:

 #notification_status(style='display:none')

js.haml फ़ाइल सामग्री:

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

मैं नोटिफ़िकेशन भेजने के अपने परिदृश्य का परीक्षण कर रहा था और उपयोगकर्ता को Cucumber (Cucumber -rails gem in Capybara सपोर्ट से निर्मित ) का उपयोग करके अधिसूचना स्थिति संदेश प्रदर्शित कर रहा था

मैं यह जांचने की कोशिश कर रहा था कि तत्व में id: नोटिफिकेशन_स्टैटस मेरी चरण परिभाषा में सफल प्रतिक्रिया पर दिखाई दे रहा था। इसके लिए मैं निम्नलिखित प्रश्न का उत्तर दे रहा हूं:

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#v अदृश्य%3F-instance_method ) निम्नलिखित जानकारी:

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

इस प्रकार मैं इस नतीजे पर पहुंचा कि जब किसी तत्व की दृश्यता का परीक्षण कैपिबारा के दृश्यमान परिणामों पर निर्भर नहीं करता है? एक सीएसएस चयनकर्ता का उपयोग करते समय और किसी तत्व के लिंक कैपिबारा में सुझाए गए समाधान का उपयोग करते हुए विधि

मैं निम्नलिखित के साथ आया:

 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')

8

दिखाई देने वाला साधन स्पष्ट नहीं है

विफलता दिखाई देने वाली चीज़ों की गलतफहमी से आ सकती है या नहीं, क्योंकि यह गैर-स्पष्ट है, चालक पोर्टेबल नहीं है, और अंडर-डॉक्यूमेंटेड है। कुछ परीक्षण:

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>

रैक परीक्षण को केवल एक चीज अदृश्य मानती है display: none(आंतरिक सीएसएस नहीं क्योंकि यह चयनकर्ता नहीं करते हैं):

!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 पर पूर्ण runnable परीक्षण ।


1
शानदार जवाब - इस प्रयास में आपका धन्यवाद। कई ड्राइवरों का उपयोग करते हुए एक सूट में तत्वों की परीक्षण दृश्यता गैर-तुच्छ है।
एंडी ट्रिग्ज

1
"यह झूठा हुआ करता था (दृश्य और अदृश्य दोनों तत्वों को देखता है), वर्तमान में सच है, और Capybara.ignore_hidden_elements विकल्प द्वारा नियंत्रित किया जाता है।" अधिक जानकारी के लिए इस ब्लॉग पोस्ट को देखें: elabs.se/blog/60-introducing-capybara-2-1
rizidoro

5

आप इस पोस्ट को देखना चाहते हैं , जो प्रतीक्षा के लिए एक नमूना विधि प्रदान करती है जब तक कि सभी ajax अनुरोध पूर्ण नहीं हो जाते:

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

5
यह समाधान भविष्य के अनुकूल नहीं है, जैसा wait_untilकि कैपिबारा 2 से हटा दिया गया था ।
परमहर १r

1
उपयोगTimeout.timeout
इयान वघन

बेहतर उपयोगSelenium::WebDriver::Wait
नकीलोन

यदि आप केवल सेलेनियम का उपयोग करते हैं
निकोले कोन्ड्रेंटेंको

2

स्वीकृत उत्तर थोड़ा पुराना है, क्योंकि 'चाहिए' पदावनत सिंटैक्स है। इन दिनों आप की तर्ज पर कुछ करना बेहतर होगाexpect(page).not_to have_css('#blah', visible: :hidden)


1

यहां अन्य उत्तर तत्व के लिए "प्रतीक्षा" करने का सबसे अच्छा तरीका है। हालाँकि मैंने पाया है कि मैं जिस साइट पर काम कर रहा हूँ उसके लिए यह काम नहीं किया। मूल रूप से जिस तत्व पर क्लिक करने की आवश्यकता थी, वह पूरी तरह से लोड होने से पहले ही दिखाई देता था। यह एक दूसरे के अंश में है, लेकिन मैंने पाया कि मेरा परीक्षण इस अवसर पर इतना तेज चला कि उसने बटन पर क्लिक किया और कुछ नहीं हुआ। मैंने इस मेक-शिफ्ट बूलियन एक्सप्रेशन को करते हुए इसके आसपास काम करने में कामयाबी हासिल की:

if page.has_selector?('<css-that-appears-after-click>')
  puts ('<Some-message-you-want-printed-in-the-output>')
else
  find('<css-for-the-button-to-click-again>', :match == :first).trigger('click')
end

मूल रूप से यह कुछ है कि दिखाई देना चाहिए के लिए देखने के लिए capybara डिफ़ॉल्ट प्रतीक्षा समय का उपयोग करता है, अगर यह वहाँ नहीं है तो यह आपके क्लिक को पुनः प्रयास करेगा।

फिर से मैं कहूंगा कि should have_selectorविधि को पहले आज़माया जाना चाहिए, लेकिन अगर यह सिर्फ काम नहीं करेगा तो यह कोशिश करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.