Как написать соответствие RSpec, которое уважает Capybara в пределах блока? - PullRequest
0 голосов
/ 18 ноября 2018

Я пытаюсь написать собственный сопоставитель RSpec для использования в системных тестах Rails, работающих под Capybara - идея состоит в том, чтобы сопоставлять текст, игнорируя при этом определенные теги <span>.

Этоmatcher:

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, а не как целая страница ...

1 Ответ

0 голосов
/ 18 ноября 2018

В вашем примере page - это сеанс капибары (который содержит его текущую область действия). Когда вы вызываете 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, поэтому вам необходимо убедиться, что ваша страница загружена / стабильна перед ее использованием.

...