Capybara'da ebeveyn düğümü nasıl alınır?


86

Genellikle kimlik veya diğer tanımlama özellikleri olmadan DOM öğeleri oluşturan birçok jQuery eklentisiyle çalışıyorum ve bunları Capybara'ya almanın tek yolu (örneğin tıklamak için) - önce komşularını (atalarının başka bir çocuğu) almaktır . Ama hiçbir yerde bulamadım, Capybara böyle şeyleri destekliyor mu örneğin:

find('#some_button').parent.fill_in "Name:", :with => name

?


Ayrıca, Capybara'nın {display: hidden} öğelerine tıklama oluşturduğunu söylerseniz, benim için çok yararlı olacak ve bazı kapsamdaki öğeleri bulmanın bir yolu var mı, burada display! = Hidden?
sandrew

Bu ayrı bir sorudur, ancak kullandığınız sürücüye bağlıdır. webrat gizli şeyleri mutlu bir şekilde bulacaktır, ancak selenyum göremediğiniz öğelere tıklamaktan o kadar mutlu olmaz.
jamuraa

Yanıtlar:


111

Jamuraa'nın cevabını gerçekten yararlı buldum, ancak tam xpath'e gitmek benim durumumda bana bir dizge kabusu verdi, bu yüzden Capybara'daki bul'ları birleştirerek css ve xpath seçimini karıştırmama izin vererek mutlu bir şekilde kullandım. Örneğiniz daha sonra şöyle görünecektir:

find('#some_button').find(:xpath,".//..").fill_in "Name:", :with => name

Capybara 2.0 güncellemesi : find(:xpath,".//..")büyük olasılıkla bir Ambiguous matchhatayla sonuçlanacaktır . Bu durumda first(:xpath,".//..")bunun yerine kullanın.


Bu fikir için teşekkürler - bunu asla düşünmezdim! Find (: css) ile bulduğum bir td elemanı için el.parent yapıyordum, ancak nedense anlamıyorum, el.parent # <Capybara :: Document> döndürüyordu. el.find (: xpath, ".// ..") ise ihtiyacım olan # <Capybara :: Element tag = "tr"> döndürüyor.
Tyler Rick

Belirli bir ebeveyn düğümü yinelemeli olarak bulmanın başka bir yolu, xpath'in ata veya kendi kendine seçicisidir. Stackoverflow.com/questions/1362466/… 'a
vrish88

25
.//..Ebeveyni ..bulmana gerek yok - sadece yeterli ve bu da asla belirsiz değil.
Eamon Nerbonne

ty! Bu yorumun partiye biraz geç kaldığını biliyorum, ancak düzenlemeyi ve Eamon'un yorumunu okuduktan sonra bunu şu kısma indirgedim: el.first (: xpath, '..')
aschyiel

39

Bunu capybara ve CSS ile yapmanın bir yolu yok. Geçmişte bu hedefi gerçekleştirmek için XPath kullandım, bu ana öğeyi elde etmenin bir yolu var ve Capybara tarafından destekleniyor:

find(:xpath, '//*[@id="some_button"]/..').fill_in "Name:", :with => name

2
Benzer bir xpath bulmayı yaptığımda, ifadenin geçersiz olduğunu söyleyen bir Nokogiri hatası alıyorum. İfadeyi düzeltmek için açık köşeli find(:xpath, '//*[@id="some_button"]/..')
parantezin önüne

35

Aşağıdakilerin işe yaradığını buldum:

find(:xpath, '..')

Capybara bunu desteklemek için güncellendi.

https://github.com/jnicklas/capybara/pull/505


1
Bana öyle geliyor ki burada bir önceki cevabı yanıtlıyorsunuz / tamamlıyorsunuz ("Bu" ne "çalışmıyordu"?). Tam ve bağımsız bir cevap olsaydı daha iyi olurdu. Bu yüzden düzenlemenizi tavsiye ederim. ;-)
helenov

Onaylayabilir. En son Capybara 2.14.4 ile bu, ana düğümü elde etmenin uygun yoludur.
fny

10

Herhangi bir ebeveyn düğümünü ( atada olduğu gibi ) nasıl bulacağınızı anlamaya çalışırken rastladıysanız (@ vrish88'in @Pascal Lindelauf'un cevabı hakkındaki yorumunda ima edildiği gibi):

find('#some_button').find(:xpath, 'ancestor::div[@id="some_div_id"]')

5

Bu cevap, bir kardeş unsurunun nasıl manipüle edileceğiyle ilgilidir ki bu, orijinal sorunun ima ettiğine inandığım şeydir.

Soru hipoteziniz küçük bir ince ayar ile çalışır. Dinamik olarak oluşturulan alan böyle görünüyorsa ve bir kimliği yoksa:

<div>
  <input></input>
  <button>Test</button>
</div>

Sorgunuz daha sonra şöyle olacaktır:

find('button', text: 'Test').find(:xpath, "..").find('input').set('whatever')

Dinamik olarak üretilen giriş bir id öğesi ile birlikte gelirse (bunlara dikkat edin, açısal olsa da, öğeler ekleme ve silmeye göre değişmeyeceklerdir), bu şöyle bir şey olacaktır:

find('button', text: 'Test').find(:xpath, "..").fill_in('#input_1', with: 'whatever')

Umarım yardımcı olur.


4

İlk önce bu üst öğe içindeki metni kullanarak ana öğeyi bularak farklı bir yaklaşım kullanıyorum:

find("<parent element>", text: "text within your #some_button").fill_in "Name:", with: name

Belki bu benzer bir durumda yararlıdır.


1
Bu harika bir seçenektir. Kullanıcı arabirimi eylemlerinin belirli bir metni içeren sayfanın bir bölümüne kapsamını belirlemek benim için yaygın bir kullanım durumudur.
clemensp

2

Bir css sınıfına sahip bir ata bulmam gerekiyordu, ancak hedef atanın mevcut bir veya daha fazla css sınıfına sahip olup olmadığı belirsizdi, bu yüzden deterministik bir xpath sorgusu yapmanın bir yolunu görmedim. Bunun yerine bunu geliştirdim:

def find_ancestor_with_class(field, cssClass)
  ancestor = field
  loop do
    ancestor = ancestor.find(:xpath, '..')
    break if ancestor.nil?

    break if ancestor.has_css? cssClass
  end

  ancestor
end

Uyarı: Bunu idareli kullanın, testlerde size çok zamana mal olabilir, bu yüzden atanın sadece birkaç atlama uzakta olduğundan emin olun.


Hızlandırma: ikinci molanızı ile değiştirin break if ancestor[:class].split(" ").include?(css_class).
hakunin

@hakunin Ne kadar hızlanma görüyorsun merak ediyorum? Önemli?
kross

Şimdi test edilemiyor, ancak has_css bir saniye sürüyor gibi görünürken, sınıf eşleştirme hemen göründü.
hakunin

Capybara'da artık ancestor(selector)yerleşik bir yöntem var. Bkz. Github.com/teamcapybara/capybara/commit/…
Tyler Rick

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.