Передача хеша в селектор капибары - PullRequest
0 голосов
/ 11 октября 2018

У меня есть собственный селектор Capybara

module Selectors
  Capybara.add_selector(:dataAttribute) do
    xpath { |attribute| ".//*[@data-target='#{attribute}']" }
  end
end


find(:dataAttribute, 'myButton')

И он работает просто отлично.

Теперь мне нужно обобщить его и иметь возможность передавать также атрибут данных, чтобы я мог найти дляэкземпляр <div data-behavior"hideYourself">...</div>.

В идеале, я бы хотел, чтобы API был ниже

find(:dataAttribute, attribute: 'behavior', value: 'hideYourself')
#OR
find(:dataAttribute, { attribute: 'behavior', value: 'hideYourself' })

Итак, я обновил свой селектор следующим образом

module Selectors
  Capybara.add_selector(:dataAttribute) do
    xpath { |params| ".//*[@data-#{params[:attribute]}='#{params[:value]}']" }
  end
end

НоЯ получаю NoMethodError: undefined method '[]' for nil:NilClass.Я сделал небольшую отладку и заметил, что в текущем селекторе (1 строковый параметр) значение в блоке установлено правильно (например, myButton).Однако, когда я передаю хеш, значение равно nil.

Любая идея, как передать несколько параметров селектору?

find(:dataAttribute, 'behavior', 'hideYourself') тоже подойдет.

1 Ответ

0 голосов
/ 11 октября 2018

Поиск Капибары принимает тип селектора, необязательный локатор, а затем параметры.Проблема, с которой вы сталкиваетесь, заключается в том, что вы передаете Hash в качестве второго параметра, а затем третий параметр, который не интерпретируется как пропущенный локатор и хэш опций.Из-за этого вы можете использовать ваш селектор, как написано, передавая пустой хэш опций, чтобы хэш атрибута / значения интерпретировался как локатор

find(:dataAttribute, attribute: 'behavior', value: 'hideYourself', {})

Все это затем может быть заключено в вспомогательный метод find_data_attributeтак что вам не придется вручную передавать пустой хэш опций.

def find_data_attribute(locator, **options)
  find(:dataAttribute, locator, options)
end

Другой вариант - написать ваш селектор по-другому и использовать вместо него опции - что-то вроде

Capybara.add_selector(:dataAttribute) do
  xpath(:attribute, :value) do |_locator, attribute:, value:, **| 
    ".//*[@data-#{attribute}='#{value}']"
  end
end

, которое сообщаетСелектор для ожидаемых: атрибута и: значения параметров, которые должны быть переданы, что позволило бы работать find(:dataAttribute, attribute: 'behavior', value: 'hideYourself').

Последний вариант - использовать сопоставитель опций с подстановочными знаками по строкам

Capybara.add_selector(:dataAttribute) do
  xpath do |_locator, **|
    #you could use the locator to limit by element type if wanted - see Capybaras built-in :element selector - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L467
    XPath.descendant
  end

  expression_filter(:attributes, matcher: /.+/) do |xpath, name, val|
    xpath[XPath.attr("data-#{name}")==val]
  end
end

Что затем должно позволить вам

find(:dataAttribute, behavior: 'hideYourself')

найти по одному атрибуту данных или

find(:dataAttribute, behavior: 'hideYourself', other_data_attr_name: 'some value')

найти по коэффициентам

...