Commit 7bff17eb authored by Rémy Coutable's avatar Rémy Coutable

Shave spec/features/issues/filtered_search/dropdown_label_spec.rb from 10 minutes to 1.5 minutes

- Don't use `sleep` (most of the time was wasted by that)
- Expect some elements to be visible instead: capybara is smart enough
  to retry a few times if it cannot find an element
- See
  https://github.com/teamcapybara/capybara#asynchronous-javascript-ajax-and-friends
- Don't create unneccessary DB records
- Group some examples together to shave some setup time (where it makes
  sense)
Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent ee59a64b
require 'rails_helper' require 'spec_helper'
describe 'Dropdown label', js: true, feature: true do describe 'Dropdown label', js: true, feature: true do
include WaitForAjax let(:project) { create(:empty_project) }
let(:user) { create(:user) }
let(:filtered_search) { find('.filtered-search') }
let(:js_dropdown_label) { '#js-dropdown-label' }
let(:filter_dropdown) { find("#{js_dropdown_label} .filter-dropdown") }
let!(:project) { create(:empty_project) } shared_context 'with labels' do
let!(:user) { create(:user) } let!(:bug_label) { create(:label, project: project, title: 'bug-label') }
let!(:bug_label) { create(:label, project: project, title: 'bug') } let!(:uppercase_label) { create(:label, project: project, title: 'BUG-LABEL') }
let!(:uppercase_label) { create(:label, project: project, title: 'BUG') }
let!(:two_words_label) { create(:label, project: project, title: 'High Priority') } let!(:two_words_label) { create(:label, project: project, title: 'High Priority') }
let!(:wont_fix_label) { create(:label, project: project, title: 'Won"t Fix') } let!(:wont_fix_label) { create(:label, project: project, title: 'Won"t Fix') }
let!(:wont_fix_single_label) { create(:label, project: project, title: 'Won\'t Fix') } let!(:wont_fix_single_label) { create(:label, project: project, title: 'Won\'t Fix') }
let!(:special_label) { create(:label, project: project, title: '!@#$%^+&*()')} let!(:special_label) { create(:label, project: project, title: '!@#$%^+&*()') }
let!(:long_label) { create(:label, project: project, title: 'this is a very long title this is a very long title this is a very long title this is a very long title this is a very long title')} let!(:long_label) { create(:label, project: project, title: 'this is a very long title this is a very long title this is a very long title this is a very long title this is a very long title') }
let(:filtered_search) { find('.filtered-search') } end
let(:js_dropdown_label) { '#js-dropdown-label' }
def init_label_search
filtered_search.set('label:')
# This ensures the dropdown is shown
expect(find(js_dropdown_label)).not_to have_css('.filter-dropdown-loading')
end
def send_keys_to_filtered_search(input) def search_for_label(label)
input.split("").each do |i| init_label_search
filtered_search.send_keys(i) filtered_search.send_keys(label)
sleep 3
wait_for_ajax
sleep 3
end end
def click_label(text)
filter_dropdown.find('.filter-dropdown-item', text: text).click
end end
def dropdown_label_size def dropdown_label_size
page.all('#js-dropdown-label .filter-dropdown .filter-dropdown-item').size filter_dropdown.all('.filter-dropdown-item').size
end end
def click_label(text) def clear_search_field
find('#js-dropdown-label .filter-dropdown .filter-dropdown-item', text: text).click find('.filtered-search-input-container .clear-search').click
end end
before do before do
project.team << [user, :master] project.add_master(user)
login_as(user) login_as(user)
create(:issue, project: project) create(:issue, project: project)
...@@ -42,11 +50,12 @@ describe 'Dropdown label', js: true, feature: true do ...@@ -42,11 +50,12 @@ describe 'Dropdown label', js: true, feature: true do
describe 'keyboard navigation' do describe 'keyboard navigation' do
it 'selects label' do it 'selects label' do
send_keys_to_filtered_search('label:') bug_label = create(:label, project: project, title: 'bug-label')
init_label_search
filtered_search.native.send_keys(:down, :down, :enter) filtered_search.native.send_keys(:down, :down, :enter)
expect(filtered_search.value).to eq("label:~#{special_label.name} ") expect(filtered_search.value).to eq("label:~#{bug_label.title} ")
end end
end end
...@@ -54,171 +63,177 @@ describe 'Dropdown label', js: true, feature: true do ...@@ -54,171 +63,177 @@ describe 'Dropdown label', js: true, feature: true do
it 'opens when the search bar has label:' do it 'opens when the search bar has label:' do
filtered_search.set('label:') filtered_search.set('label:')
expect(page).to have_css(js_dropdown_label, visible: true) expect(page).to have_css(js_dropdown_label)
end end
it 'closes when the search bar is unfocused' do it 'closes when the search bar is unfocused' do
find('body').click() find('body').click
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
end end
it 'should show loading indicator when opened' do it 'shows loading indicator when opened and hides it when loaded' do
filtered_search.set('label:') filtered_search.set('label:')
expect(page).to have_css('#js-dropdown-label .filter-dropdown-loading', visible: true) expect(find(js_dropdown_label)).to have_css('.filter-dropdown-loading')
end expect(find(js_dropdown_label)).not_to have_css('.filter-dropdown-loading')
it 'should hide loading indicator when loaded' do
send_keys_to_filtered_search('label:')
expect(page).not_to have_css('#js-dropdown-label .filter-dropdown-loading')
end end
it 'should load all the labels when opened' do it 'loads all the labels when opened' do
send_keys_to_filtered_search('label:') bug_label = create(:label, project: project, title: 'bug-label')
filtered_search.set('label:')
expect(dropdown_label_size).to be > 0 expect(filter_dropdown).to have_content(bug_label.title)
expect(dropdown_label_size).to eq(1)
end end
end end
describe 'filtering' do describe 'filtering' do
include_context 'with labels'
before do before do
filtered_search.set('label') init_label_search
end end
it 'filters by name' do it 'filters by case-insensitive name with or without symbol' do
send_keys_to_filtered_search(':b') search_for_label('b')
expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible
expect(dropdown_label_size).to eq(2) expect(dropdown_label_size).to eq(2)
end
it 'filters by case insensitive name' do
send_keys_to_filtered_search(':B')
expect(dropdown_label_size).to eq(2) clear_search_field
end init_label_search
it 'filters by name with symbol' do search_for_label('~bu')
send_keys_to_filtered_search(':~bu')
expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible
expect(dropdown_label_size).to eq(2) expect(dropdown_label_size).to eq(2)
end end
it 'filters by case insensitive name with symbol' do it 'filters by multiple words with or without symbol' do
send_keys_to_filtered_search(':~BU') filtered_search.send_keys('Hig')
expect(dropdown_label_size).to eq(2)
end
it 'filters by multiple words' do
send_keys_to_filtered_search(':Hig')
expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end
it 'filters by multiple words with symbol' do clear_search_field
send_keys_to_filtered_search(':~Hig') init_label_search
filtered_search.send_keys('~Hig')
expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end end
it 'filters by multiple words containing single quotes' do it 'filters by multiple words containing single quotes with or without symbol' do
send_keys_to_filtered_search(':won\'t') filtered_search.send_keys('won\'t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end
it 'filters by multiple words containing single quotes with symbol' do clear_search_field
send_keys_to_filtered_search(':~won\'t') init_label_search
filtered_search.send_keys('~won\'t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end end
it 'filters by multiple words containing double quotes' do it 'filters by multiple words containing double quotes with or without symbol' do
send_keys_to_filtered_search(':won"t') filtered_search.send_keys('won"t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end
it 'filters by multiple words containing double quotes with symbol' do clear_search_field
send_keys_to_filtered_search(':~won"t') init_label_search
filtered_search.send_keys('~won"t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end end
it 'filters by special characters' do it 'filters by special characters with or without symbol' do
send_keys_to_filtered_search(':^+') filtered_search.send_keys('^+')
expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end
it 'filters by special characters with symbol' do clear_search_field
send_keys_to_filtered_search(':~^+') init_label_search
filtered_search.send_keys('~^+')
expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible
expect(dropdown_label_size).to eq(1) expect(dropdown_label_size).to eq(1)
end end
end end
describe 'selecting from dropdown' do describe 'selecting from dropdown' do
include_context 'with labels'
before do before do
filtered_search.set('label:') init_label_search
end end
it 'fills in the label name when the label has not been filled' do it 'fills in the label name when the label has not been filled' do
click_label(bug_label.title) click_label(bug_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~#{bug_label.title} ") expect(filtered_search.value).to eq("label:~#{bug_label.title} ")
end end
it 'fills in the label name when the label is partially filled' do it 'fills in the label name when the label is partially filled' do
send_keys_to_filtered_search('bu') filtered_search.send_keys('bu')
click_label(bug_label.title) click_label(bug_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~#{bug_label.title} ") expect(filtered_search.value).to eq("label:~#{bug_label.title} ")
end end
it 'fills in the label name that contains multiple words' do it 'fills in the label name that contains multiple words' do
click_label(two_words_label.title) click_label(two_words_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~\"#{two_words_label.title}\" ") expect(filtered_search.value).to eq("label:~\"#{two_words_label.title}\" ")
end end
it 'fills in the label name that contains multiple words and is very long' do it 'fills in the label name that contains multiple words and is very long' do
click_label(long_label.title) click_label(long_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~\"#{long_label.title}\" ") expect(filtered_search.value).to eq("label:~\"#{long_label.title}\" ")
end end
it 'fills in the label name that contains double quotes' do it 'fills in the label name that contains double quotes' do
click_label(wont_fix_label.title) click_label(wont_fix_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~'#{wont_fix_label.title}' ") expect(filtered_search.value).to eq("label:~'#{wont_fix_label.title}' ")
end end
it 'fills in the label name with the correct capitalization' do it 'fills in the label name with the correct capitalization' do
click_label(uppercase_label.title) click_label(uppercase_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~#{uppercase_label.title} ") expect(filtered_search.value).to eq("label:~#{uppercase_label.title} ")
end end
it 'fills in the label name with special characters' do it 'fills in the label name with special characters' do
click_label(special_label.title) click_label(special_label.title)
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:~#{special_label.title} ") expect(filtered_search.value).to eq("label:~#{special_label.title} ")
end end
it 'selects `no label`' do it 'selects `no label`' do
find('#js-dropdown-label .filter-dropdown-item', text: 'No Label').click find("#{js_dropdown_label} .filter-dropdown-item", text: 'No Label').click
expect(page).to have_css(js_dropdown_label, visible: false) expect(page).not_to have_css(js_dropdown_label)
expect(filtered_search.value).to eq("label:none ") expect(filtered_search.value).to eq("label:none ")
end end
end end
...@@ -226,44 +241,47 @@ describe 'Dropdown label', js: true, feature: true do ...@@ -226,44 +241,47 @@ describe 'Dropdown label', js: true, feature: true do
describe 'input has existing content' do describe 'input has existing content' do
it 'opens label dropdown with existing search term' do it 'opens label dropdown with existing search term' do
filtered_search.set('searchTerm label:') filtered_search.set('searchTerm label:')
expect(page).to have_css(js_dropdown_label, visible: true)
expect(page).to have_css(js_dropdown_label)
end end
it 'opens label dropdown with existing author' do it 'opens label dropdown with existing author' do
filtered_search.set('author:@person label:') filtered_search.set('author:@person label:')
expect(page).to have_css(js_dropdown_label, visible: true)
expect(page).to have_css(js_dropdown_label)
end end
it 'opens label dropdown with existing assignee' do it 'opens label dropdown with existing assignee' do
filtered_search.set('assignee:@person label:') filtered_search.set('assignee:@person label:')
expect(page).to have_css(js_dropdown_label, visible: true)
expect(page).to have_css(js_dropdown_label)
end end
it 'opens label dropdown with existing label' do it 'opens label dropdown with existing label' do
filtered_search.set('label:~urgent label:') filtered_search.set('label:~urgent label:')
expect(page).to have_css(js_dropdown_label, visible: true)
expect(page).to have_css(js_dropdown_label)
end end
it 'opens label dropdown with existing milestone' do it 'opens label dropdown with existing milestone' do
filtered_search.set('milestone:%v2.0 label:') filtered_search.set('milestone:%v2.0 label:')
expect(page).to have_css(js_dropdown_label, visible: true)
expect(page).to have_css(js_dropdown_label)
end end
end end
describe 'caching requests' do describe 'caching requests' do
it 'caches requests after the first load' do it 'caches requests after the first load' do
filtered_search.set('label') create(:label, project: project, title: 'bug-label')
send_keys_to_filtered_search(':') init_label_search
initial_size = dropdown_label_size
expect(initial_size).to be > 0 expect(dropdown_label_size).to eq(1)
create(:label, project: project) create(:label, project: project)
find('.filtered-search-input-container .clear-search').click clear_search_field
filtered_search.set('label') init_label_search
send_keys_to_filtered_search(':')
expect(dropdown_label_size).to eq(initial_size) expect(dropdown_label_size).to eq(1)
end end
end end
end end
...@@ -35,6 +35,7 @@ RSpec.configure do |config| ...@@ -35,6 +35,7 @@ RSpec.configure do |config|
config.include Warden::Test::Helpers, type: :request config.include Warden::Test::Helpers, type: :request
config.include LoginHelpers, type: :feature config.include LoginHelpers, type: :feature
config.include SearchHelpers, type: :feature config.include SearchHelpers, type: :feature
config.include WaitForAjax, type: :feature
config.include StubConfiguration config.include StubConfiguration
config.include EmailHelpers, type: :mailer config.include EmailHelpers, type: :mailer
config.include TestEnv config.include TestEnv
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment