diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 07:33:21 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 07:33:21 +0000 |
commit | 36a59d088eca61b834191dacea009677a96c052f (patch) | |
tree | e4f33972dab5d8ef79e3944a9f403035fceea43f /spec/features/issues | |
parent | a1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff) | |
download | gitlab-ce-36a59d088eca61b834191dacea009677a96c052f.tar.gz |
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'spec/features/issues')
22 files changed, 423 insertions, 524 deletions
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb index 507d427bf0b..1e8b9b6b60b 100644 --- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb +++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb @@ -26,7 +26,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j end it 'shows a button to resolve all threads by creating a new issue' do - within('.line-resolve-all-container') do + within('.discussions-counter') do expect(page).to have_selector resolve_all_discussions_link_selector( title: "Create issue to resolve all threads" ) end end @@ -76,14 +76,12 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j end it 'has a link to resolve all threads by creating an issue' do - page.within '.mr-widget-body' do - expect(page).to have_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) - end + expect(page).to have_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end context 'creating an issue for threads' do before do - page.within '.mr-widget-body' do + page.within '.mr-state-widget' do page.click_link 'Create issue to resolve all threads', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) wait_for_all_requests diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 3ba2f7e788d..18b70c9622a 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -6,11 +6,12 @@ RSpec.describe 'Dropdown assignee', :js do include FilteredSearchHelpers let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } - let(:js_dropdown_assignee) { '#js-dropdown-assignee' } - let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") } + before do + stub_feature_flags(vue_issues_list: true) + end describe 'behavior' do before do @@ -21,15 +22,17 @@ RSpec.describe 'Dropdown assignee', :js do end it 'loads all the assignees when opened' do - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=' - expect_filtered_search_dropdown_results(filter_dropdown, 2) + # Expect None, Any, administrator, John Doe2 + expect_suggestion_count 4 end it 'shows current user at top of dropdown' do - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=' - expect(filter_dropdown.first('.filter-dropdown-item')).to have_content(user.name) + # List items 1 to 3 are None, Any, divider + expect(page).to have_css('.gl-filtered-search-suggestion:nth-child(4)', text: user.name) end end @@ -41,7 +44,7 @@ RSpec.describe 'Dropdown assignee', :js do visit project_issues_path(project) Gitlab::Testing::RequestBlockerMiddleware.block_requests! - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=' end after do @@ -49,11 +52,10 @@ RSpec.describe 'Dropdown assignee', :js do end it 'selects current user' do - find("#{js_dropdown_assignee} .filter-dropdown-item", text: user.username).click + click_on user.username - expect(page).to have_css(js_dropdown_assignee, visible: false) - expect_tokens([assignee_token(user.username)]) - expect_filtered_search_input_empty + expect_assignee_token(user.username) + expect_empty_search_term end end @@ -93,7 +95,7 @@ RSpec.describe 'Dropdown assignee', :js do it 'shows inherited, direct, and invited group members but not descendent members', :aggregate_failures do visit issues_group_path(subgroup) - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=' expect(page).to have_text group_user.name expect(page).to have_text subgroup_user.name @@ -103,7 +105,7 @@ RSpec.describe 'Dropdown assignee', :js do visit project_issues_path(subgroup_project) - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=' expect(page).to have_text group_user.name expect(page).to have_text subgroup_user.name diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 893ffc6575b..07e2bd3b7e4 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -6,13 +6,12 @@ RSpec.describe 'Dropdown author', :js do include FilteredSearchHelpers let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } - let(:js_dropdown_author) { '#js-dropdown-author' } - let(:filter_dropdown) { find("#{js_dropdown_author} .filter-dropdown") } - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) sign_in(user) @@ -21,22 +20,22 @@ RSpec.describe 'Dropdown author', :js do describe 'behavior' do it 'loads all the authors when opened' do - input_filtered_search('author:=', submit: false, extra_space: false) + select_tokens 'Author', '=' - expect_filtered_search_dropdown_results(filter_dropdown, 2) + expect_suggestion_count 2 end it 'shows current user at top of dropdown' do - input_filtered_search('author:=', submit: false, extra_space: false) + select_tokens 'Author', '=' - expect(filter_dropdown.first('.filter-dropdown-item')).to have_content(user.name) + expect(page).to have_css('.gl-filtered-search-suggestion:first-child', text: user.name) end end describe 'selecting from dropdown without Ajax call' do before do Gitlab::Testing::RequestBlockerMiddleware.block_requests! - input_filtered_search('author:=', submit: false, extra_space: false) + select_tokens 'Author', '=' end after do @@ -44,11 +43,10 @@ RSpec.describe 'Dropdown author', :js do end it 'selects current user' do - find("#{js_dropdown_author} .filter-dropdown-item", text: user.username).click + click_on user.username - expect(page).to have_css(js_dropdown_author, visible: false) - expect_tokens([author_token(user.username)]) - expect_filtered_search_input_empty + expect_author_token(user.username) + expect_empty_search_term end end end diff --git a/spec/features/issues/filtered_search/dropdown_base_spec.rb b/spec/features/issues/filtered_search/dropdown_base_spec.rb index b8fb807dd78..5fdab288b2d 100644 --- a/spec/features/issues/filtered_search/dropdown_base_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_base_spec.rb @@ -6,18 +6,12 @@ RSpec.describe 'Dropdown base', :js do include FilteredSearchHelpers let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - let(:js_dropdown_assignee) { '#js-dropdown-assignee' } - let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") } - - def dropdown_assignee_size - filter_dropdown.all('.filter-dropdown-item').size - end - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) sign_in(user) @@ -26,17 +20,17 @@ RSpec.describe 'Dropdown base', :js do describe 'caching requests' do it 'caches requests after the first load' do - input_filtered_search('assignee:=', submit: false, extra_space: false) - initial_size = dropdown_assignee_size + select_tokens 'Assignee', '=' + initial_size = get_suggestion_count expect(initial_size).to be > 0 new_user = create(:user) project.add_maintainer(new_user) - find('.filtered-search-box .clear-search').click - input_filtered_search('assignee:=', submit: false, extra_space: false) + click_button 'Clear' + select_tokens 'Assignee', '=' - expect(dropdown_assignee_size).to eq(initial_size) + expect_suggestion_count(initial_size) end end end diff --git a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb index f5ab53d5052..d6d59b89a8c 100644 --- a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb @@ -6,15 +6,13 @@ RSpec.describe 'Dropdown emoji', :js do include FilteredSearchHelpers let_it_be(:project) { create(:project, :public) } - let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } let_it_be(:award_emoji_star) { create(:award_emoji, name: 'star', user: user, awardable: issue) } - let(:filtered_search) { find('.filtered-search') } - let(:js_dropdown_emoji) { '#js-dropdown-my-reaction' } - let(:filter_dropdown) { find("#{js_dropdown_emoji} .filter-dropdown") } - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) create_list(:award_emoji, 2, user: user, name: 'thumbsup') create_list(:award_emoji, 1, user: user, name: 'thumbsdown') @@ -27,15 +25,15 @@ RSpec.describe 'Dropdown emoji', :js do end describe 'behavior' do - it 'does not open when the search bar has my-reaction=' do - filtered_search.set('my-reaction=') + it 'does not contain My-Reaction in the list of suggestions' do + click_filtered_search_bar - expect(page).not_to have_css(js_dropdown_emoji) + expect(page).not_to have_link 'My-Reaction' end end end - context 'when user loggged in' do + context 'when user logged in' do before do sign_in(user) @@ -43,22 +41,18 @@ RSpec.describe 'Dropdown emoji', :js do end describe 'behavior' do - it 'opens when the search bar has my-reaction=' do - filtered_search.set('my-reaction:=') - - expect(page).to have_css(js_dropdown_emoji, visible: true) - end - it 'loads all the emojis when opened' do - input_filtered_search('my-reaction:=', submit: false, extra_space: false) + select_tokens 'My-Reaction', '=' - expect_filtered_search_dropdown_results(filter_dropdown, 3) + # Expect None, Any, star, thumbsup, thumbsdown + expect_suggestion_count 5 end it 'shows the most populated emoji at top of dropdown' do - input_filtered_search('my-reaction:=', submit: false, extra_space: false) + select_tokens 'My-Reaction', '=' - expect(first("#{js_dropdown_emoji} .filter-dropdown li")).to have_content(award_emoji_star.name) + # List items 1-3 are None, Any, divider + expect(page).to have_css('.gl-filtered-search-suggestion-list li:nth-child(4)', text: award_emoji_star.name) end end end diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index 9cc58a33bb7..c64247b2b15 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -9,19 +9,9 @@ RSpec.describe 'Dropdown hint', :js do let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - let(:js_dropdown_hint) { '#js-dropdown-hint' } - let(:js_dropdown_operator) { '#js-dropdown-operator' } - - def click_hint(text) - find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: text).click - end - - def click_operator(op) - find("#js-dropdown-operator .filter-dropdown .filter-dropdown-item[data-value='#{op}']").click - end - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) end @@ -31,8 +21,9 @@ RSpec.describe 'Dropdown hint', :js do end it 'does not exist my-reaction dropdown item' do - expect(page).to have_css(js_dropdown_hint, visible: false) - expect(page).not_to have_content('My-reaction') + click_filtered_search_bar + + expect(page).not_to have_link 'My-reaction' end end @@ -45,57 +36,56 @@ RSpec.describe 'Dropdown hint', :js do describe 'behavior' do before do - expect(page).to have_css(js_dropdown_hint, visible: false) - filtered_search.click + click_filtered_search_bar end it 'opens when the search bar is first focused' do - expect(page).to have_css(js_dropdown_hint, visible: true) + expect_visible_suggestions_list find('body').click - expect(page).to have_css(js_dropdown_hint, visible: false) + expect_hidden_suggestions_list end end describe 'filtering' do it 'filters with text' do - filtered_search.set('a') + click_filtered_search_bar + send_keys 'as' - expect(find(js_dropdown_hint)).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6) + # Expect Assignee and Release + expect_suggestion_count 2 end end describe 'selecting from dropdown with no input' do before do - filtered_search.click + click_filtered_search_bar end it 'opens the token dropdown when you click on it' do - click_hint('Author') + click_link 'Author' - expect(page).to have_css(js_dropdown_hint, visible: false) - expect(page).to have_css(js_dropdown_operator, visible: true) + expect_visible_suggestions_list + expect_suggestion '=' - click_operator('=') + click_link '= is' - expect(page).to have_css(js_dropdown_hint, visible: false) - expect(page).to have_css(js_dropdown_operator, visible: false) - expect(page).to have_css('#js-dropdown-author', visible: true) - expect_tokens([{ name: 'Author', operator: '=' }]) - expect_filtered_search_input_empty + expect_visible_suggestions_list + expect_token_segment 'Author' + expect_token_segment '=' + expect_empty_search_term end end describe 'reselecting from dropdown' do it 'reuses existing token text' do - filtered_search.send_keys('author') - filtered_search.send_keys(:backspace) - filtered_search.send_keys(:backspace) - click_hint('Author') + click_filtered_search_bar + send_keys 'author', :backspace, :backspace + click_link 'Author' - expect_tokens([{ name: 'Author' }]) - expect_filtered_search_input_empty + expect_token_segment 'Author' + expect_empty_search_term end end end diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index 1b48810f716..67e3792a04c 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -10,10 +10,9 @@ RSpec.describe 'Dropdown label', :js do let_it_be(:issue) { create(:issue, project: project) } let_it_be(:label) { create(:label, project: project, title: 'bug-label') } - let(:filtered_search) { find('.filtered-search') } - let(:filter_dropdown) { find('#js-dropdown-label .filter-dropdown') } - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) sign_in(user) @@ -22,9 +21,10 @@ RSpec.describe 'Dropdown label', :js do describe 'behavior' do it 'loads all the labels when opened' do - filtered_search.set('label:=') + select_tokens 'Label', '=' - expect_filtered_search_dropdown_results(filter_dropdown, 1) + # Expect None, Any, bug-label + expect_suggestion_count 3 end end end diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index 859d1e4a5e5..19a4c8853f1 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -11,10 +11,9 @@ RSpec.describe 'Dropdown milestone', :js do let_it_be(:uppercase_milestone) { create(:milestone, title: 'CAP_MILESTONE', project: project) } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - let(:filter_dropdown) { find('#js-dropdown-milestone .filter-dropdown') } - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) sign_in(user) @@ -22,12 +21,11 @@ RSpec.describe 'Dropdown milestone', :js do end describe 'behavior' do - before do - filtered_search.set('milestone:=') - end - it 'loads all the milestones when opened' do - expect_filtered_search_dropdown_results(filter_dropdown, 2) + select_tokens 'Milestone', '=' + + # Expect None, Any, Upcoming, Started, CAP_MILESTONE, v1.0 + expect_suggestion_count 6 end end end diff --git a/spec/features/issues/filtered_search/dropdown_release_spec.rb b/spec/features/issues/filtered_search/dropdown_release_spec.rb index 2210a26c251..50ac9068b26 100644 --- a/spec/features/issues/filtered_search/dropdown_release_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_release_spec.rb @@ -5,16 +5,15 @@ require 'spec_helper' RSpec.describe 'Dropdown release', :js do include FilteredSearchHelpers - let_it_be(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } let_it_be(:release) { create(:release, tag: 'v1.0', project: project) } let_it_be(:crazy_release) { create(:release, tag: '☺!/"#%&\'{}+,-.<>;=@]_`{|}🚀', project: project) } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - let(:filter_dropdown) { find('#js-dropdown-release .filter-dropdown') } - before do + stub_feature_flags(vue_issues_list: true) + project.add_maintainer(user) sign_in(user) @@ -22,12 +21,11 @@ RSpec.describe 'Dropdown release', :js do end describe 'behavior' do - before do - filtered_search.set('release:=') - end - it 'loads all the releases when opened' do - expect_filtered_search_dropdown_results(filter_dropdown, 2) + select_tokens 'Release', '=' + + # Expect None, Any, v1.0, !/\"#%&'{}+,-.<>;=@]_`{|} + expect_suggestion_count 4 end end end diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 1375384d1aa..13bce49e6d1 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -6,13 +6,8 @@ RSpec.describe 'Filter issues', :js do include FilteredSearchHelpers let(:project) { create(:project) } - - # NOTE: The short name here is actually important - # - # When the name is longer, the filtered search input can end up scrolling - # horizontally, and PhantomJS can't handle it. - let(:user) { create(:user, name: 'Ann') } - let(:user2) { create(:user, name: 'jane') } + let(:user) { create(:user) } + let(:user2) { create(:user) } let!(:bug_label) { create(:label, project: project, title: 'bug') } let!(:caps_sensitive_label) { create(:label, project: project, title: 'CaPs') } @@ -24,6 +19,7 @@ RSpec.describe 'Filter issues', :js do end before do + stub_feature_flags(vue_issues_list: true) project.add_maintainer(user) create(:issue, project: project, author: user2, title: "Bug report 1") @@ -64,31 +60,25 @@ RSpec.describe 'Filter issues', :js do it 'filters by all available tokens' do search_term = 'issue' + select_tokens 'Assignee', '=', user.username, 'Author', '=', user.username, 'Label', '=', caps_sensitive_label.title, 'Milestone', '=', milestone.title + send_keys search_term, :enter - input_filtered_search("assignee:=@#{user.username} author:=@#{user.username} label:=~#{caps_sensitive_label.title} milestone:=%#{milestone.title} #{search_term}") - - wait_for_requests - - expect_tokens([ - assignee_token(user.name), - author_token(user.name), - label_token(caps_sensitive_label.title), - milestone_token(milestone.title) - ]) + expect_assignee_token(user.name) + expect_author_token(user.name) + expect_label_token(caps_sensitive_label.title) + expect_milestone_token(milestone.title) expect_issues_list_count(1) - expect_filtered_search_input(search_term) + expect_search_term(search_term) end describe 'filter issues by author' do context 'only author' do it 'filters issues by searched author' do - input_filtered_search("author:=@#{user.username}") + select_tokens 'Author', '=', user.username, submit: true - wait_for_requests - - expect_tokens([author_token(user.name)]) + expect_author_token(user.name) expect_issues_list_count(5) - expect_filtered_search_input_empty + expect_empty_search_term end end end @@ -96,46 +86,30 @@ RSpec.describe 'Filter issues', :js do describe 'filter issues by assignee' do context 'only assignee' do it 'filters issues by searched assignee' do - input_filtered_search("assignee:=@#{user.username}") - - wait_for_requests + select_tokens 'Assignee', '=', user.username, submit: true - expect_tokens([assignee_token(user.name)]) + expect_assignee_token(user.name) expect_issues_list_count(5) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by no assignee' do - input_filtered_search('assignee:=none') + select_tokens 'Assignee', '=', 'None', submit: true - expect_tokens([assignee_token('None')]) + expect_assignee_token 'None' expect_issues_list_count(3) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by invalid assignee' do skip('to be tested, issue #26546') end - - it 'filters issues by multiple assignees' do - create(:issue, project: project, author: user, assignees: [user2, user]) - - input_filtered_search("assignee:=@#{user.username} assignee:=@#{user2.username}") - - expect_tokens([ - assignee_token(user.name), - assignee_token(user2.name) - ]) - - expect_issues_list_count(1) - expect_filtered_search_input_empty - end end end describe 'filter by reviewer' do it 'does not allow filtering by reviewer' do - find('.filtered-search').click + click_filtered_search_bar expect(page).not_to have_button('Reviewer') end @@ -144,57 +118,53 @@ RSpec.describe 'Filter issues', :js do describe 'filter issues by label' do context 'only label' do it 'filters issues by searched label' do - input_filtered_search("label:=~#{bug_label.title}") + select_tokens 'Label', '=', bug_label.title, submit: true - expect_tokens([label_token(bug_label.title)]) + expect_label_token(bug_label.title) expect_issues_list_count(2) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues not containing searched label' do - input_filtered_search("label:!=~#{bug_label.title}") + select_tokens 'Label', '!=', bug_label.title, submit: true - expect_tokens([label_token(bug_label.title)]) + expect_negated_label_token(bug_label.title) expect_issues_list_count(6) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by any label' do - input_filtered_search('label:=any') + select_tokens 'Label', '=', 'Any', submit: true - expect_tokens([label_token('Any', false)]) + expect_label_token 'Any' expect_issues_list_count(4) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by no label' do - input_filtered_search('label:=none') + select_tokens 'Label', '=', 'None', submit: true - expect_tokens([label_token('None', false)]) + expect_label_token 'None' expect_issues_list_count(4) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by multiple labels' do - input_filtered_search("label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title}") + select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, submit: true - expect_tokens([ - label_token(bug_label.title), - label_token(caps_sensitive_label.title) - ]) + expect_label_token(bug_label.title) + expect_label_token(caps_sensitive_label.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by multiple labels with not operator' do - input_filtered_search("label:!=~#{bug_label.title} label:=~#{caps_sensitive_label.title}") + select_tokens 'Label', '!=', bug_label.title, 'Label', '=', caps_sensitive_label.title, submit: true - expect_tokens([ - label_token(bug_label.title), - label_token(caps_sensitive_label.title) - ]) + expect_negated_label_token(bug_label.title) + expect_label_token(caps_sensitive_label.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by label containing special characters' do @@ -202,11 +172,11 @@ RSpec.describe 'Filter issues', :js do special_issue = create(:issue, title: "Issue with special character label", project: project) special_issue.labels << special_label - input_filtered_search("label:=~#{special_label.title}") + select_tokens 'Label', '=', special_label.title, submit: true - expect_tokens([label_token(special_label.title)]) + expect_label_token(special_label.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by label not containing special characters' do @@ -214,21 +184,21 @@ RSpec.describe 'Filter issues', :js do special_issue = create(:issue, title: "Issue with special character label", project: project) special_issue.labels << special_label - input_filtered_search("label:!=~#{special_label.title}") + select_tokens 'Label', '!=', special_label.title, submit: true - expect_tokens([label_token(special_label.title)]) + expect_negated_label_token(special_label.title) expect_issues_list_count(8) - expect_filtered_search_input_empty + expect_empty_search_term end it 'does not show issues for unused labels' do new_label = create(:label, project: project, title: 'new_label') - input_filtered_search("label:=~#{new_label.title}") + select_tokens 'Label', '=', new_label.title, submit: true - expect_tokens([label_token(new_label.title)]) + expect_label_token(new_label.title) expect_no_issues_list - expect_filtered_search_input_empty + expect_empty_search_term end end @@ -238,31 +208,28 @@ RSpec.describe 'Filter issues', :js do special_multiple_issue = create(:issue, title: "Issue with special character multiple words label", project: project) special_multiple_issue.labels << special_multiple_label - input_filtered_search("label:=~'#{special_multiple_label.title}'") + select_tokens 'Label', '=', special_multiple_label.title, submit: true # Check for search results (which makes sure that the page has changed) expect_issues_list_count(1) - - # filtered search defaults quotations to double quotes - expect_tokens([label_token("\"#{special_multiple_label.title}\"")]) - - expect_filtered_search_input_empty + expect_label_token(special_multiple_label.title) + expect_empty_search_term end it 'single quotes' do - input_filtered_search("label:=~'#{multiple_words_label.title}'") + select_tokens 'Label', '=', multiple_words_label.title, submit: true expect_issues_list_count(1) - expect_tokens([label_token("\"#{multiple_words_label.title}\"")]) - expect_filtered_search_input_empty + expect_label_token(multiple_words_label.title) + expect_empty_search_term end it 'double quotes' do - input_filtered_search("label:=~\"#{multiple_words_label.title}\"") + select_tokens 'Label', '=', multiple_words_label.title, submit: true - expect_tokens([label_token("\"#{multiple_words_label.title}\"")]) + expect_label_token(multiple_words_label.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'single quotes containing double quotes' do @@ -270,11 +237,11 @@ RSpec.describe 'Filter issues', :js do double_quotes_label_issue = create(:issue, title: "Issue with double quotes label", project: project) double_quotes_label_issue.labels << double_quotes_label - input_filtered_search("label:=~'#{double_quotes_label.title}'") + select_tokens 'Label', '=', double_quotes_label.title, submit: true - expect_tokens([label_token("'#{double_quotes_label.title}'")]) + expect_label_token(double_quotes_label.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'double quotes containing single quotes' do @@ -282,49 +249,41 @@ RSpec.describe 'Filter issues', :js do single_quotes_label_issue = create(:issue, title: "Issue with single quotes label", project: project) single_quotes_label_issue.labels << single_quotes_label - input_filtered_search("label:=~\"#{single_quotes_label.title}\"") + select_tokens 'Label', '=', single_quotes_label.title, submit: true - expect_tokens([label_token("\"#{single_quotes_label.title}\"")]) + expect_label_token(single_quotes_label.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end end context 'multiple labels with other filters' do it 'filters issues by searched label, label2, author, assignee, milestone and text' do search_term = 'bug' - - input_filtered_search("label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title} author:=@#{user.username} assignee:=@#{user.username} milestone:=%#{milestone.title} #{search_term}") - - wait_for_requests - - expect_tokens([ - label_token(bug_label.title), - label_token(caps_sensitive_label.title), - author_token(user.name), - assignee_token(user.name), - milestone_token(milestone.title) - ]) + select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, 'Author', '=', user.username, 'Assignee', '=', user.username, 'Milestone', '=', milestone.title + send_keys search_term, :enter + + expect_label_token(bug_label.title) + expect_label_token(caps_sensitive_label.title) + expect_author_token(user.name) + expect_assignee_token(user.name) + expect_milestone_token(milestone.title) expect_issues_list_count(1) - expect_filtered_search_input(search_term) + expect_search_term(search_term) end it 'filters issues by searched label, label2, author, assignee, not included in a milestone' do search_term = 'bug' - - input_filtered_search("label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title} author:=@#{user.username} assignee:=@#{user.username} milestone:!=%#{milestone.title} #{search_term}") - - wait_for_requests - - expect_tokens([ - label_token(bug_label.title), - label_token(caps_sensitive_label.title), - author_token(user.name), - assignee_token(user.name), - milestone_token(milestone.title, false, '!=') - ]) + select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, 'Author', '=', user.username, 'Assignee', '=', user.username, 'Milestone', '!=', milestone.title + send_keys search_term, :enter + + expect_label_token(bug_label.title) + expect_label_token(caps_sensitive_label.title) + expect_author_token(user.name) + expect_assignee_token(user.name) + expect_negated_milestone_token(milestone.title) expect_issues_list_count(0) - expect_filtered_search_input(search_term) + expect_search_term(search_term) end end @@ -333,8 +292,8 @@ RSpec.describe 'Filter issues', :js do click_link multiple_words_label.title expect_issues_list_count(1) - expect_tokens([label_token("\"#{multiple_words_label.title}\"")]) - expect_filtered_search_input_empty + expect_label_token(multiple_words_label.title) + expect_empty_search_term end end end @@ -342,19 +301,19 @@ RSpec.describe 'Filter issues', :js do describe 'filter issues by milestone' do context 'only milestone' do it 'filters issues by searched milestone' do - input_filtered_search("milestone:=%#{milestone.title}") + select_tokens 'Milestone', '=', milestone.title, submit: true - expect_tokens([milestone_token(milestone.title)]) + expect_milestone_token(milestone.title) expect_issues_list_count(5) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by no milestone' do - input_filtered_search("milestone:=none") + select_tokens 'Milestone', '=', 'None', submit: true - expect_tokens([milestone_token('None', false)]) + expect_milestone_token 'None' expect_issues_list_count(3) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by upcoming milestones' do @@ -362,11 +321,11 @@ RSpec.describe 'Filter issues', :js do create(:issue, project: project, milestone: future_milestone, author: user) end - input_filtered_search("milestone:=upcoming") + select_tokens 'Milestone', '=', 'Upcoming', submit: true - expect_tokens([milestone_token('Upcoming', false)]) + expect_milestone_token 'Upcoming' expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by negation of upcoming milestones' do @@ -378,72 +337,72 @@ RSpec.describe 'Filter issues', :js do create(:issue, project: project, milestone: past_milestone, author: user) end - input_filtered_search("milestone:!=upcoming") + select_tokens 'Milestone', '!=', 'Upcoming', submit: true - expect_tokens([milestone_token('Upcoming', false, '!=')]) + expect_negated_milestone_token 'Upcoming' expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by started milestones' do - input_filtered_search("milestone:=started") + select_tokens 'Milestone', '=', 'Started', submit: true - expect_tokens([milestone_token('Started', false)]) + expect_milestone_token 'Started' expect_issues_list_count(5) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by negation of started milestones' do milestone2 = create(:milestone, title: "9", project: project, start_date: 2.weeks.from_now) create(:issue, project: project, author: user, title: "something else", milestone: milestone2) - input_filtered_search("milestone:!=started") + select_tokens 'Milestone', '!=', 'Started', submit: true - expect_tokens([milestone_token('Started', false, '!=')]) + expect_negated_milestone_token 'Started' expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by milestone containing special characters' do special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project) create(:issue, project: project, milestone: special_milestone) - input_filtered_search("milestone:=%#{special_milestone.title}") + select_tokens 'Milestone', '=', special_milestone.title, submit: true - expect_tokens([milestone_token(special_milestone.title)]) + expect_milestone_token(special_milestone.title) expect_issues_list_count(1) - expect_filtered_search_input_empty + expect_empty_search_term end it 'filters issues by milestone not containing special characters' do special_milestone = create(:milestone, title: '!@\#{$%^&*()}', project: project) create(:issue, project: project, milestone: special_milestone) - input_filtered_search("milestone:!=%#{special_milestone.title}") + select_tokens 'Milestone', '!=', special_milestone.title, submit: true - expect_tokens([milestone_token(special_milestone.title, false, '!=')]) + expect_negated_milestone_token(special_milestone.title) expect_issues_list_count(8) - expect_filtered_search_input_empty + expect_empty_search_term end it 'does not show issues for unused milestones' do new_milestone = create(:milestone, title: 'new', project: project) - input_filtered_search("milestone:=%#{new_milestone.title}") + select_tokens 'Milestone', '=', new_milestone.title, submit: true - expect_tokens([milestone_token(new_milestone.title)]) + expect_milestone_token(new_milestone.title) expect_no_issues_list - expect_filtered_search_input_empty + expect_empty_search_term end it 'show issues for unused milestones' do new_milestone = create(:milestone, title: 'new', project: project) - input_filtered_search("milestone:!=%#{new_milestone.title}") + select_tokens 'Milestone', '!=', new_milestone.title, submit: true - expect_tokens([milestone_token(new_milestone.title, false, '!=')]) + expect_negated_milestone_token(new_milestone.title) expect_issues_list_count(8) - expect_filtered_search_input_empty + expect_empty_search_term end end end @@ -452,47 +411,47 @@ RSpec.describe 'Filter issues', :js do context 'only text' do it 'filters issues by searched text' do search = 'Bug' - input_filtered_search(search) + submit_search_term(search) expect_issues_list_count(4) - expect_filtered_search_input(search) + expect_search_term(search) end it 'filters issues by multiple searched text' do search = 'Bug report' - input_filtered_search(search) + submit_search_term(search) expect_issues_list_count(3) - expect_filtered_search_input(search) + expect_search_term(search) end it 'filters issues by case insensitive searched text' do search = 'bug report' - input_filtered_search(search) + submit_search_term(search) expect_issues_list_count(3) - expect_filtered_search_input(search) + expect_search_term(search) end it 'filters issues by searched text containing single quotes' do issue = create(:issue, project: project, author: user, title: "issue with 'single quotes'") - search = "'single quotes'" - input_filtered_search(search) + search = 'single quotes' + submit_search_term "'#{search}'" expect_issues_list_count(1) - expect_filtered_search_input(search) + expect_search_term(search) expect(page).to have_content(issue.title) end it 'filters issues by searched text containing double quotes' do issue = create(:issue, project: project, author: user, title: "issue with \"double quotes\"") - search = '"double quotes"' - input_filtered_search(search) + search = 'double quotes' + submit_search_term "\"#{search}\"" expect_issues_list_count(1) - expect_filtered_search_input(search) + expect_search_term(search) expect(page).to have_content(issue.title) end @@ -502,36 +461,43 @@ RSpec.describe 'Filter issues', :js do issue = create(:issue, project: project, author: user, title: "issue with !@\#{$%^&*()-+") search = '!@#{$%^&*()-+' - input_filtered_search(search) + submit_search_term(search) expect_issues_list_count(1) - expect_filtered_search_input(search) + expect_search_term(search) expect(page).to have_content(issue.title) end it 'does not show any issues' do search = 'testing' - input_filtered_search(search) + submit_search_term(search) expect_no_issues_list - expect_filtered_search_input(search) + expect_search_term(search) end it 'filters issues by issue reference' do search = '#1' - input_filtered_search(search) + submit_search_term(search) expect_issues_list_count(1) - expect_filtered_search_input(search) + expect_search_term(search) end end context 'searched text with other filters' do it 'filters issues by searched text, author, text, assignee, text, label1, text, label2, text, milestone and text' do - input_filtered_search("bug author:=@#{user.username} report label:=~#{bug_label.title} label:=~#{caps_sensitive_label.title} milestone:=%#{milestone.title} foo") + click_filtered_search_bar + send_keys 'bug ' + select_tokens 'Author', '=', user.username + send_keys 'report ' + select_tokens 'Label', '=', bug_label.title + select_tokens 'Label', '=', caps_sensitive_label.title + select_tokens 'Milestone', '=', milestone.title + send_keys 'foo', :enter expect_issues_list_count(1) - expect_filtered_search_input('bug report foo') + expect_search_term('bug report foo') end end @@ -549,17 +515,11 @@ RSpec.describe 'Filter issues', :js do author: user, created_at: 5.days.ago) - input_filtered_search('days ago') + submit_search_term 'days ago' expect_issues_list_count(2) - - sort_toggle = find('.filter-dropdown-container .dropdown') - sort_toggle.click - - find('.filter-dropdown-container .dropdown-menu li a', text: 'Created date').click - wait_for_requests - - expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(new_issue.title) + expect(page).to have_button 'Created date' + expect(page).to have_css('.issue:first-of-type .issue-title', text: new_issue.title) end end end @@ -568,7 +528,7 @@ RSpec.describe 'Filter issues', :js do let!(:closed_issue) { create(:issue, :closed, project: project, title: 'closed bug') } before do - input_filtered_search('bug') + submit_search_term 'bug' # This ensures that the search is performed expect_issues_list_count(4, 1) @@ -599,19 +559,17 @@ RSpec.describe 'Filter issues', :js do end it 'milestone dropdown loads milestones' do - input_filtered_search("milestone:=", submit: false) + select_tokens 'Milestone', '=' - within('#js-dropdown-milestone') do - expect(page).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) - end + # Expect None, Any, Upcoming, Started, 8 + expect_suggestion_count 5 end it 'label dropdown load labels' do - input_filtered_search("label:=", submit: false) + select_tokens 'Label', '=' - within('#js-dropdown-label') do - expect(page).to have_selector('.filter-dropdown .filter-dropdown-item', count: 3) - end + # Dropdown shows None, Any, and 3 labels + expect_suggestion_count 5 end end end diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb index 3929d3694ff..bb5964258be 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -4,7 +4,6 @@ require 'spec_helper' RSpec.describe 'Recent searches', :js do include FilteredSearchHelpers - include MobileHelpers let_it_be(:project_1) { create(:project, :public) } let_it_be(:project_2) { create(:project, :public) } @@ -14,116 +13,96 @@ RSpec.describe 'Recent searches', :js do let(:project_1_local_storage_key) { "#{project_1.full_path}-issue-recent-searches" } before do - Capybara.ignore_hidden_elements = false + stub_feature_flags(vue_issues_list: true) # Visit any fast-loading page so we can clear local storage without a DOM exception visit '/404' remove_recent_searches end - after do - Capybara.ignore_hidden_elements = true - end - it 'searching adds to recent searches' do visit project_issues_path(project_1) - input_filtered_search('foo', submit: true) - input_filtered_search('bar', submit: true) - - items = all('.filtered-search-history-dropdown-item', visible: false, count: 2) + submit_then_clear_search 'foo' + submit_then_clear_search 'bar' + click_button 'Toggle history' - expect(items[0].text).to eq('bar') - expect(items[1].text).to eq('foo') + expect_recent_searches_history_item 'bar' + expect_recent_searches_history_item 'foo' end it 'visiting URL with search params adds to recent searches' do visit project_issues_path(project_1, label_name: 'foo', search: 'bar') visit project_issues_path(project_1, label_name: 'qux', search: 'garply') - items = all('.filtered-search-history-dropdown-item', visible: false, count: 2) + click_button 'Toggle history' - expect(items[0].text).to eq('label: = ~qux garply') - expect(items[1].text).to eq('label: = ~foo bar') + expect_recent_searches_history_item 'Label := qux garply' + expect_recent_searches_history_item 'Label := foo bar' end it 'saved recent searches are restored last on the list' do - set_recent_searches(project_1_local_storage_key, '["saved1", "saved2"]') + set_recent_searches(project_1_local_storage_key, '[[{"type":"filtered-search-term","value":{"data":"saved1"}}],[{"type":"filtered-search-term","value":{"data":"saved2"}}]]') visit project_issues_path(project_1, search: 'foo') + click_button 'Toggle history' - items = all('.filtered-search-history-dropdown-item', visible: false, count: 3) - - expect(items[0].text).to eq('foo') - expect(items[1].text).to eq('saved1') - expect(items[2].text).to eq('saved2') + expect_recent_searches_history_item 'foo' + expect_recent_searches_history_item 'saved1' + expect_recent_searches_history_item 'saved2' end it 'searches are scoped to projects' do visit project_issues_path(project_1) - input_filtered_search('foo', submit: true) - input_filtered_search('bar', submit: true) + submit_then_clear_search 'foo' + submit_then_clear_search 'bar' visit project_issues_path(project_2) - input_filtered_search('more', submit: true) - input_filtered_search('things', submit: true) - - items = all('.filtered-search-history-dropdown-item', visible: false, count: 2) + submit_then_clear_search 'more' + submit_then_clear_search 'things' + click_button 'Toggle history' - expect(items[0].text).to eq('things') - expect(items[1].text).to eq('more') + expect_recent_searches_history_item 'things' + expect_recent_searches_history_item 'more' end it 'clicking item fills search input' do - set_recent_searches(project_1_local_storage_key, '["foo", "bar"]') + set_recent_searches(project_1_local_storage_key, '[[{"type":"filtered-search-term","value":{"data":"foo"}}],[{"type":"filtered-search-term","value":{"data":"bar"}}]]') visit project_issues_path(project_1) - find('.filtered-search-history-dropdown-toggle-button').click - all('.filtered-search-history-dropdown-item', count: 2)[0].click - wait_for_filtered_search('foo') + click_button 'Toggle history' + click_button 'foo' - expect(find('.filtered-search').value.strip).to eq('foo') + expect_search_term 'foo' end it 'clear recent searches button, clears recent searches' do - set_recent_searches(project_1_local_storage_key, '["foo"]') + set_recent_searches(project_1_local_storage_key, '[[{"type":"filtered-search-term","value":{"data":"foo"}}]]') visit project_issues_path(project_1) - find('.filtered-search-history-dropdown-toggle-button').click - all('.filtered-search-history-dropdown-item', count: 1) + click_button 'Toggle history' - find('.filtered-search-history-clear-button').click - items_after = all('.filtered-search-history-dropdown-item', count: 0) + expect_recent_searches_history_item_count 1 - expect(items_after.count).to eq(0) + click_button 'Clear recent searches' + click_button 'Toggle history' + + expect(page).to have_text "You don't have any recent searches" + expect_recent_searches_history_item_count 0 end it 'shows flash error when failed to parse saved history' do set_recent_searches(project_1_local_storage_key, 'fail') visit project_issues_path(project_1) - expect(find('[data-testid="alert-danger"]')).to have_text('An error occurred while parsing recent searches') + expect(page).to have_text 'An error occurred while parsing recent searches' end - context 'on tablet/mobile screen' do - it 'shows only the history icon in the dropdown' do - resize_screen_sm - visit project_issues_path(project_1) - - expect(find('.filtered-search-history-dropdown-wrapper')).to have_selector('svg', visible: true) - expect(find('.filtered-search-history-dropdown-wrapper')).to have_selector('span', text: 'Recent searches', visible: false) - end - end - - context 'on PC screen' do - it 'shows only the Recent searches text in the dropdown' do - restore_window_size - visit project_issues_path(project_1) - - expect(find('.filtered-search-history-dropdown-wrapper')).to have_selector('svg', visible: false) - expect(find('.filtered-search-history-dropdown-wrapper')).to have_selector('span', text: 'Recent searches', visible: true) - end + def submit_then_clear_search(search) + click_filtered_search_bar + send_keys(search, :enter) + click_button 'Clear' end end diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 60963d95ae5..8639ec2a227 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -9,102 +9,74 @@ RSpec.describe 'Search bar', :js do let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - before do + stub_feature_flags(vue_issues_list: true) project.add_maintainer(user) sign_in(user) visit project_issues_path(project) end - def get_left_style(style) - left_style = /left:\s\d*[.]\d*px/.match(style) - left_style.to_s.gsub('left: ', '').to_f - end - describe 'keyboard navigation' do - it 'makes item active' do - filtered_search.native.send_keys(:down) - - page.within '#js-dropdown-hint' do - expect(page).to have_selector('.droplab-item-active') - end - end - it 'selects item' do - filtered_search.native.send_keys(:down, :down, :enter) + click_filtered_search_bar + send_keys :down, :enter - expect_tokens([{ name: 'Assignee' }]) - expect_filtered_search_input_empty + expect_token_segment 'Assignee' end end describe 'clear search button' do it 'clears text' do search_text = 'search_text' - filtered_search.set(search_text) + click_filtered_search_bar + send_keys search_text + + expect(page).to have_field 'Search', with: search_text - expect(filtered_search.value).to eq(search_text) - find('.filtered-search-box .clear-search').click + click_button 'Clear' - expect(filtered_search.value).to eq('') + expect(page).to have_field 'Search', with: '' end it 'hides by default' do - expect(page).to have_css('.clear-search', visible: false) + expect(page).not_to have_button 'Clear' end it 'hides after clicked' do - filtered_search.set('a') - find('.filtered-search-box .clear-search').click + click_filtered_search_bar + send_keys 'a' - expect(page).to have_css('.clear-search', visible: false) + click_button 'Clear' + + expect(page).not_to have_button 'Clear' end it 'hides when there is no text' do - filtered_search.set('a') - filtered_search.set('') + click_filtered_search_bar + send_keys 'a', :backspace, :backspace - expect(page).to have_css('.clear-search', visible: false) + expect(page).not_to have_button 'Clear' end it 'shows when there is text' do - filtered_search.set('a') + click_filtered_search_bar + send_keys 'a' - expect(page).to have_css('.clear-search', visible: true) + expect(page).to have_button 'Clear' end it 'resets the dropdown hint filter' do - filtered_search.click - original_size = page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size - - filtered_search.set('autho') - - expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) - - find('.filtered-search-box .clear-search').click - filtered_search.click - - expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size) - end - - it 'resets the dropdown filters' do - filtered_search.click - - hint_offset = get_left_style(find('#js-dropdown-hint')['style']) - - filtered_search.set('a') - - filtered_search.set('author:') + click_filtered_search_bar + original_size = get_suggestion_count + send_keys 'autho' - find('#js-dropdown-hint', visible: false) + expect_suggestion_count 1 - find('.filtered-search-box .clear-search').click - filtered_search.click + click_button 'Clear' + click_filtered_search_bar - expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', minimum: 6) - expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset) + expect_suggestion_count(original_size) end end end diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb index 2d8587d886f..9fb6a4cc2af 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -14,178 +14,160 @@ RSpec.describe 'Visual tokens', :js do let_it_be(:cc_label) { create(:label, project: project, title: 'Community Contribution') } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - let(:filter_author_dropdown) { find("#js-dropdown-author .filter-dropdown") } - - def is_input_focused - page.evaluate_script("document.activeElement.classList.contains('filtered-search')") - end - before do + stub_feature_flags(vue_issues_list: true) project.add_user(user, :maintainer) project.add_user(user_rock, :maintainer) sign_in(user) - set_cookie('sidebar_collapsed', 'true') - visit project_issues_path(project) end describe 'editing a single token' do before do - input_filtered_search('author:=@root assignee:=none', submit: false) - first('.tokens-container .filtered-search-token').click - wait_for_requests + select_tokens 'Author', '=', user.username, 'Assignee', '=', 'None' + click_token_segment(user.name) end it 'opens author dropdown' do - expect(page).to have_css('#js-dropdown-author', visible: true) - expect_filtered_search_input('@root') + expect_visible_suggestions_list + expect(page).to have_field('Search', with: 'root') end it 'filters value' do - filtered_search.send_keys(:backspace) + send_keys :backspace - expect(page).to have_css('#js-dropdown-author .filter-dropdown .filter-dropdown-item', count: 1) + expect_suggestion_count 1 end it 'ends editing mode when document is clicked' do find('.js-navbar').click - expect_filtered_search_input_empty - expect(page).to have_css('#js-dropdown-author', visible: false) + expect_empty_search_term + expect_hidden_suggestions_list end describe 'selecting different author from dropdown' do before do - filter_author_dropdown.find('.filter-dropdown-item .dropdown-light-content', text: "@#{user_rock.username}").click + send_keys :backspace, :backspace, :backspace, :backspace + click_on user_rock.name end it 'changes value in visual token' do - wait_for_requests - expect(first('.tokens-container .filtered-search-token .value').text).to eq("#{user_rock.name}") - end - - it 'moves input to the right' do - expect(is_input_focused).to eq(true) + expect_author_token(user_rock.name) end end end describe 'editing multiple tokens' do before do - input_filtered_search('author:=@root assignee:=none', submit: false) - first('.tokens-container .filtered-search-token').click + select_tokens 'Author', '=', user.username, 'Assignee', '=', 'None' + click_token_segment(user.name) end it 'opens author dropdown' do - expect(page).to have_css('#js-dropdown-author', visible: true) + expect_visible_suggestions_list end it 'opens assignee dropdown' do - find('.tokens-container .filtered-search-token', text: 'Assignee').click - expect(page).to have_css('#js-dropdown-assignee', visible: true) + click_token_segment 'Assignee' + + expect_visible_suggestions_list end end describe 'editing a search term while editing another filter token' do before do - input_filtered_search('foo assignee:=', submit: false) - first('.tokens-container .filtered-search-term').click + click_filtered_search_bar + send_keys 'foo ' + select_tokens 'Assignee', '=' + click_token_segment 'foo' + send_keys ' ' end it 'opens author dropdown' do - find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: 'Author').click + click_on 'Author' - expect(page).to have_css('#js-dropdown-operator', visible: true) - expect(page).to have_css('#js-dropdown-author', visible: false) + expect_suggestion '=' + expect_suggestion '!=' - find('#js-dropdown-operator .filter-dropdown .filter-dropdown-item[data-value="="]').click + click_on '= is' - expect(page).to have_css('#js-dropdown-operator', visible: false) - expect(page).to have_css('#js-dropdown-author', visible: true) + expect_suggestion(user.name) + expect_suggestion(user_rock.name) end end describe 'add new token after editing existing token' do before do - input_filtered_search('author:=@root assignee:=none', submit: false) - first('.tokens-container .filtered-search-token').click - filtered_search.send_keys(' ') + select_tokens 'Assignee', '=', user.username, 'Label', '=', 'None' + click_token_segment(user.name) + send_keys ' ' end describe 'opens dropdowns' do it 'opens hint dropdown' do - expect(page).to have_css('#js-dropdown-hint', visible: true) + expect_visible_suggestions_list end it 'opens token dropdown' do - filtered_search.send_keys('author:=') + click_on 'Author' - expect(page).to have_css('#js-dropdown-author', visible: true) + expect_visible_suggestions_list end end describe 'visual tokens' do it 'creates visual token' do - filtered_search.send_keys('author:=@thomas ') - token = page.all('.tokens-container .filtered-search-token')[1] + click_on 'Author' + click_on '= is' + click_on 'The Rock' - expect(token.find('.name').text).to eq('Author') - expect(token.find('.value').text).to eq('@thomas') + expect_author_token 'The Rock' end end it 'does not tokenize incomplete token' do - filtered_search.send_keys('author:=') - + click_on 'Author' find('.js-navbar').click - token = page.all('.tokens-container .js-visual-token')[1] - expect_filtered_search_input_empty - expect(token.find('.name').text).to eq('Author') + expect_empty_search_term + expect_token_segment 'Assignee' end end describe 'search using incomplete visual tokens' do before do - input_filtered_search('author:=@root assignee:=none', extra_space: false) + select_tokens 'Author', '=', user.username, 'Assignee', '=', 'None' end it 'tokenizes the search term to complete visual token' do - expect_tokens([ - author_token(user.name), - assignee_token('None') - ]) + expect_author_token(user.name) + expect_assignee_token 'None' end end it 'does retain hint token when mix of typing and clicks are performed' do - input_filtered_search('label:', extra_space: false, submit: false) - - expect(page).to have_css('#js-dropdown-operator', visible: true) - - find('#js-dropdown-operator li[data-value="="]').click - - token = page.all('.tokens-container .js-visual-token')[0] + select_tokens 'Label' + click_on '= is' - expect(token.find('.name').text).to eq('Label') - expect(token.find('.operator').text).to eq('=') + expect_token_segment 'Label' + expect_token_segment '=' end describe 'Any/None option' do it 'hidden when NOT operator is selected' do - input_filtered_search('milestone:!=', extra_space: false, submit: false) + select_tokens 'Milestone', '!=' - expect(page).not_to have_selector("#js-dropdown-milestone", text: 'Any') - expect(page).not_to have_selector("#js-dropdown-milestone", text: 'None') + expect_no_suggestion 'Any' + expect_no_suggestion 'None' end it 'shown when EQUAL operator is selected' do - input_filtered_search('milestone:=', extra_space: false, submit: false) + select_tokens 'Milestone', '=' - expect(page).to have_selector("#js-dropdown-milestone", text: 'Any') - expect(page).to have_selector("#js-dropdown-milestone", text: 'None') + expect_suggestion 'Any' + expect_suggestion 'None' end end end diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 6f4a13c5fad..8732e2ecff2 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -445,7 +445,7 @@ RSpec.describe 'GFM autocomplete', :js do click_button('Cancel') page.within('.modal') do - click_button('OK', match: :first) + click_button('Discard changes', match: :first) end wait_for_requests diff --git a/spec/features/issues/rss_spec.rb b/spec/features/issues/rss_spec.rb index b20502ecc25..bdc5f282875 100644 --- a/spec/features/issues/rss_spec.rb +++ b/spec/features/issues/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Project Issues RSS' do +RSpec.describe 'Project Issues RSS', :js do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } @@ -13,6 +13,10 @@ RSpec.describe 'Project Issues RSS' do group.add_developer(user) end + before do + stub_feature_flags(vue_issues_list: true) + end + context 'when signed in' do let_it_be(:user) { create(:user) } @@ -25,7 +29,10 @@ RSpec.describe 'Project Issues RSS' do visit path end - it_behaves_like "it has an RSS button with current_user's feed token" + it "shows the RSS button with current_user's feed token" do + expect(page).to have_link 'Subscribe to RSS feed', href: /feed_token=#{user.feed_token}/ + end + it_behaves_like "an autodiscoverable RSS feed with current_user's feed token" end @@ -34,7 +41,10 @@ RSpec.describe 'Project Issues RSS' do visit path end - it_behaves_like "it has an RSS button without a feed token" + it "shows the RSS button without a feed token" do + expect(page).not_to have_link 'Subscribe to RSS feed', href: /feed_token/ + end + it_behaves_like "an autodiscoverable RSS feed without a feed token" end diff --git a/spec/features/issues/user_bulk_edits_issues_labels_spec.rb b/spec/features/issues/user_bulk_edits_issues_labels_spec.rb index 71213fb661f..27377f6e1fd 100644 --- a/spec/features/issues/user_bulk_edits_issues_labels_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_labels_spec.rb @@ -12,8 +12,12 @@ RSpec.describe 'Issues > Labels bulk assignment' do let!(:issue1) { create(:issue, project: project, title: "Issue 1", labels: [frontend]) } let!(:issue2) { create(:issue, project: project, title: "Issue 2") } - let(:issue_1_selector) { "#issue_#{issue1.id}" } - let(:issue_2_selector) { "#issue_#{issue2.id}" } + let(:issue_1_selector) { "#issuable_#{issue1.id}" } + let(:issue_2_selector) { "#issuable_#{issue2.id}" } + + before do + stub_feature_flags(vue_issues_list: true) + end context 'as an allowed user', :js do before do diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb index ae1bce7ea4c..1c707466b51 100644 --- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb +++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb @@ -25,6 +25,20 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do sign_in(user) end + context 'when ’Create merge request’ button is clicked' do + before do + visit project_issue_path(project, issue) + + wait_for_requests + + click_button('Create merge request') + + wait_for_requests + end + + it_behaves_like 'merge request author auto assign' + end + context 'when interacting with the dropdown' do before do visit project_issue_path(project, issue) diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index 8a5e33ba18c..3bba041dab7 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -8,12 +8,16 @@ RSpec.describe "User creates issue" do let_it_be(:project) { create(:project_empty_repo, :public) } let_it_be(:user) { create(:user) } + before do + stub_feature_flags(vue_issues_list: true) + end + context "when unauthenticated" do before do sign_out(:user) end - it "redirects to signin then back to new issue after signin" do + it "redirects to signin then back to new issue after signin", :js do create(:issue, project: project) visit project_issues_path(project) diff --git a/spec/features/issues/user_filters_issues_spec.rb b/spec/features/issues/user_filters_issues_spec.rb index 5d05df6aaf0..42c2b5d32c1 100644 --- a/spec/features/issues/user_filters_issues_spec.rb +++ b/spec/features/issues/user_filters_issues_spec.rb @@ -7,6 +7,8 @@ RSpec.describe 'User filters issues', :js do let_it_be(:project) { create(:project_empty_repo, :public) } before do + stub_feature_flags(vue_issues_list: true) + %w[foobar barbaz].each do |title| create(:issue, author: user, @@ -24,7 +26,7 @@ RSpec.describe 'User filters issues', :js do let(:issue) { @issue } it 'allows filtering by issues with no specified assignee' do - visit project_issues_path(project, assignee_id: IssuableFinder::Params::FILTER_NONE) + visit project_issues_path(project, assignee_id: IssuableFinder::Params::FILTER_NONE.capitalize) expect(page).to have_content 'foobar' expect(page).not_to have_content 'barbaz' diff --git a/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb b/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb index 1fa8f533869..5aae5abaf10 100644 --- a/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb +++ b/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb @@ -10,6 +10,7 @@ RSpec.describe 'User scrolls to deep-linked note' do context 'on issue page', :js do it 'on comment' do + stub_feature_flags(gl_avatar_for_all_user_avatars: false) visit project_issue_path(project, issue, anchor: "note_#{comment_1.id}") wait_for_requests diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb index 669c7c45411..1577d7d5ce8 100644 --- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb +++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb @@ -8,6 +8,8 @@ RSpec.describe 'New issue breadcrumb' do let(:user) { project.creator } before do + stub_feature_flags(vue_issues_list: true) + sign_in(user) visit(new_project_issue_path(project)) end @@ -24,10 +26,10 @@ RSpec.describe 'New issue breadcrumb' do visit project_issue_path(project, issue) - expect(find('.breadcrumbs-sub-title a')[:href]).to end_with(issue_path(issue)) + expect(find('[data-testid="breadcrumb-current-link"] a')[:href]).to end_with(issue_path(issue)) end - it 'excludes award_emoji from comment count' do + it 'excludes award_emoji from comment count', :js do issue = create(:issue, author: user, assignees: [user], project: project, title: 'foobar') create(:award_emoji, awardable: issue) diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb index 86bdaf5d706..4af313576ed 100644 --- a/spec/features/issues/user_sorts_issues_spec.rb +++ b/spec/features/issues/user_sorts_issues_spec.rb @@ -16,6 +16,8 @@ RSpec.describe "User sorts issues" do let_it_be(:later_due_milestone) { create(:milestone, project: project, due_date: '2013-12-12') } before do + stub_feature_flags(vue_issues_list: true) + create_list(:award_emoji, 2, :upvote, awardable: issue1) create_list(:award_emoji, 2, :downvote, awardable: issue2) create(:award_emoji, :downvote, awardable: issue1) @@ -24,26 +26,23 @@ RSpec.describe "User sorts issues" do sign_in(user) end - it 'keeps the sort option' do + it 'keeps the sort option', :js do visit(project_issues_path(project)) - find('.filter-dropdown-container .dropdown').click - - page.within('ul.dropdown-menu.dropdown-menu-right li') do - click_link('Milestone') - end + click_button 'Created date' + click_button 'Milestone' visit(issues_dashboard_path(assignee_username: user.username)) - expect(find('.issues-filters a.is-active')).to have_content('Milestone') + expect(page).to have_button 'Milestone' visit(project_issues_path(project)) - expect(find('.issues-filters a.is-active')).to have_content('Milestone') + expect(page).to have_button 'Milestone' visit(issues_group_path(group)) - expect(find('.issues-filters a.is-active')).to have_content('Milestone') + expect(page).to have_button 'Milestone' end it 'sorts by popularity', :js do |