有没有办法在Capybara中按文字查找任何元素?

Joã*_*tor 0 selenium automated-tests capybara

我想在我的页面上找到任何带有给定文本的元素,但是当我将它传递给没有元素的查找时,它会给我一个错误

find(material.attachment_filename) #material.attachment_filename is "01. pain killer.mp3"
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

find('a',text: material.attachment_filename)
Run Code Online (Sandbox Code Playgroud)

它工作正常,给定的错误是:

硒:: webdriver的::错误:: InvalidSelectorError:

给定css选择器表达式"01. pain killer.mp3"无效:SyntaxError:指定了无效或非法字符串

Tho*_*ole 7

Capybara的find有3个参数(Capybara选择器类型,定位器字符串和选项哈希).如果未指定选择器类型,则默认为:css,这意味着定位器字符串需要是CSS选择器.这意味着find(material.attachment_filename)在你的情况下相当于

find(:css, "01. pain killer.mp3")
Run Code Online (Sandbox Code Playgroud)

因为"01. pain killer.mp3"是无效的CSS会导致你看到的错误.如果你想找到包含文本的任何元素,你可以做类似的事情

find('*', text: "01. pain killer.mp3") 
Run Code Online (Sandbox Code Playgroud)

它会找到包含文本的任何元素,但是它也会找到所有的祖先元素,因为它们也包含文本,所以你可能想要的是使用正则表达式来确保元素只包含该内容

find('*', /\A#{Regexp.escape(material.attachment_filename)}\z/)
Run Code Online (Sandbox Code Playgroud)

应该解释为

find('*', /\A01\. pain killer\.mp3\z/)
Run Code Online (Sandbox Code Playgroud)

注意:如果您的页面上只包含简单内容,那将会非常缓慢,因为这意味着将所有元素从selenium传输到capybara以检查文本内容.

更高效的解决方案是使用XPath,它支持通过文本内容查找元素(CSS不支持)

find(:xpath, XPath.descendant[XPath.string.n.is(material.attachment_filename)]) #using the XPath library - contains (assuming Capybara.exact == false)
find(:xpath, XPath.descendant[XPath.string.n.is(material.attachment_filename)], exact: true) #using the XPath library - equals (you could also pass exact:false to force contains)
Run Code Online (Sandbox Code Playgroud)

如果元素实际上是您正在寻找的链接,那么您可能想要使用

find(:xpath, ".//*[contains(., '#{material.attachment_filename}')]") #contains the text
find(:xpath, ".//*[text()='#{material.attachment_filename}']") #equals the text
Run Code Online (Sandbox Code Playgroud)

要么

find_link("01. pain killer.mp3")
Run Code Online (Sandbox Code Playgroud)