Refactoring: Prefer RSpec matchers over selectors for expressive output and isolated scope.
This commit is contained in:
parent
7c935655d5
commit
8386a07a7b
11 changed files with 186 additions and 54 deletions
|
@ -1,20 +0,0 @@
|
||||||
RSpec::Matchers.define :allow_to_search_for do |expected|
|
|
||||||
match do |actual|
|
|
||||||
search_string = expected.translation.title
|
|
||||||
|
|
||||||
actual.find('.js-search-input').fill_in with: search_string
|
|
||||||
actual.find('.search-results').has_text? search_string
|
|
||||||
end
|
|
||||||
|
|
||||||
description do
|
|
||||||
"allows to search for \"#{expected.translation.title}\""
|
|
||||||
end
|
|
||||||
|
|
||||||
failure_message do
|
|
||||||
"could not search for \"#{expected.translation.title}\""
|
|
||||||
end
|
|
||||||
|
|
||||||
failure_message do
|
|
||||||
"\"#{expected.translation.title}\" showed up in search results"
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -39,18 +39,3 @@ end
|
||||||
Capybara.add_selector(:link_containing) do
|
Capybara.add_selector(:link_containing) do
|
||||||
xpath { |text| ".//a//*[text()[contains(.,\"#{text}\")]]" }
|
xpath { |text| ".//a//*[text()[contains(.,\"#{text}\")]]" }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Knowledge Base
|
|
||||||
Capybara.add_selector(:knowledge_base_editor_bar) do
|
|
||||||
css { '.topbar' }
|
|
||||||
end
|
|
||||||
|
|
||||||
Capybara.add_selector(:knowledge_base_language_banner) do
|
|
||||||
css { '.language-banner' }
|
|
||||||
end
|
|
||||||
|
|
||||||
# don't use "knowledge_base" prefix because breadcrumbs
|
|
||||||
# could be available in other contexts (in the future)
|
|
||||||
Capybara.add_selector(:breadcrumb) do
|
|
||||||
css { '.breadcrumbs .breadcrumb span' }
|
|
||||||
end
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
module KnowledgeBasePublicMatchers
|
||||||
|
module HaveBreadcrumb
|
||||||
|
extend RSpec::Matchers::DSL
|
||||||
|
|
||||||
|
matcher :have_breadcrumb do
|
||||||
|
match { breadcrumb_found? && of_specified_length? }
|
||||||
|
|
||||||
|
chain(:with, :length)
|
||||||
|
chain(:items) {}
|
||||||
|
|
||||||
|
description do
|
||||||
|
if @length.present?
|
||||||
|
"have #{@length}-item breadcrumb"
|
||||||
|
else
|
||||||
|
'have breadcrumb'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do
|
||||||
|
if breadcrumb_found? && !of_specified_length?
|
||||||
|
"expected breadcrumb to contain #{@length} items (#{actual_length} found)"
|
||||||
|
else
|
||||||
|
'expected to find breadcrumb, but none was found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message_when_negated do
|
||||||
|
if breadcrumb_found? && @length.present?
|
||||||
|
"expected breadcrumb not to contain #{@length} items"
|
||||||
|
else
|
||||||
|
'expected not to find breadcrumb, but did'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def breadcrumb_found?
|
||||||
|
actual.has_css?('.breadcrumbs')
|
||||||
|
end
|
||||||
|
|
||||||
|
def of_specified_length?
|
||||||
|
@length.nil? || @length == actual_length
|
||||||
|
end
|
||||||
|
|
||||||
|
def actual_length
|
||||||
|
actual.all('.breadcrumbs .breadcrumb').length
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include KnowledgeBasePublicMatchers::HaveBreadcrumb, type: :system
|
||||||
|
end
|
|
@ -0,0 +1,53 @@
|
||||||
|
module KnowledgeBasePublicMatchers
|
||||||
|
module HaveBreadcrumbItem
|
||||||
|
extend RSpec::Matchers::DSL
|
||||||
|
|
||||||
|
matcher :have_breadcrumb_item do |expected|
|
||||||
|
match { breadcrumb_item_found? && at_specified_index? }
|
||||||
|
|
||||||
|
chain(:at_index, :index)
|
||||||
|
|
||||||
|
description do
|
||||||
|
if @index.present?
|
||||||
|
%(have "#{expected}" in breadcrumb at index #{@index})
|
||||||
|
else
|
||||||
|
%(have "#{expected}" in breadcrumb)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do
|
||||||
|
if breadcrumb_item_found? && !at_specified_index?
|
||||||
|
%(expected to find "#{expected}" at index #{@index} of breadcrumb (found at #{breadcrumb_item_index}))
|
||||||
|
else
|
||||||
|
%(expected to find "#{expected}" in breadcrumb, but did not)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message_when_negated do
|
||||||
|
if breadcrumb_item_found? && @index.present?
|
||||||
|
%(expected not to find "#{expected}" at index #{@index} of breadcrumb)
|
||||||
|
else
|
||||||
|
%(expected not to find "#{expected}" in breadcrumb, but did)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def breadcrumb_item_found?
|
||||||
|
!breadcrumb_item_index.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def at_specified_index?
|
||||||
|
@index.nil? || @index == breadcrumb_item_index
|
||||||
|
end
|
||||||
|
|
||||||
|
def breadcrumb_item_index
|
||||||
|
@breadcrumb_item_index ||= actual.all('.breadcrumbs .breadcrumb').index do |item|
|
||||||
|
item.find('span').text == expected
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include KnowledgeBasePublicMatchers::HaveBreadcrumbItem, type: :system
|
||||||
|
end
|
|
@ -0,0 +1,16 @@
|
||||||
|
module KnowledgeBasePublicMatchers
|
||||||
|
module HaveEditorBar
|
||||||
|
extend RSpec::Matchers::DSL
|
||||||
|
|
||||||
|
matcher :have_editor_bar do
|
||||||
|
match { actual.has_css? '.topbar' }
|
||||||
|
description { 'display editor bar' }
|
||||||
|
failure_message { 'expected to find editor bar above header, but did not' }
|
||||||
|
failure_message_when_negated { 'expected not to find editor bar above header, but did' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include KnowledgeBasePublicMatchers::HaveEditorBar, type: :system
|
||||||
|
end
|
|
@ -0,0 +1,16 @@
|
||||||
|
module KnowledgeBasePublicMatchers
|
||||||
|
module HaveLanguageBanner
|
||||||
|
extend RSpec::Matchers::DSL
|
||||||
|
|
||||||
|
matcher :have_language_banner do
|
||||||
|
match { actual.has_css? '.language-banner' }
|
||||||
|
description { 'display language banner' }
|
||||||
|
failure_message { 'expected to find language banner, but did not' }
|
||||||
|
failure_message_when_negated { 'expected not to find language banner, but did' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include KnowledgeBasePublicMatchers::HaveLanguageBanner, type: :system
|
||||||
|
end
|
|
@ -0,0 +1,30 @@
|
||||||
|
module KnowledgeBasePublicMatchers
|
||||||
|
module ProduceSearchResultFor
|
||||||
|
extend RSpec::Matchers::DSL
|
||||||
|
|
||||||
|
matcher :produce_search_result_for do |expected|
|
||||||
|
match do |actual|
|
||||||
|
search_string = expected.translation.title
|
||||||
|
|
||||||
|
actual.find('.js-search-input').fill_in with: search_string
|
||||||
|
actual.find('.search-results').has_text? search_string
|
||||||
|
end
|
||||||
|
|
||||||
|
description do
|
||||||
|
%(allows to search for "#{expected.translation.title}")
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do
|
||||||
|
%(could not search for "#{expected.translation.title}")
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do
|
||||||
|
%("#{expected.translation.title}" showed up in search results)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.include KnowledgeBasePublicMatchers::ProduceSearchResultFor, type: :system
|
||||||
|
end
|
|
@ -17,14 +17,14 @@ RSpec.describe 'Public Knowledge Base for guest search', type: :system, authenti
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'list published article' do
|
it 'list published article' do
|
||||||
expect(page).to allow_to_search_for published_answer
|
expect(page).to produce_search_result_for published_answer
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'list draft article' do
|
it 'list draft article' do
|
||||||
expect(page).to allow_to_search_for draft_answer
|
expect(page).to produce_search_result_for draft_answer
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'list internal article' do
|
it 'list internal article' do
|
||||||
expect(page).to allow_to_search_for internal_answer
|
expect(page).to produce_search_result_for internal_answer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ RSpec.describe 'Public Knowledge Base for editor', type: :system, authenticated:
|
||||||
context 'homepage' do
|
context 'homepage' do
|
||||||
before { visit help_no_locale_path }
|
before { visit help_no_locale_path }
|
||||||
|
|
||||||
it { expect(page).to have_selector(:knowledge_base_editor_bar) }
|
it { expect(page).to have_editor_bar }
|
||||||
|
|
||||||
it 'expect to have edit button' do
|
it 'expect to have edit button' do
|
||||||
button = find '.topbar-btn'
|
button = find '.topbar-btn'
|
||||||
|
|
|
@ -17,14 +17,14 @@ RSpec.describe 'Public Knowledge Base for guest search', type: :system, authenti
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'list published article' do
|
it 'list published article' do
|
||||||
expect(page).to allow_to_search_for published_answer
|
expect(page).to produce_search_result_for published_answer
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'not list draft article' do
|
it 'not list draft article' do
|
||||||
expect(page).not_to allow_to_search_for draft_answer
|
expect(page).not_to produce_search_result_for draft_answer
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'not list internal article' do
|
it 'not list internal article' do
|
||||||
expect(page).not_to allow_to_search_for internal_answer
|
expect(page).not_to produce_search_result_for internal_answer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,8 +12,8 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated:
|
||||||
|
|
||||||
it('is redirected to primary locale') { expect(page).to have_current_path help_root_path(primary_locale.system_locale.locale) }
|
it('is redirected to primary locale') { expect(page).to have_current_path help_root_path(primary_locale.system_locale.locale) }
|
||||||
|
|
||||||
it { expect(page).not_to have_selector(:breadcrumb) }
|
it { expect(page).not_to have_breadcrumb }
|
||||||
it { expect(page).not_to have_selector(:knowledge_base_editor_bar) }
|
it { expect(page).not_to have_editor_bar }
|
||||||
|
|
||||||
it 'shows category' do
|
it 'shows category' do
|
||||||
within '.main' do
|
within '.main' do
|
||||||
|
@ -31,7 +31,7 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated:
|
||||||
context 'category' do
|
context 'category' do
|
||||||
before { visit help_category_path(primary_locale.system_locale.locale, category) }
|
before { visit help_category_path(primary_locale.system_locale.locale, category) }
|
||||||
|
|
||||||
it { expect(page).to have_selector(:breadcrumb) }
|
it { expect(page).to have_breadcrumb }
|
||||||
|
|
||||||
it 'shows published answer' do
|
it 'shows published answer' do
|
||||||
within '.main' do
|
within '.main' do
|
||||||
|
@ -52,9 +52,9 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated:
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'breadcrumb' do
|
context 'breadcrumb' do
|
||||||
it { expect(page).to have_selector(:breadcrumb, count: 2) }
|
it { expect(page).to have_breadcrumb.with(2).items }
|
||||||
it { expect(page.all(:breadcrumb)[0]).to have_text(knowledge_base.translation.title) }
|
it { expect(page).to have_breadcrumb_item(knowledge_base.translation.title).at_index(0) }
|
||||||
it { expect(page.all(:breadcrumb)[1]).to have_text(category.translation.title) }
|
it { expect(page).to have_breadcrumb_item(category.translation.title).at_index(1) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,17 +62,17 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated:
|
||||||
before { visit help_answer_path(primary_locale.system_locale.locale, category, published_answer) }
|
before { visit help_answer_path(primary_locale.system_locale.locale, category, published_answer) }
|
||||||
|
|
||||||
context 'breadcrumb' do
|
context 'breadcrumb' do
|
||||||
it { expect(page).to have_selector(:breadcrumb, count: 3) }
|
it { expect(page).to have_breadcrumb.with(3).items }
|
||||||
it { expect(page.all(:breadcrumb)[0]).to have_text(knowledge_base.translation.title) }
|
it { expect(page).to have_breadcrumb_item(knowledge_base.translation.title).at_index(0) }
|
||||||
it { expect(page.all(:breadcrumb)[1]).to have_text(category.translation.title) }
|
it { expect(page).to have_breadcrumb_item(category.translation.title).at_index(1) }
|
||||||
it { expect(page.all(:breadcrumb)[2]).to have_text(published_answer.translation.title) }
|
it { expect(page).to have_breadcrumb_item(published_answer.translation.title).at_index(2) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'wrong locale' do
|
context 'wrong locale' do
|
||||||
before { visit help_root_path(alternative_locale.system_locale.locale) }
|
before { visit help_root_path(alternative_locale.system_locale.locale) }
|
||||||
|
|
||||||
it { expect(page).to have_selector(:knowledge_base_language_banner) }
|
it { expect(page).to have_language_banner }
|
||||||
|
|
||||||
context 'switch to correct locale after clicking on language banner' do
|
context 'switch to correct locale after clicking on language banner' do
|
||||||
before do
|
before do
|
||||||
|
@ -81,7 +81,7 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(page).not_to have_selector(:knowledge_base_language_banner) }
|
it { expect(page).not_to have_language_banner }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue