我正在尝试编写一个自定义的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
而不是整个页面的形式传递。
答案 0 :(得分:2)
在您的示例中,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提供的匹配器那样具有任何等待/重试行为,因此您需要在使用页面之前确保页面已加载/稳定。