2016-11-16 2 views
2

Я хочу найти первый класс, который включает в себя определенный текст (имя в этом случае) и кнопку, включенную внутри него.Capybara: как найти класс с использованием нескольких атрибутов внутри класса

У меня есть источник, как этот

<div class="some parent class"> 
     <div class="class" id="1"> 
       <div class="some other name">......</div> 
       <div class="button enabled">......</div> 
      </div> 
      <div class="class" id="2"> 
       <div class="name">......</div> 
       <div class="button disabled">......</div> 
      </div> 
      <div class="class" id="3"> 
       <div class="name">......</div> 
       <div class="button enabled">......</div> 
      </div> 

</div> 

Я попытался

first('.class',text: 'name') 

находит первый класс с именем, но деактивирует кнопку Ofcourse. Тогда я попытался

first('.class',text: 'name', text: 'button text') 

, но похоже, что он применяется оператор ИЛИ между текстовыми параметрами и находит класс с идентификатором 1. Есть ли способ применить оператор И между параметрами текста или любым другим способом, чтобы найти класс, в котором он имеет определенный текст и присутствует кнопка. Также хочу отметить, что положение этих классов может быть случайным, поэтому нельзя сказать, что просто найти последний класс.

+0

вы пытались что-то вроде ', если находка (». класс). в числе? ("имя") && find ('. class'). include? ("button enabled") ... '? – fabersky

ответ

1

все из div теги, которые имеют указанный текст. Затем перебирать те, чтобы найти первый, который также включает в себя кнопку Enabled:

all('.class', text: 'name').find { |div| div.has_css?('div.button.enabled') } 

Вы можете получить более высокую производительность с помощью одного выражения XPath. Однако, это довольно громоздко и вряд ли стоит усилий:

first(
    :xpath, 
    '//div 
    [contains(concat(" ", @class, " "), " class ")] 
    [.//text()[contains(., "name")]] 
    [.//div 
     [contains(concat(" ", @class, " "), " button ")] 
     [contains(concat(" ", @class, " "), " enabled ")]]' 
) 
+0

'all' возвращает объект результата Capybara # (который похож на Array) - он не поддерживает вызов' # find' на нем –

+0

@ThomasWalpole, '# find', похоже, работает на меня. Похоже, что [Capybara :: Result includes Enumerable] (https://github.com/teamcapybara/capybara/blob/master/lib/capybara/result.rb#L22-L23). –

+0

Упс - моя ошибка - я неправильно понял, что вы делали, и подумал, что вы звоните в Capybara find - извините за это - FYI блочная фильтрация в моем ответе заставляет все это выполнить в рамках одного поиска, поэтому вы не сталкиваетесь с проблемами с 'all' не ждет и не возвращает неподдерживаемые результаты. –

1

Если вы просто хотите, чтобы соответствовать по тексту, содержащемуся вы можете использовать регулярное выражение для text опции

find('.class', text: /name.*button text/) 

Если вы хотите убедитесь, что она включает в себя фактический элемент кнопки, и вы используете водосвинку v2.10 + вы можете использовать блок фильтрации с чем-то вроде

find('.class', text: 'name'){ |node| node.has_button?('button text', wait: 0) }