因此,当使用Capybara和Chromedriver自动化网页时,我有一个包含多个下拉菜单(具有相同选项)的页面。
它们都是react-select(我有一个帮助文件)。可悲的是,他们都有相同的标签文本(但不是标签ID ......但我不认为page.select
适用于标签ID)。
我想过做一个页面。所有关于反应选择?然后只是通过阵列?这可能吗?
反应选择看起来非常标准,我意识到跨度有一个id,但选择那个不能用于反应 - 从我能够分辨的选择。:
<div class="Select-control">
<span class="Select-multi-value-wrapper" id="react-select-6--value">
<div class="Select-placeholder">Select...</div>
<div class="Select-input" style="display: inline-block;">
<input role="combobox" aria-expanded="false" aria-owns="" aria-haspopup="false" aria-activedescendant="react-select-6--value" value="" style="width: 5px; box-sizing: content-box;">
<div style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre;"></div>
</div>
</span>
<span class="Select-arrow-zone"><span class="Select-arrow"></span></span>
</div>
我可以通过page.all把它拉进来吗?我做的反应助手就是这样做的:
module CapybaraReactHelper
def capybara_react_select(selector, label)
within selector do
find('.Select-control').click
expect(page).to have_css('.Select-menu-outer') # options should now be available
expect(page).to have_css('.Select-option', text: label)
find('.Select-option', text: label).click
end
end
end
有什么想法吗?
谢谢!
答案 0 :(得分:1)
id
上的.Select-multi-value-wrapper
选择是否有效,因为span
不是react-select组件的顶级代码。使用react-select和Capybara通常很困难,因为Capybara表单助手不会使用react-select的自定义标记和行为。
正如您所提到的,您可以使用现有帮助程序版本以及范围within
块和page.all()
来解决此问题。例如:
# helper
def react_select_capybara(selector, option)
within selector do
find('.Select-arrow-zone').click
expect(page).to have_css('.Select-menu-outer')
find('.Select-option', text: option).click
expect(page).to have_css('.Select-value-label', text: option)
end
end
# usage
given(:select_values) { ['Grace Hopper', 'Ada Lovelace'] }
...
react_selects = page.all('.Select')
select_values.each do |select_value, i|
react_select_capybara(react_selects[i], select_value)
end
虽然这会起作用,但它很脆弱 - 它依赖于页面上反应选择的隐式排序。更健壮的设置会为每个react-select组件传递一个自定义类名,以便在测试中唯一标识它。来自react-select docs on custom classnames:
您可以为组件提供自定义className prop,它将添加到基础.Select外部容器的className。
实现这可能看起来像:
# JSX
<ReactSelect className="js-select-user-form-1" ... />
<ReactSelect className="js-select-user-form-2" ... />
# Spec
react_select_capybara(".js-select-user-form-1", 'Grace Hopper')
react_select_capybara(".js-select-user-form-2", 'Ada Lovelace')
答案 1 :(得分:1)
page.select
不适用于此,因为它仅适用于HTNL <select>
元素。这是一个JS驱动的小部件,而不是HTML <select>
元素。
如果您只是自动化页面(而不是测试应用程序),那么使用JS(通过execute_script
)设置隐藏<input>
的值可能会更容易。
如果您正在测试应用,那么您可以使用page.all
收集所有反应选择并逐步完成,只要从任何反应选择中选择并不替换任何其他反应选择页面(会留下过时的元素)。
如果这还没有提供足够的信息来解决您的问题,而您真正的问题是尝试选择特定的反应选择,那么请在您的问题中添加足够的HTML,以便我们可以看到实际的差异存在于您尝试选择的小部件之间(例如,2个不同的反应选择元素)