我正在尝试编写一个自定义的RSpec匹配器,用于在Capybara下运行的Rails系统测试,其想法是在忽略某些<span>
标记的情况下匹配文本。
这就是匹配器:
RSpec::Matchers.define :have_cleaned_text do |text|
match do |content|
content.body.include?(text) || content.body.gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
以及正在测试的页面的HTML正文:
<h1>Test Page</h1>
<div id='constraint'>
<p>Clean text</p>
<p>Broken<span class='separator'>|<span>text</p>
</div>
前两项测试通过:
within('#constraint') do
expect(page).to have_cleaned_text('Clean text')
expect(page).to have_cleaned_text('Broken text')
expect(page).not_to have_cleaned_text('Test Page') # fails!
end
…但第三个失败,因为have_cleaned_text
忽略了within
块并针对整个页面进行测试。
如何使我的匹配器尊重within
块?我本以为它会作为content
通过,而不是整个页面…
在您的示例中,page
是一个Capybara会话(包含其当前范围(。当您在会话中调用body
(source
和html
是别名(时,它会返回文档的HTML源。由于您正在寻找元素的HTML源代码,因此需要类似的内容
RSpec::Matchers.define :have_cleaned_text do |text|
match do |session|
session.current_scope[:innerHTML].include?(text) || session.current_scope[:innerHTML].gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
请注意,像这样编写的匹配器不会有任何等待/重试行为,就像Capybara提供的匹配器一样,所以在使用它之前,你需要确保你的页面加载/稳定。