将哈希传递给水豚选择器

Passing an hash to a Capybara Selector

我有一个自定义的水豚选择器

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')也可以。

Capybaras find 采用选择器类型、可选定位器,然后是选项。您 运行 遇到的问题是,如果您将哈希作为第二个参数传递,然后没有第三个参数被解释为没有传递定位器和选项哈希。因此,您可以通过传递一个空的选项散列来使用您的选择器,因此 attribute/value 散列被解释为定位器

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

这告诉选择器期望传递 :attribute 和 :value 选项,这将允许 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')

按倍数求