Capybara에서 부모 노드를 얻는 방법은 무엇입니까?


85

나는 종종 id 또는 기타 식별 속성없이 DOM 요소를 생성하는 많은 jQuery 플러그인을 사용하고 있으며,이를 Capybara에서 가져 오는 유일한 방법 (예 : 클릭)-먼저 이웃 (조상의 다른 자식)을 가져 오는 것입니다. . 그러나 나는 어디에도 찾지 못했습니다. 예를 들어 Capybara는 다음과 같은 것들을 지원합니까?

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

?


또한 Capybara가 {display : hidden}을 사용하여 요소에 대한 클릭을 생성하며, display! = hidden이라는 일부 범위에서 요소를 찾을 수있는 방법이 있습니까?
sandrew

이것은 별도의 질문이지만 사용중인 드라이버에 따라 다릅니다. webrat은 숨겨진 것을 행복하게 찾을 수 있지만 셀레늄은 볼 수없는 항목을 클릭하는 것만 큼 행복하지 않습니다.
jamuraa

답변:


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">을 반환하는데, 이것이 제가 필요로하는 것입니다.
Tyler Rick

특정 상위 노드를 재귀 적으로 찾는 또 다른 방법은 xpath의 상위 또는 자체 선택기를 사용하는 것입니다. 그것을 확인하십시오 stackoverflow.com/questions/1362466/…
vrish88

25
.//..부모를 찾을 필요가 없습니다. 그저 ..충분하고 모호하지도 않습니다.
에이 몬 Nerbonne

타이! 이 댓글이 파티에 조금 늦었 음을 알고 있지만 편집과 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, '..')

이를 지원하기 위해 카피 바라가 업데이트되었습니다.

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


1
여기에서 이전 답변에 응답 / 완료하는 것 같습니다 ( "이" "무엇이 작동하지 않았습니까"?). 완전하고 독립적 인 답변이라면 더 좋을 것입니다. 그래서 나는 그것을 편집하는 것이 좋습니다. ;-)
helenov

확인할 수 있습니다. 최신 Capybara 2.14.4에서 이것은 부모 노드를 얻는 적절한 방법입니다.
fny

10

부모 ( 조상 에서와 같이) 노드 를 찾는 방법을 알아 내려고 우연히 발견 한 경우 ( @Pascal Lindelauf의 답변에 대한 @ 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

2

CSS 클래스가있는 조상을 찾아야했지만 대상 조상에 하나 이상의 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

경고 : 이것을 아껴서 사용하면 테스트에서 많은 시간이 소요될 수 있으므로 조상이 몇 홉 떨어져 있는지 확인하십시오.


속도 향상 : 두 번째 휴식 시간을 break if ancestor[:class].split(" ").include?(css_class).
하쿠 닌

@hakunin 얼마나 속도 향상을보고 있는지 궁금합니다. 중요한?
크로스

지금은 테스트 할 수 없지만 has_css는 1 초가 걸리는 것처럼 보였고 클래스 매칭은 즉각적인 것처럼 보였습니다.
하쿠 닌

Capybara 에는 이제 ancestor(selector)메소드가 내장되어 있습니다. github.com/teamcapybara/capybara/commit/…
타일러 릭

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.