Capybara不会通过其"名称"属性找到按钮

And*_*son 9 html ruby integration-testing ruby-on-rails capybara

经过W3C验证的HTML 5网页在登录表单中包含这个工作简单的按钮.

<input data-disable-with="Signing in, please wait&amp;hellip;"
       name="commit" type="submit" value="Sign in" />
Run Code Online (Sandbox Code Playgroud)

我正在编写一个基本无意义的测试:-)在Rails 3.2.17应用程序中,这只是为了获得Capybara的支持,我已经完全陷入谷歌搜索,阅读文档和阅读源代码到测试框架,没有喜悦- 尝试通过其name(即"commit")找到此按钮失败.

click_button("commit")
find_button("commit")
Run Code Online (Sandbox Code Playgroud)

两者都导致了Capybara::ElementNotFound: Unable to find button "commit".如果我使用的可见按钮文本Sign in元素,然后发现,即这些:

click_button("Sign in")
find_button("Sign in")
Run Code Online (Sandbox Code Playgroud)

...两者都工作正常,因此看起来XML解析器在查找元素时没有任何问题.

文档click_button说明定位器在"id,text或value"上工作,"text"对于这样的input元素没有意义(可见文本取自value属性),但可能与button元素相关.因此,我们可能希望失败,但是如果我们通过文档查看代码,则发现它以find与调用相同的方式调用find_button.然而find_button,记录不同; 它说它位于"id,name或value".令人遗憾的是,我们从中知道文档被破坏了,因为它说明了两个不同的事情,后者的结果是相同的.

无论哪种方式,都没有按名称找到该元素,这意味着我认为较低级别的find调用不会搜索name属性.这意味着Capybara(2.2.1,Nokogiri 1.6.1)在这方面相当破碎.怎么没有人注意到?我用谷歌搜索了很多年,似乎没有出现.我似乎很想念这一点:-)

你可能会问我为什么不在按钮中搜索英文文本?因为国际化.这个旧的,Rails 1 - > 2 - > 3升级的应用程序有一些I18n部分和其他静态文本部分.我不想被迫将I18n放入Capybara测试的任何视图中,这样我就可以使用测试I18n.t()来确保匹配尽管语言或语言环境文件更新不同.同样,在2014年将硬编码的英文字符串写入我的测试中显然是非常愚蠢的.

这就是为什么我们有名字和ID等......理所当然的(在理论上!)标识符是机器读取的,而不是人工读取的.

我可以通过"type = submit"来修改CSS所选择的内容,但是严重的是,为什么Capybara在其文档说明时没有搜索name属性,为什么文档不同意在两个调用的方法上搜索哪些属性使用完全相同的参数完全相同的后端实现?

TIA :)

And*_*son 16

事实证明,两个调用的文档都是误导性的,因为它们都没有查看列出的属性.显而易见的是,"按钮"的含义显然非常令人困惑,因为这里的一些人似乎认为它实际上只是一个HTML button元素,但事实并非如此.

如果您查看文档的来源,比如说click_button:

https://github.com/jnicklas/capybara/blob/a94dfbc4d07dcfe53bbea334f7f47f584737a0c0/lib/capybara/node/actions.rb#L36

......你会看到这只是调用(正如我在其他地方提到的)find一种类型:button,然后又传递给Capybara的Query引擎,而引擎最终只是使用标准的内部选择机制来查找事物.它非常优雅; 与外部客户端可以添加自己的自定义选择器以使查找更方便的方式相同:

http://rubydoc.info/github/jnicklas/capybara/master/Capybara#add_selector-class_method

...所以Capybara在内部添加了自己的选择器,重要的是,包括:button:

https://github.com/jnicklas/capybara/blob/a94dfbc4d07dcfe53bbea334f7f47f584737a0c0/lib/capybara/selector.rb#L133

它不是由任何特殊情况魔术完成的,只是一些预定义的自定义选择器.因此,如果您一直想知道在Capybara中可以使用哪些自定义选择器,那就是要读取的文件(它可能也被隐藏在文档中但我自己还没有找到列表).

在这里,我们看到按钮代码实际上是调用XPath::HTML.button,这是不同存储库中的不同代码块,具有以下文档:

http://rdoc.info/github/jnicklas/xpath/XPath/HTML#button-instance_method

...在编写时略微过时的代码,因为代码显示了更多的东西被识别,包括和的input类型(即,而不是,当然也包括后者) .resetbutton<input type="button"...><button...>...</button>

https://github.com/jnicklas/xpath/blob/59badfa50d645ac64c70fc6a0c2f7fe826999a1f/lib/xpath/html.rb#L22

我们还可以看到在这个代码finder方法真的只有通过认定id,value以及title-即不是通过"文本",并没有通过此姓名.

因此,假设XPath按预期运行,虽然从文档中不清楚,我们可以看到Capybara没有正确记录自己,但可能应该将链接转换为XPath API以获取更多信息,以避免当前的信息重复和这可能会给维护者和API客户端带来问题.

与此同时,我提出了这个问题:

https://github.com/jnicklas/capybara/issues/1267


Iev*_*gen 9

您也可以使用css选择器作为默认的capybara定位器.人们说他们更快.

find('[name=commit]').click
Run Code Online (Sandbox Code Playgroud)

Capybara不看name它的发现者的属性:(


Bab*_*avi 6

如果需要,可以使用xpath选择器

find(:xpath, "//input[contains(@name, 'commit')]").click()
Run Code Online (Sandbox Code Playgroud)