カピバラで親ノードを取得するにはどうすればよいですか?


85

私は多くのjQueryプラグインを使用しています。これらのプラグインは、IDやその他の識別プロパティなしでDOM要素を作成することが多く、Capybaraでそれらを取得する唯一の方法(クリックなど)は、最初にネイバー(その祖先の別の子)を取得することです。 。しかし、私はどこにも見つかりませんでした。たとえば、カピバラはそのようなものをサポートしていますか。

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


また、あなたが言うなら、それは私にとって非常に便利です、カピバラは{display:hidden}で要素のクリックを生成しますか、そしてdisplay!= hidden}であるスコープ内の要素を見つける方法はありますか?
サンドリュー2011

これは別の質問ですが、使用しているドライバーによって異なります。webratは隠されたものを喜んで見つけますが、セレンはあなたが見ることができないアイテムをクリックするほど幸せではありません。
jamuraa 2011

回答:


111

jamuraaの答えは本当に役に立ちましたが、私の場合、完全なxpathを使用すると文字列の悪夢が発生したため、Capybaraでfindを連結する機能を利用して、cssとxpathの選択を組み合わせることができました。この場合、例は次のようになります。

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

Capybara 2.0アップデート:エラーが発生find(:xpath,".//..")する可能性がありAmbiguous matchます。その場合は、first(:xpath,".//..")代わりに使用してください。


そのアイデアをありがとう-私はそれを考えたことはなかったでしょう!find(:css)で見つけたtd要素に対してel.parentを実行していましたが、何らかの理由で理解できず、el.parentが#<Capybara :: Document>を返していました。一方、el.find(:xpath、 ".// ..")は#<Capybara :: Element tag = "tr">を返します。これは、私が必要としていたものです。
タイラーリック

特定の親ノードを再帰的に見つける別の方法は、xpathの祖先または自己セレクターを使用することです。stackoverflow.com/questions/1362466/…をチェックしてください
vrish88

25
.//..親を見つける必要はありません-ただ..十分であり、それも曖昧になることはありません。
Eamon Nerbonne 2013

ty!このコメントはパーティーに少し遅れていることは知っていますが、編集とEamonのコメントを読んだ後、次のように要約しました:el.first(:xpath、 '..')
aschyiel

39

カピバラとCSSでこれを行う方法はありません。私は過去にこの目標を達成するためにXPathを使用しましたが、これには親要素を取得する方法があり、Capybaraによってサポートされています。

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

2
同様のxpath検索を実行すると、式が無効であるというNokogiriエラーが発生します。:私は表現修正するために式の中で、オープン正方形のbraketのアスタリスクインフロントを追加find(:xpath, '//*[@id="some_button"]/..')
アンドリューFerk

35

私はそれが機能する次のものを見つけました:

find(:xpath, '..')

Capybaraは、これをサポートするように更新されました。

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


1
ここで前の回答に応答/完了しているように見えます(「これ」は「機能していなかった」のですか?)。それが完全で独立した答えであるならば、それはより良いでしょう。ですから、編集することをお勧めします。;-)
helenov 2016年

確認できます。最新のCapybara2.14.4では、これが親ノードを取得する適切な方法です。
fny 2017

10

祖先のように)親ノードを見つける方法を見つけようとしてこれに遭遇した場合(@PascalLindelaufの回答に対する@ vrish88のコメントで示唆されているように):

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

5

この答えは、元の質問がほのめかしていると私が信じている兄弟要素を操作する方法に関係しています

あなたの質問の仮説は、微調整で機能します。動的に生成されたフィールドが次のようになり、IDがない場合:

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

その場合、クエリは次のようになります。

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

動的に生成された入力にid要素が添付されている場合(角度の場合と同様にこれらに注意してください。要素の追加と削除に基づいて変更されることはありません)、次のようになります。

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

お役に立てば幸いです。


4

この親要素内のテキストを使用して最初に親要素を見つけることにより、別のアプローチを使用しています。

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

たぶん、これは同様の状況で役立ちます。


1
これは素晴らしいオプションです。特定のテキストを含むページの一部にUIアクションをスコープすることは、私にとって一般的なユースケースです。
clemensp 2016

2

cssクラスを持つ祖先を見つける必要がありましたが、ターゲットの祖先に1つ以上のcssクラスが存在するかどうかは不明であったため、決定論的なxpathクエリを作成する方法がわかりませんでした。私は代わりにこれを作り上げました:

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

警告:これは慎重に使用してください。テストに多くの時間がかかる可能性があるため、祖先がほんの数ホップ離れていることを確認してください。


スピードアップ:2回目の休憩をbreak if ancestor[:class].split(" ").include?(css_class)。に置き換えます。
hakunin 2015年

@hakuninどれだけスピードアップしているのか気になりますか?重要ですか?
kross 2015年

現在テストできませんが、クラスのマッチングがすぐに行われている間、has_cssには1秒かかるようです。
hakunin 2015年

カピバラは今 ancestor(selector)に建てられた方法を参照してください。github.com/teamcapybara/capybara/commit/...
タイラーリック

-5

ここにあります

http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Base:parent

親メソッドが存在します;)


5
これは、トップレベルのドキュメントのみを返します。それがドライバーの問題なのか、それとも何なのかわからない。
Nerdmaster 2013年

ドキュメントを読むと、これは要素の親ではなく、「フレーム」の親を意味しているように見えますか?
ニック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.