【问题标题】:How to write an RSpec matcher that respect's Capybara's within block?如何编写一个尊重 Capybara 块内的 RSpec 匹配器?
【发布时间】:2018-11-18 13:45:44
【问题描述】:

我正在尝试编写一个自定义的 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,而不是整个页面......

【问题讨论】:

    标签: ruby-on-rails rspec capybara


    【解决方案1】:

    在您的示例中,page 是 Capybara 会话(包含其当前范围)。当您在会话中调用 bodysourcehtml 是别名)时,它会返回文档的 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 提供的匹配器那样有任何等待/重试行为,因此您需要在使用之前确保您的页面已加载/稳定。

    【讨论】:

      猜你喜欢
      • 2015-01-16
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      相关资源
      最近更新 更多