diff --git a/ee/spec/controllers/ee/groups_controller_spec.rb b/ee/spec/controllers/ee/groups_controller_spec.rb index 46224e1ff6aaa26a16fd811602bb79e42c61aece..8eb9243372b1bffab1b3e4aac44f57c14a2d3514 100644 --- a/ee/spec/controllers/ee/groups_controller_spec.rb +++ b/ee/spec/controllers/ee/groups_controller_spec.rb @@ -20,18 +20,6 @@ it_behaves_like 'namespace storage limit alert' end - describe 'GET #issues' do - it 'does not list test cases' do - issue = create(:issue, project: project, title: 'foo') - incident = create(:incident, project: project) - create(:quality_test_case, project: project) - - get :issues, params: { id: group.to_param } - - expect(assigns(:issues)).to match_array([issue, incident]) - end - end - describe 'GET #activity' do render_views diff --git a/ee/spec/controllers/projects/issues_controller_spec.rb b/ee/spec/controllers/projects/issues_controller_spec.rb index d75f20b39b07285a44a1c407f116b45ed4a1220f..f695ca6c64774d6ae3890547e177c2956380f7c2 100644 --- a/ee/spec/controllers/projects/issues_controller_spec.rb +++ b/ee/spec/controllers/projects/issues_controller_spec.rb @@ -29,27 +29,6 @@ def perform(method, action, opts = {}) stub_licensed_features(issue_weights: true, epics: true, security_dashboard: true, issuable_default_templates: true) end - describe '#index' do - it 'allows sorting by weight' do - expected = [issue, issue2].sort_by(&:weight) - - perform :get, :index, sort: 'weight' - - expect(response).to have_gitlab_http_status(:ok) - expect(assigns(:issues)).to eq(expected) - end - - it 'allows filtering by weight' do - _ = issue - _ = issue2 - - perform :get, :index, weight: 1 - - expect(response).to have_gitlab_http_status(:ok) - expect(assigns(:issues)).to eq([issue2]) - end - end - describe '#update' do it 'sets issue weight and epic' do perform :put, :update, id: issue.to_param, issue: { weight: 6, epic_id: epic.id }, format: :json @@ -190,17 +169,6 @@ def send_request stub_licensed_features(issue_weights: false, epics: false, security_dashboard: false) end - describe '#index' do - it 'ignores filtering by weight' do - expected = [issue, issue2] - - perform :get, :index, weight: 1 - - expect(response).to have_gitlab_http_status(:ok) - expect(assigns(:issues)).to match_array(expected) - end - end - describe '#update' do it 'does not set issue weight' do perform :put, :update, id: issue.to_param, issue: { weight: 6 }, format: :json diff --git a/ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb b/ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb index 0087496bbcf762126db4c0fbd089b8666362ee92..f17b50ceb6a7c00675b58ba1e342eeb8e6073e86 100644 --- a/ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb +++ b/ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb @@ -19,32 +19,24 @@ let_it_be(:iteration_2_issue) { create(:issue, project: project, iteration: iteration_2) } let_it_be(:no_iteration_issue) { create(:issue, project: project) } - let(:filter_input) { find('.gl-filtered-search-term-input')} - let(:filter_first_suggestion) { find('.gl-filtered-search-suggestion-list').first('.gl-filtered-search-suggestion') } - let(:filter_submit) { find('.gl-search-box-by-click-search-button') } - shared_examples 'filters by iteration' do context 'when iterations are not available' do before do stub_licensed_features(iterations: false) - stub_feature_flags(vue_issues_list: true) visit page_path end it 'does not show the iteration filter option' do - filter_input.click + click_empty_filtered_search_bar - page.within('.gl-filtered-search-suggestion-list') do - expect(page).not_to have_content('Iteration') - end + expect_no_suggestion('Iteration') end end context 'when iterations are available' do before do stub_licensed_features(iterations: true) - stub_feature_flags(vue_issues_list: true) visit page_path @@ -75,7 +67,7 @@ context 'when passing specific iteration by period' do before do - set_filter('iteration', iteration_1.period) + select_tokens 'Iteration', '=', iteration_1.period end it_behaves_like 'filters issues by iteration' @@ -83,7 +75,7 @@ context 'when passing Current iteration' do before do - set_filter('iteration', 'Current') + select_tokens 'Iteration', '=', 'Current' end it_behaves_like 'filters issues by iteration' @@ -93,7 +85,7 @@ before do visit page_path - set_negated_filter('iteration', iteration_item) + select_tokens 'Iteration', '!=', iteration_item end context 'with specific iteration' do @@ -114,8 +106,6 @@ shared_examples 'shows iterations when using iteration token' do context 'when viewing list of iterations' do before do - stub_feature_flags(vue_issues_list: true) - visit page_path find_field('Search or filter results...').click @@ -182,20 +172,4 @@ it_behaves_like 'filters by iteration' end - - def set_filter(type, filter_value) - filter_input.click - filter_input.set("#{type}:") - filter_first_suggestion.click # Select `=` operator - click_on filter_value - filter_submit.click - end - - def set_negated_filter(type, filter_value) - filter_input.click - filter_input.set("#{type}:") - click_on '!=' - click_on filter_value - filter_submit.click - end end diff --git a/ee/spec/features/issues/filtered_search/filter_issues_by_multiple_assignees_spec.rb b/ee/spec/features/issues/filtered_search/filter_issues_by_multiple_assignees_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..adfe7792a0c5a6a6f3f98795f9aac67c8bb8c327 --- /dev/null +++ b/ee/spec/features/issues/filtered_search/filter_issues_by_multiple_assignees_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Filter issues by multiple assignees', :js do + include FilteredSearchHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:user2) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:issue) { create(:issue, project: project, author: user, assignees: [user2, user]) } + + before do + project.add_maintainer(user) + project.add_developer(user2) + + sign_in(user) + visit project_issues_path(project) + end + + it 'filters issues by multiple assignees' do + select_tokens 'Assignee', '=', user.username, 'Assignee', '=', user2.username + + expect_assignee_token(user.name) + expect_assignee_token(user2.name) + expect_empty_search_term + + expect_issues_list_count(1) + end +end diff --git a/ee/spec/features/issues/filtered_search/filter_issues_epic_spec.rb b/ee/spec/features/issues/filtered_search/filter_issues_epic_spec.rb index 1f535962e6273a815e6fc66a6577c4a799c3597f..d16ea850d6650176f76ca7b47a8069e36991a362 100644 --- a/ee/spec/features/issues/filtered_search/filter_issues_epic_spec.rb +++ b/ee/spec/features/issues/filtered_search/filter_issues_epic_spec.rb @@ -17,8 +17,6 @@ let_it_be(:epic_issue2) { create(:epic_issue, issue: issue2, epic: epic2) } let_it_be(:epic_issue3) { create(:epic_issue, issue: issue3, epic: epic2) } - let(:filter_dropdown) { find("#js-dropdown-epic .filter-dropdown") } - before do stub_licensed_features(epics: true) group.add_maintainer(user) @@ -28,28 +26,29 @@ shared_examples 'filter issues by epic' do it 'filters issues by epic' do - input_filtered_search("epic:=&#{epic1.id}") + select_tokens 'Epic', '=', epic1.title expect_issues_list_count(1) end it 'filters issues by negated epic' do - input_filtered_search("epic:!=&#{epic1.id}") + select_tokens 'Epic', '!=', epic1.title expect_issues_list_count(2) end it 'shows epics in the filtered search dropdown' do - input_filtered_search('epic:=', submit: false, extra_space: false) + select_tokens 'Epic', '=', submit: false - expect_filtered_search_dropdown_results(filter_dropdown, 2) + # Expect None, Any, My title 5, My title 4 + expect_filtered_search_suggestion_count(4) end it 'shows correct filtered search epic token value' do - input_filtered_search('epic:=', submit: false, extra_space: false) + select_tokens 'Epic', '=', submit: false click_on epic1.title - expect(find('.filtered-search-token .value').text).to eq("\"#{epic1.title}\"::&#{epic1.id}") + expect_epic_token("&#{epic1.id}::#{epic1.title}") end end diff --git a/ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb b/ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb index c9c2b6ffbe9c738cfff262a77ee2213e230ad34c..e612c35d6d43ea3a66a538abf145a6505ffde562 100644 --- a/ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb +++ b/ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb @@ -12,8 +12,6 @@ let_it_be(:issue1) { create(:issue, project: project, weight: 1) } let_it_be(:issue2) { create(:issue, project: project, weight: 2, title: 'Bug report 1', milestone: milestone, author: user, assignees: [user], labels: [label]) } - let(:filter_dropdown) { find("#js-dropdown-weight .filter-dropdown") } - def expect_issues_list_count(open_count, closed_count = 0) all_count = open_count + closed_count @@ -32,25 +30,24 @@ def expect_issues_list_count(open_count, closed_count = 0) describe 'behavior' do it 'loads all the weights when opened' do - input_filtered_search('weight:=', submit: false, extra_space: false) + select_tokens 'Weight', '=', submit: false - expect_filtered_search_dropdown_results(filter_dropdown, 21) + # Expect None, Any, numbers 0 to 20 + expect_filtered_search_suggestion_count 23 end end describe 'only weight' do it 'filter issues by searched weight' do - input_filtered_search('weight:=1') + select_tokens 'Weight', '=', '1' expect_issues_list_count(1) end end describe 'negated weight only' do - let(:search) { 'weight:!=2' } - it 'excludes issues with specified weight' do - input_filtered_search(search) + select_tokens 'Weight', '!=', '2' expect_issues_list_count(1) end @@ -58,43 +55,43 @@ def expect_issues_list_count(open_count, closed_count = 0) describe 'weight with other filters' do it 'filters issues by searched weight and text' do - search = "weight:=2 bug" - input_filtered_search(search) + select_tokens 'Weight', '=', issue2.weight, submit: false + send_keys('bug', :enter) expect_issues_list_count(1) - expect_filtered_search_input('bug') + expect_search_term('bug') end it 'filters issues by searched weight, author and text' do - search = "weight:=2 author:=@root bug" - input_filtered_search(search) + select_tokens 'Weight', '=', '2', 'Author', '=', user.username, submit: false + send_keys('bug', :enter) expect_issues_list_count(1) - expect_filtered_search_input('bug') + expect_search_term('bug') end it 'filters issues by searched weight, author, assignee and text' do - search = "weight:=2 author:=@root assignee:=@root bug" - input_filtered_search(search) + select_tokens 'Weight', '=', '2', 'Author', '=', user.username, 'Assignee', '=', user.username, submit: false + send_keys('bug', :enter) expect_issues_list_count(1) - expect_filtered_search_input('bug') + expect_search_term('bug') end it 'filters issues by searched weight, author, assignee, label and text' do - search = "weight:=2 author:=@root assignee:=@root label:=~urgent bug" - input_filtered_search(search) + select_tokens 'Weight', '=', '2', 'Author', '=', user.username, 'Assignee', '=', user.username, 'Label', '=', label.title, submit: false + send_keys('bug', :enter) expect_issues_list_count(1) - expect_filtered_search_input('bug') + expect_search_term('bug') end it 'filters issues by searched weight, milestone and text' do - search = "weight:=2 milestone:=%version1 bug" - input_filtered_search(search) + select_tokens 'Weight', '=', '2', 'Milestone', '=', milestone.title, submit: false + send_keys('bug', :enter) expect_issues_list_count(1) - expect_filtered_search_input('bug') + expect_search_term('bug') end end end diff --git a/ee/spec/features/issues/user_sees_empty_state_spec.rb b/ee/spec/features/issues/user_sees_empty_state_spec.rb index 18ab480290dbf9b92032c9ad947f475e20d3bdfa..54de00b75dfb18dd17217f7ee6f3092535074b1f 100644 --- a/ee/spec/features/issues/user_sees_empty_state_spec.rb +++ b/ee/spec/features/issues/user_sees_empty_state_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Issues' do +RSpec.describe 'Issues', :js do let_it_be(:project) { create(:project, :public) } let_it_be(:auditor) { create(:user, auditor: true) } diff --git a/ee/spec/features/issues/user_views_issues_spec.rb b/ee/spec/features/issues/user_views_issues_spec.rb index 4d7f1fc7fc1fe90707da9706731cb840b44f2a32..4c9262141657a5201b49315724cf63a915c25351 100644 --- a/ee/spec/features/issues/user_views_issues_spec.rb +++ b/ee/spec/features/issues/user_views_issues_spec.rb @@ -10,6 +10,7 @@ let_it_be(:issue3) { create(:issue, project: project, health_status: 'at_risk') } before do + stub_licensed_features(blocked_issues: true, issuable_health_status: true, issue_weights: true) sign_in(user) visit project_issues_path(project) end diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index a82c5681911ba93ffd57cc059722353192f90f05..86eaf186d06cc12592836ef07d871c7d348fbb25 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -466,51 +466,6 @@ end end - describe 'GET #issues', :sidekiq_might_not_need_inline do - let_it_be(:issue_1) { create(:issue, project: project, title: 'foo') } - let_it_be(:issue_2) { create(:issue, project: project, title: 'bar') } - - before do - create_list(:award_emoji, 3, awardable: issue_2) - create_list(:award_emoji, 2, awardable: issue_1) - create_list(:award_emoji, 2, :downvote, awardable: issue_2) - - sign_in(user) - end - - context 'sorting by votes' do - it 'sorts most popular issues' do - get :issues, params: { id: group.to_param, sort: 'upvotes_desc' } - expect(assigns(:issues)).to eq [issue_2, issue_1] - end - - it 'sorts least popular issues' do - get :issues, params: { id: group.to_param, sort: 'downvotes_desc' } - expect(assigns(:issues)).to eq [issue_2, issue_1] - end - end - - context 'searching' do - it 'works with popularity sort' do - get :issues, params: { id: group.to_param, search: 'foo', sort: 'popularity' } - - expect(assigns(:issues)).to eq([issue_1]) - end - - it 'works with priority sort' do - get :issues, params: { id: group.to_param, search: 'foo', sort: 'priority' } - - expect(assigns(:issues)).to eq([issue_1]) - end - - it 'works with label priority sort' do - get :issues, params: { id: group.to_param, search: 'foo', sort: 'label_priority' } - - expect(assigns(:issues)).to eq([issue_1]) - end - end - end - describe 'GET #merge_requests', :sidekiq_might_not_need_inline do let(:merge_request_1) { create(:merge_request, source_project: project) } let(:merge_request_2) { create(:merge_request, :simple, source_project: project) } diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 9d3711d8a96f638c02d64ad6dee4524b307416f2..8d1a8483861a0dab011b39f2daed79e6dd5e4070 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -72,42 +72,12 @@ project.add_developer(user) end - context 'when issues_full_text_search is disabled' do - before do - stub_feature_flags(issues_full_text_search: false) - end - - it_behaves_like 'issuables list meta-data', :issue - end - - context 'when issues_full_text_search is enabled' do - before do - stub_feature_flags(issues_full_text_search: true) - end - - it_behaves_like 'issuables list meta-data', :issue - end - - it_behaves_like 'set sort order from user preference' do - let(:sorting_param) { 'updated_asc' } - end - it "returns index" do get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to have_gitlab_http_status(:ok) end - it 'returns only list type issues' do - issue = create(:issue, project: project) - incident = create(:issue, project: project, issue_type: 'incident') - create(:issue, project: project, issue_type: 'test_case') - - get :index, params: { namespace_id: project.namespace, project_id: project } - - expect(assigns(:issues)).to contain_exactly(issue, incident) - end - it "returns 301 if request path doesn't match project path" do get :index, params: { namespace_id: project.namespace, project_id: project.path.upcase } @@ -123,72 +93,6 @@ end end - it_behaves_like 'issuable list with anonymous search disabled' do - let(:params) { { namespace_id: project.namespace, project_id: project } } - - before do - project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - end - end - - it_behaves_like 'paginated collection' do - let!(:issue_list) { create_list(:issue, 2, project: project) } - let(:collection) { project.issues } - let(:params) do - { - namespace_id: project.namespace.to_param, - project_id: project, - state: 'opened' - } - end - - before do - sign_in(user) - project.add_developer(user) - allow(Kaminari.config).to receive(:default_per_page).and_return(1) - end - - it 'does not use pagination if disabled' do - allow(controller).to receive(:pagination_disabled?).and_return(true) - - get :index, params: params.merge(page: last_page + 1) - - expect(response).to have_gitlab_http_status(:ok) - expect(assigns(:issues).size).to eq(2) - end - end - - context 'with relative_position sorting' do - let!(:issue_list) { create_list(:issue, 2, project: project) } - - before do - sign_in(user) - project.add_developer(user) - allow(Kaminari.config).to receive(:default_per_page).and_return(1) - end - - it 'overrides the number allowed on the page' do - get :index, - params: { - namespace_id: project.namespace.to_param, - project_id: project, - sort: 'relative_position' - } - - expect(assigns(:issues).count).to eq 2 - end - - it 'allows the default number on the page' do - get :index, - params: { - namespace_id: project.namespace.to_param, - project_id: project - } - - expect(assigns(:issues).count).to eq 1 - end - end - context 'external authorization' do before do sign_in user @@ -739,84 +643,6 @@ def go(id:) let_it_be(:unescaped_parameter_value) { create(:issue, :confidential, project: project, author: author) } let_it_be(:request_forgery_timing_attack) { create(:issue, :confidential, project: project, assignees: [assignee]) } - describe 'GET #index' do - it 'does not list confidential issues for guests' do - sign_out(:user) - get_issues - - expect(assigns(:issues)).to eq [issue] - end - - it 'does not list confidential issues for non project members' do - sign_in(non_member) - get_issues - - expect(assigns(:issues)).to eq [issue] - end - - it 'does not list confidential issues for project members with guest role' do - sign_in(member) - project.add_guest(member) - - get_issues - - expect(assigns(:issues)).to eq [issue] - end - - it 'lists confidential issues for author' do - sign_in(author) - get_issues - - expect(assigns(:issues)).to include unescaped_parameter_value - expect(assigns(:issues)).not_to include request_forgery_timing_attack - end - - it 'lists confidential issues for assignee' do - sign_in(assignee) - get_issues - - expect(assigns(:issues)).not_to include unescaped_parameter_value - expect(assigns(:issues)).to include request_forgery_timing_attack - end - - it 'lists confidential issues for project members' do - sign_in(member) - project.add_developer(member) - - get_issues - - expect(assigns(:issues)).to include unescaped_parameter_value - expect(assigns(:issues)).to include request_forgery_timing_attack - end - - context 'when admin mode is enabled', :enable_admin_mode do - it 'lists confidential issues for admin' do - sign_in(admin) - get_issues - - expect(assigns(:issues)).to include unescaped_parameter_value - expect(assigns(:issues)).to include request_forgery_timing_attack - end - end - - context 'when admin mode is disabled' do - it 'does not list confidential issues for admin' do - sign_in(admin) - get_issues - - expect(assigns(:issues)).to eq [issue] - end - end - - def get_issues - get :index, - params: { - namespace_id: project.namespace.to_param, - project_id: project - } - end - end - shared_examples_for 'restricted action' do |http_status| it 'returns 404 for guests' do sign_out(:user) diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb index 0317f9162ccf3efa8d81cce8cb260f687a9c7dd7..f11e5c565455466add0b9369fa60fb2bef661306 100644 --- a/spec/features/groups/empty_states_spec.rb +++ b/spec/features/groups/empty_states_spec.rb @@ -100,21 +100,23 @@ end it "the new #{issuable_name} button opens a project dropdown" do - within '.empty-state' do - click_button 'Toggle project select' - end + click_button 'Toggle project select' - expect(page).to have_selector('.ajax-project-dropdown') + if issuable == :issue + expect(page).to have_button project.name + else + expect(page).to have_selector('.ajax-project-dropdown') + end end end end shared_examples "no projects" do - it 'displays an empty state' do + it 'displays an empty state', :js do expect(page).to have_selector('.empty-state') end - it "does not show a new #{issuable_name} button" do + it "does not show a new #{issuable_name} button", :js do within '.empty-state' do expect(page).not_to have_link("create #{issuable_name}") end @@ -143,7 +145,7 @@ visit path end - it 'displays an empty state' do + it 'displays an empty state', :js do expect(page).to have_selector('.empty-state') end end diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 6b66344512473399aab381ec8785e89eaf0aad2f..a5c28a6cea647131909c3522626646a158430cc3 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -58,10 +58,10 @@ let(:user2) { user_outside_group } it 'filters by only group users' do - filtered_search.set('assignee:=') + select_tokens 'Assignee', '=', submit: false - expect(find('#js-dropdown-assignee .filter-dropdown')).to have_content(user.name) - expect(find('#js-dropdown-assignee .filter-dropdown')).not_to have_content(user2.name) + expect_suggestion(user.name) + expect_no_suggestion(user2.name) end end end @@ -83,18 +83,6 @@ end end - it 'truncates issue counts if over the threshold', :clean_gitlab_redis_cache do - allow(Rails.cache).to receive(:read).and_call_original - allow(Rails.cache).to receive(:read).with( - ['group', group.id, 'issues'], - { expires_in: Gitlab::IssuablesCountForState::CACHE_EXPIRES_IN } - ).and_return({ opened: 1050, closed: 500, all: 1550 }) - - visit issues_group_path(group) - - expect(page).to have_text('Open 1.1k Closed 500 All 1.6k') - end - context 'when project is archived' do before do ::Projects::UpdateService.new(project, user_in_group, archived: true).execute @@ -115,7 +103,6 @@ let!(:subgroup_issue) { create(:issue, project: subgroup_project) } before do - stub_feature_flags(vue_issues_list: true) visit issues_group_path(group_with_no_issues) end @@ -135,14 +122,10 @@ end it 'shows projects only with issues feature enabled', :js do - within '.empty-state' do - click_button 'Toggle project select' - end + click_button 'Toggle project select' - page.within('.select2-results') do - expect(page).to have_content(project.full_name) - expect(page).not_to have_content(project_with_issues_disabled.full_name) - end + expect(page).to have_button project.full_name + expect(page).not_to have_button project_with_issues_disabled.full_name end end end @@ -160,6 +143,7 @@ it 'displays all issues' do visit issues_group_path(group, sort: 'relative_position') + select_manual_sort page.within('.issues-list') do expect(page).to have_selector('li.issue', count: 3) @@ -168,20 +152,21 @@ it 'has manual-ordering css applied' do visit issues_group_path(group, sort: 'relative_position') + select_manual_sort expect(page).to have_selector('.manual-ordering') end it 'each issue item has a gl-cursor-grab css applied' do visit issues_group_path(group, sort: 'relative_position') + select_manual_sort expect(page).to have_selector('.issue.gl-cursor-grab', count: 3) end it 'issues should be draggable and persist order' do visit issues_group_path(group, sort: 'relative_position') - - wait_for_requests + select_manual_sort drag_to(selector: '.manual-ordering', from_index: 0, @@ -200,21 +185,19 @@ sign_out(user_in_group) visit issues_group_path(group, sort: 'relative_position') - - wait_for_requests + select_manual_sort drag_to(selector: '.manual-ordering', from_index: 0, to_index: 2) - wait_for_requests + expect(page).to have_text 'An error occurred while reordering issues.' + end - # Issue order should remain the same - page.within('.manual-ordering') do - expect(find('.issue:nth-child(1) .title')).to have_content('Issue #1') - expect(find('.issue:nth-child(2) .title')).to have_content('Issue #2') - expect(find('.issue:nth-child(3) .title')).to have_content('Issue #3') - end + def select_manual_sort + click_button 'Created date' + click_button 'Manual' + wait_for_requests end def check_issue_order @@ -239,14 +222,8 @@ def check_issue_order end it 'shows the pagination' do - expect(page).to have_link 'Prev' - expect(page).to have_link 'Next' - end - - it 'first pagination item is active' do - page.within('.gl-pagination') do - expect(find('li.active')).to have_content('1') - end + expect(page).to have_button 'Prev', disabled: true + expect(page).to have_button 'Next' end end end diff --git a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb index 9fe110701871483bd3cf39cff902d634deade271..c0b1ca86cd00a3a9a3ba5b5e46632936ed4cbc19 100644 --- a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb +++ b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb @@ -2,7 +2,9 @@ require 'spec_helper' -RSpec.describe 'Groups > User sees users dropdowns in issuables list' do +RSpec.describe 'Groups > User sees users dropdowns in issuables list', :js do + include FilteredSearchHelpers + let(:entity) { create(:group) } let(:user_in_dropdown) { create(:user) } let!(:user_not_in_dropdown) { create(:user) } @@ -10,15 +12,51 @@ before do entity.add_developer(user_in_dropdown) + sign_in(user_in_dropdown) end - it_behaves_like 'issuable user dropdown behaviors' do - let(:issuable) { create(:issue, project: project) } + describe 'issue list user dropdown behaviors' do + let!(:issuable) { create(:issue, project: project) } let(:issuables_path) { issues_group_path(entity) } + + describe "author dropdown" do + it 'only includes members of the project/group' do + visit issuables_path + + select_tokens 'Author', '=', submit: false + + expect_suggestion(user_in_dropdown.name) + expect_no_suggestion(user_not_in_dropdown.name) + end + end + + describe "assignee dropdown" do + it 'only includes members of the project/group' do + visit issuables_path + + select_tokens 'Assignee', '=', submit: false + + expect_suggestion(user_in_dropdown.name) + expect_no_suggestion(user_not_in_dropdown.name) + end + end end - it_behaves_like 'issuable user dropdown behaviors' do - let(:issuable) { create(:merge_request, source_project: project) } + describe 'merge request list user dropdown behaviors' do + let!(:issuable) { create(:merge_request, source_project: project) } let(:issuables_path) { merge_requests_group_path(entity) } + + %w[author assignee].each do |dropdown| + describe "#{dropdown} dropdown" do + it 'only includes members of the project/group' do + visit issuables_path + + filtered_search.set("#{dropdown}:=") + + expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).to have_content(user_in_dropdown.name) + expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).not_to have_content(user_not_in_dropdown.name) + end + end + end end end diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index a0786d36fdf5bac2f0e88d3f1365447b9fe53528..0fa2d238b0a2dc8c94a67b7115d4e60f840ac749 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -34,16 +34,16 @@ it 'sorts labels alphabetically' do label1 = create(:label, project: project, title: 'a') label2 = create(:label, project: project, title: 'z') - label3 = create(:label, project: project, title: 'X') - label4 = create(:label, project: project, title: 'B') + label3 = create(:label, project: project, title: 'x') + label4 = create(:label, project: project, title: 'b') issuable = create_issuable(issuable_type) issuable.labels << [label1, label2, label3, label4] visit_issuable_list(issuable_type) - expect(all('.gl-label-text')[0].text).to have_content('B') - expect(all('.gl-label-text')[1].text).to have_content('X') - expect(all('.gl-label-text')[2].text).to have_content('a') + expect(all('.gl-label-text')[0].text).to have_content('a') + expect(all('.gl-label-text')[1].text).to have_content('b') + expect(all('.gl-label-text')[2].text).to have_content('x') expect(all('.gl-label-text')[3].text).to have_content('z') end end diff --git a/spec/features/issue_rebalancing_spec.rb b/spec/features/issue_rebalancing_spec.rb index 978768270ec2dd3c0c307fa4447d665424d27b9a..686aa5eb1b6d30f5688e7395de2a1f017d98ea1f 100644 --- a/spec/features/issue_rebalancing_spec.rb +++ b/spec/features/issue_rebalancing_spec.rb @@ -38,16 +38,16 @@ expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) end - it 'shows an alert in project issues list with manual sort' do + it 'shows an alert in project issues list with manual sort', :js do visit project_issues_path(project, sort: 'relative_position') - expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) + expect(page).to have_selector('.flash-notice', text: alert_message_regex, count: 1) end - it 'shows an alert in group issues list with manual sort' do + it 'shows an alert in group issues list with manual sort', :js do visit issues_group_path(group, sort: 'relative_position') - expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) + expect(page).to have_selector('.flash-notice', text: alert_message_regex, count: 1) end it 'does not show an alert in project issues list with other sorts' do diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 3ba2f7e788db02493f600ae74db7c0dfcb11aaad..27ef58c7f25e81751a45868e3a220d529b7ac952 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -9,9 +9,6 @@ let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } let_it_be(:issue) { create(:issue, project: project) } - let(:js_dropdown_assignee) { '#js-dropdown-assignee' } - let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") } - describe 'behavior' do before do project.add_maintainer(user) @@ -21,15 +18,17 @@ end it 'loads all the assignees when opened' do - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=', submit: false - expect_filtered_search_dropdown_results(filter_dropdown, 2) + # Expect None, Any, administrator, John Doe2 + expect_filtered_search_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', '=', submit: false - expect(filter_dropdown.first('.filter-dropdown-item')).to have_content(user.name) + # List items 1 to 3 are None, Any, divider + expect(find('.gl-filtered-search-suggestion:nth-child(4)')).to have_text user.name end end @@ -41,7 +40,9 @@ visit project_issues_path(project) Gitlab::Testing::RequestBlockerMiddleware.block_requests! - input_filtered_search('assignee:=', submit: false, extra_space: false) + find_field('Search or filter results...').click + click_on 'Assignee' + click_on '= is' end after do @@ -49,11 +50,10 @@ 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 +93,7 @@ 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', '=', submit: false expect(page).to have_text group_user.name expect(page).to have_text subgroup_user.name @@ -103,7 +103,7 @@ visit project_issues_path(subgroup_project) - input_filtered_search('assignee:=', submit: false, extra_space: false) + select_tokens 'Assignee', '=', submit: false 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 893ffc6575bd732cebcfe63563665ab11b632df0..0fd4db63ee94421eec51b1707fbb59604d75785c 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -9,9 +9,6 @@ let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } 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 project.add_maintainer(user) sign_in(user) @@ -21,22 +18,24 @@ describe 'behavior' do it 'loads all the authors when opened' do - input_filtered_search('author:=', submit: false, extra_space: false) + select_tokens 'Author', '=', submit: false - expect_filtered_search_dropdown_results(filter_dropdown, 2) + expect_filtered_search_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', '=', submit: false - expect(filter_dropdown.first('.filter-dropdown-item')).to have_content(user.name) + expect(find('.gl-filtered-search-suggestion:first-child')).to have_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) + find_field('Search or filter results...').click + click_on 'Author' + click_on '= is' end after do @@ -44,11 +43,10 @@ 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 b8fb807dd78f34ddb1a09040ea084237e80024c3..7d861ee2860222720925c1c6e72b14657ee7266c 100644 --- a/spec/features/issues/filtered_search/dropdown_base_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_base_spec.rb @@ -9,14 +9,6 @@ let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } 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 project.add_maintainer(user) sign_in(user) @@ -26,17 +18,18 @@ def dropdown_assignee_size 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', '=', submit: false + initial_size = filtered_search_suggestion_size 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', '=', submit: false - expect(dropdown_assignee_size).to eq(initial_size) + expect(page).to have_css('.gl-filtered-search-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 f5ab53d505284f8e2a36bcd703efa9c542a2f302..f5769269412bb5ead132d4c0b1d05f06c8c6ac8d 100644 --- a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb @@ -10,10 +10,6 @@ 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 project.add_maintainer(user) create_list(:award_emoji, 2, user: user, name: 'thumbsup') @@ -27,15 +23,15 @@ 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 filtered search tokens' do + click_empty_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 +39,18 @@ 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', '=', submit: false - expect_filtered_search_dropdown_results(filter_dropdown, 3) + # Expect None, Any, star, thumbsup, thumbsdown + expect_filtered_search_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', '=', submit: false - 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 9cc58a33bb72c76c1f2f05e5f1ed2a1d8b18c8b4..af3662df37096792dc828e9299f44c79692c7bb1 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -31,8 +31,9 @@ def click_operator(op) 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_empty_filtered_search_bar + + expect(page).not_to have_link('My-reaction') end end @@ -45,57 +46,56 @@ def click_operator(op) describe 'behavior' do before do - expect(page).to have_css(js_dropdown_hint, visible: false) - filtered_search.click + click_empty_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_empty_filtered_search_bar + send_keys 'la' - expect(find(js_dropdown_hint)).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6) + expect_filtered_search_suggestion_count(1) end end describe 'selecting from dropdown with no input' do before do - filtered_search.click + click_empty_filtered_search_bar end it 'opens the token dropdown when you click on it' do - click_hint('Author') + click_link 'Assignee' - 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('Assignee') + 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_empty_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 1b48810f716684b8ac51b4d16463a1bd9fb4a91e..9c5a1cd17830c6d6dd11cf852b818cd29ba682ed 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -10,9 +10,6 @@ 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 project.add_maintainer(user) sign_in(user) @@ -22,9 +19,10 @@ describe 'behavior' do it 'loads all the labels when opened' do - filtered_search.set('label:=') + select_tokens 'Label', '=', submit: false - expect_filtered_search_dropdown_results(filter_dropdown, 1) + # Expect None, Any, bug-label + expect_filtered_search_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 859d1e4a5e5f002084e018f2bd81c25cc8694954..08d81b994de3f91e209ec11b15a33bc0f56e3050 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -11,9 +11,6 @@ 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 project.add_maintainer(user) sign_in(user) @@ -22,12 +19,11 @@ 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', '=', submit: false + + # Expect None, Any, Upcoming, Started, CAP_MILESTONE, v1.0 + expect_filtered_search_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 2210a26c251aefd3ccda1d052591960ffa04ca45..0442f56f2a134a5ca7c545a15eddf142ee2791f7 100644 --- a/spec/features/issues/filtered_search/dropdown_release_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_release_spec.rb @@ -11,9 +11,6 @@ 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 project.add_maintainer(user) sign_in(user) @@ -22,12 +19,11 @@ 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', '=', submit: false + + # Expect None, Any, v1.0, !/\"#%&'{}+,-.<>;=@]_`{|} + expect_filtered_search_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 1375384d1aa87b11b3f28c503a3b4c66ecddf6c1..1fb12be021101771b29d440d019e57ed839e30ba 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 @@ 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') } @@ -65,30 +60,30 @@ def expect_no_issues_list it 'filters by all available tokens' do search_term = 'issue' - input_filtered_search("assignee:=@#{user.username} author:=@#{user.username} label:=~#{caps_sensitive_label.title} milestone:=%#{milestone.title} #{search_term}") + select_tokens 'Assignee', '=', user.username, 'Author', '=', user.username, 'Label', '=', caps_sensitive_label.title, 'Milestone', '=', milestone.title, submit: false + send_keys(search_term, :enter) 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_search_term(search_term) + expect_issues_list_count(1) - expect_filtered_search_input(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 wait_for_requests - expect_tokens([author_token(user.name)]) + expect_author_token(user.name) + expect_empty_search_term expect_issues_list_count(5) - expect_filtered_search_input_empty end end end @@ -96,46 +91,32 @@ def expect_no_issues_list describe 'filter issues by assignee' do context 'only assignee' do it 'filters issues by searched assignee' do - input_filtered_search("assignee:=@#{user.username}") + select_tokens 'Assignee', '=', user.username wait_for_requests - expect_tokens([assignee_token(user.name)]) + expect_assignee_token(user.name) + expect_empty_search_term expect_issues_list_count(5) - expect_filtered_search_input_empty end it 'filters issues by no assignee' do - input_filtered_search('assignee:=none') + select_tokens 'Assignee', '=', 'None' - expect_tokens([assignee_token('None')]) + expect_assignee_token('None') + expect_empty_search_term expect_issues_list_count(3) - expect_filtered_search_input_empty 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_empty_filtered_search_bar expect(page).not_to have_button('Reviewer') end @@ -144,57 +125,53 @@ def expect_no_issues_list 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 - 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 - 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' - 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' - 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 - 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 - 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 +179,11 @@ def expect_no_issues_list 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 - 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 +191,21 @@ def expect_no_issues_list 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 - 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 - 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 +215,29 @@ def expect_no_issues_list 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 # 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 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 - 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 +245,11 @@ def expect_no_issues_list 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 - 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,11 +257,11 @@ def expect_no_issues_list 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 - 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 @@ -294,37 +269,35 @@ def expect_no_issues_list 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}") + select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, 'Author', '=', user.username, 'Assignee', '=', user.username, 'Milestone', '=', milestone.title, submit: false + send_keys(search_term, :enter) 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) - ]) + 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}") + select_tokens 'Label', '=', bug_label.title, 'Label', '=', caps_sensitive_label.title, 'Author', '=', user.username, 'Assignee', '=', user.username, 'Milestone', '!=', milestone.title, submit: false + send_keys(search_term, :enter) 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, '!=') - ]) + 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 +306,8 @@ def expect_no_issues_list 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 +315,19 @@ def expect_no_issues_list 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 - 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' - 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 +335,11 @@ def expect_no_issues_list create(:issue, project: project, milestone: future_milestone, author: user) end - input_filtered_search("milestone:=upcoming") + select_tokens 'Milestone', '=', 'Upcoming' - 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 +351,72 @@ def expect_no_issues_list create(:issue, project: project, milestone: past_milestone, author: user) end - input_filtered_search("milestone:!=upcoming") + select_tokens 'Milestone', '!=', 'Upcoming' - 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' - 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' - 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 - 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 - 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 - 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 - 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,36 +425,36 @@ def expect_no_issues_list 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) + 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 @@ -489,10 +462,10 @@ def expect_no_issues_list issue = create(:issue, project: project, author: user, title: "issue with \"double quotes\"") search = '"double quotes"' - 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 @@ -502,36 +475,41 @@ def expect_no_issues_list 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_empty_filtered_search_bar + send_keys 'bug ' + select_tokens 'Author', '=', user.username, submit: false + send_keys 'report ' + select_tokens 'Label', '=', bug_label.title, submit: false + 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 +527,11 @@ def expect_no_issues_list 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(find('.issues-list .issue:first-of-type .issue-title')).to have_content(new_issue.title) end end end @@ -568,7 +540,7 @@ def expect_no_issues_list 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 +571,17 @@ def expect_no_issues_list end it 'milestone dropdown loads milestones' do - input_filtered_search("milestone:=", submit: false) + select_tokens 'Milestone', '=', submit: false - 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_filtered_search_suggestion_count(5) end it 'label dropdown load labels' do - input_filtered_search("label:=", submit: false) + select_tokens 'Label', '=', submit: false - 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_filtered_search_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 3929d3694ffee41f62b5d9116e14e379ff286ddb..ef1fce54464c123c09ea450680da315e9af3c62e 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -25,34 +25,46 @@ Capybara.ignore_hidden_elements = true end + def submit_search(search) + click_empty_filtered_search_bar + send_keys(search, :enter) + click_button 'Clear' + 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) + submit_search 'search1' + submit_search 'search2' - items = all('.filtered-search-history-dropdown-item', visible: false, count: 2) + click_button 'Toggle history' - expect(items[0].text).to eq('bar') - expect(items[1].text).to eq('foo') + items = all('.gl-search-box-by-click-history-item', count: 2) + + expect(items[0].text).to eq('search2') + expect(items[1].text).to eq('search1') 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' + + items = all('.gl-search-box-by-click-history-item', count: 2) - expect(items[0].text).to eq('label: = ~qux garply') - expect(items[1].text).to eq('label: = ~foo bar') + expect(items[0].text).to eq('Label := qux garply') + expect(items[1].text).to eq('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') - items = all('.filtered-search-history-dropdown-item', visible: false, count: 3) + click_button 'Toggle history' + + items = all('.gl-search-box-by-click-history-item', count: 3) expect(items[0].text).to eq('foo') expect(items[1].text).to eq('saved1') @@ -62,42 +74,45 @@ 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_search 'foo' + submit_search 'bar' visit project_issues_path(project_2) - input_filtered_search('more', submit: true) - input_filtered_search('things', submit: true) + submit_search 'more' + submit_search 'things' + + click_button 'Toggle history' - items = all('.filtered-search-history-dropdown-item', visible: false, count: 2) + items = all('.gl-search-box-by-click-history-item', count: 2) expect(items[0].text).to eq('things') expect(items[1].text).to eq('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' + + expect(page).to have_css '.gl-search-box-by-click-history-item', count: 1 - find('.filtered-search-history-clear-button').click - items_after = all('.filtered-search-history-dropdown-item', count: 0) + click_button 'Clear recent searches' + click_button 'Toggle history' - expect(items_after.count).to eq(0) + expect(page).to have_text "You don't have any recent searches" + expect(page).not_to have_css '.gl-search-box-by-click-history-item' end it 'shows flash error when failed to parse saved history' do @@ -106,24 +121,4 @@ expect(find('[data-testid="alert-danger"]')).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 - 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 60963d95ae59d8efab69ba318f0c2571d595dc34..79f2aae91b9f8a3700b75299ff87ba65d8b43867 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -9,8 +9,6 @@ let_it_be(:user) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } - let(:filtered_search) { find('.filtered-search') } - before do project.add_maintainer(user) sign_in(user) @@ -24,87 +22,68 @@ def get_left_style(style) 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_empty_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_empty_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_empty_filtered_search_bar + send_keys 'a' + + click_button 'Clear' - expect(page).to have_css('.clear-search', visible: false) + expect(page).not_to have_button 'Clear' end it 'hides when there is no text' do - filtered_search.set('a') - filtered_search.set('') + click_empty_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_empty_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 + click_empty_filtered_search_bar - hint_offset = get_left_style(find('#js-dropdown-hint')['style']) + original_size = filtered_search_suggestion_size - filtered_search.set('a') + send_keys 'autho' - filtered_search.set('author:') + expect_filtered_search_suggestion_count(1) - find('#js-dropdown-hint', visible: false) + click_button 'Clear' - find('.filtered-search-box .clear-search').click - filtered_search.click + click_empty_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_filtered_search_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 2d8587d886f84f35e6f7cfcb209bd8d70ef5d7ee..c5623673c55ed53167d463631e76982fcfcf1ffb 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -14,13 +14,6 @@ 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 project.add_user(user, :maintainer) project.add_user(user_rock, :maintainer) @@ -33,159 +26,150 @@ def is_input_focused describe 'editing a single token' 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', submit: false + click_token_segment(user.name) wait_for_requests 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_filtered_search_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(first('.gl-filtered-search-token-segment:nth-child(3)').text).to eq(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', submit: false + 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_empty_filtered_search_bar + send_keys 'foo ' + select_tokens 'Assignee', '=', submit: false + + 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 'Label' - expect(page).to have_css('#js-dropdown-operator', visible: true) - expect(page).to have_css('#js-dropdown-author', visible: false) + expect_visible_suggestions_list - 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_visible_suggestions_list 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', submit: false + 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', submit: false 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', submit: false + 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', '!=', submit: false - 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', '=', submit: false - 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/rss_spec.rb b/spec/features/issues/rss_spec.rb index b20502ecc255ba9b9288076e5bc1e5a79d32a730..e3faed81c732f6d7dd329ba1bc210680d2d0f790 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) } @@ -25,7 +25,10 @@ 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 +37,10 @@ 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 71213fb661f0cdd2e927cd02885db95750d145d5..4837d13574cacda8eb5ab11b79625c9d50ff5a94 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,8 @@ 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}" } context 'as an allowed user', :js do before do diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb index 625303f89e430d12750dc4b1021b8ed636a7e324..1c8ca470f07969327cfffa9dabbcd770323bf001 100644 --- a/spec/features/issues/user_bulk_edits_issues_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_spec.rb @@ -18,8 +18,11 @@ click_button 'Edit issues' check 'Select all' - click_button 'Select status' - click_button 'Closed' + + within('aside[aria-label="Bulk update"]') do + click_button 'Select status' + click_button 'Closed' + end click_update_issues_button expect(page).to have_selector('.issue', count: 0) @@ -31,8 +34,11 @@ click_button 'Edit issues' check 'Select all' - click_button 'Select status' - click_button 'Open' + + within('aside[aria-label="Bulk update"]') do + click_button 'Select status' + click_button 'Open' + end click_update_issues_button expect(page).to have_selector('.issue', count: 0) @@ -107,10 +113,6 @@ describe 'select all issues' do let!(:issue_2) { create(:issue, project: project) } - before do - stub_feature_flags(vue_issues_list: true) - end - it 'after selecting all issues, unchecking one issue only unselects that one issue' do visit project_issues_path(project) diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index 446f13dc4d06e28ba08bf3a89d6288b32a79ccb4..26ca40bc1d7142a559d2cfc82149530e94b01dfe 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -13,7 +13,7 @@ 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 5d05df6aaf0f37cdee2fa56559c52735afac9dd0..2941ea6ec36261c57f517c812e136ef169a5cce9 100644 --- a/spec/features/issues/user_filters_issues_spec.rb +++ b/spec/features/issues/user_filters_issues_spec.rb @@ -24,7 +24,7 @@ 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_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb index 669c7c454112990552e3e4c61b826350083cf6d7..f49af283fd595008d9cd4d864f37d43a62ad4a2c 100644 --- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb +++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb @@ -27,7 +27,7 @@ expect(find('.breadcrumbs-sub-title 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 86bdaf5d706f9194ebfda820148783a9c4ca6a68..7add6c782f7cbdca5c14d7aa6801b31a50b38418 100644 --- a/spec/features/issues/user_sorts_issues_spec.rb +++ b/spec/features/issues/user_sorts_issues_spec.rb @@ -24,26 +24,23 @@ 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 diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb index 479199b72b764d352e271fa3c88d9805a84d3a17..eb4c1fd83885e7a0837d3a407a41582a8fa60062 100644 --- a/spec/features/labels_hierarchy_spec.rb +++ b/spec/features/labels_hierarchy_spec.rb @@ -54,15 +54,21 @@ shared_examples 'filtering by ancestor labels for projects' do |board = false| it 'filters by ancestor labels' do [grandparent_group_label, parent_group_label, project_label_1].each do |label| - select_label_on_dropdown(label.title) - - wait_for_requests - if board + select_label_on_dropdown(label.title) + expect(page).to have_selector('.board-card-title') do |card| expect(card).to have_selector('a', text: labeled_issue.title) end else + within '[data-testid="filtered-search-input"]' do + click_empty_filtered_search_bar + click_on 'Label' + click_on '= is' + click_on label.title + send_keys :enter + end + expect_issues_list_count(1) expect(page).to have_selector('.issue-title', text: labeled_issue.title) end @@ -70,7 +76,11 @@ end it 'does not filter by descendant group labels' do - filtered_search.set("label=") + if board + filtered_search.set("label=") + else + select_tokens 'Label', '=', submit: false + end wait_for_requests @@ -93,11 +103,9 @@ it 'filters by ancestors and current group labels' do [grandparent_group_label, parent_group_label].each do |label| - select_label_on_dropdown(label.title) - - wait_for_requests - if board + select_label_on_dropdown(label.title) + expect(page).to have_selector('.board-card-title') do |card| expect(card).to have_selector('a', text: labeled_issue.title) end @@ -106,6 +114,14 @@ expect(card).to have_selector('a', text: labeled_issue_2.title) end else + within '[data-testid="filtered-search-input"]' do + click_empty_filtered_search_bar + click_on 'Label' + click_on '= is' + click_on label.title + send_keys :enter + end + expect_issues_list_count(3) expect(page).to have_selector('.issue-title', text: labeled_issue.title) expect(page).to have_selector('.issue-title', text: labeled_issue_2.title) @@ -115,11 +131,9 @@ end it 'filters by descendant group labels' do - wait_for_requests - - select_label_on_dropdown(group_label_3.title) - if board + select_label_on_dropdown(group_label_3.title) + expect(page).to have_selector('.board-card-title') do |card| expect(card).not_to have_selector('a', text: labeled_issue_2.title) end @@ -128,17 +142,27 @@ expect(card).to have_selector('a', text: labeled_issue_3.title) end else + select_tokens 'Label', '=', group_label_3.title + expect_issues_list_count(1) expect(page).to have_selector('.issue-title', text: labeled_issue_3.title) end end it 'does not filter by descendant group project labels' do - filtered_search.set("label=") + if board + filtered_search.set("label=") - wait_for_requests + wait_for_requests + + expect(page).not_to have_selector('.btn-link', text: project_label_3.title) + else + select_tokens 'Label', '=', submit: false - expect(page).not_to have_selector('.btn-link', text: project_label_3.title) + wait_for_requests + + expect(page).not_to have_link project_label_3.title + end end end @@ -192,10 +216,10 @@ visit project_issues_path(project_1) end - it_behaves_like 'filtering by ancestor labels for projects' + it_behaves_like 'filtering by ancestor labels for projects', false, true it 'does not filter by descendant group labels' do - filtered_search.set("label=") + select_tokens 'Label', '=', submit: false wait_for_requests diff --git a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb index 99473f3b1ea77fd68fc845ebeca036618384cbc0..7c1aae9fa6acdccc780cab2487e8b54f53330e74 100644 --- a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb +++ b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb @@ -49,7 +49,7 @@ expect(find('.issues-filters a.is-active')).to have_content('Milestone') end - it 'separates remember sorting with issues' do + it 'separates remember sorting with issues', :js do create(:issue, project: project) find('.filter-dropdown-container .dropdown').click diff --git a/spec/features/user_sorts_things_spec.rb b/spec/features/user_sorts_things_spec.rb index fa37d6922259e0893eb520fd9f4c6a7ab2dcbe2e..9fd07316ea7ddcd9dffa9e55af2906cf26e682e3 100644 --- a/spec/features/user_sorts_things_spec.rb +++ b/spec/features/user_sorts_things_spec.rb @@ -20,17 +20,18 @@ sign_in(current_user) end - it "issues -> project home page -> issues" do + it "issues -> project home page -> issues", :js do sort_option = 'Updated date' visit(project_issues_path(project)) - sort_by(sort_option) + click_button 'Created date' + click_button sort_option visit(project_path(project)) visit(project_issues_path(project)) - expect(find(".issues-filters")).to have_content(sort_option) + expect(page).to have_button(sort_option) end it "merge requests -> dashboard merge requests" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a72c8d2c4e83d27f6303ae2a8850b9fd298ca930..94b22691bac42b1788f3736402a89c89b219fbbf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -311,7 +311,7 @@ # The following `vue_issues_list` stub can be removed # once the Vue issues page has feature parity with the current Haml page - stub_feature_flags(vue_issues_list: false) + # stub_feature_flags(vue_issues_list: false) # Disable `main_branch_over_master` as we migrate # from `master` to `main` accross our codebase. diff --git a/spec/support/helpers/filtered_search_helpers.rb b/spec/support/helpers/filtered_search_helpers.rb index b6cf78b9046ef1b01564abc8d229280f70a19222..3f1868d5585c36ddeb0d338aa7a044a83de5a4a4 100644 --- a/spec/support/helpers/filtered_search_helpers.rb +++ b/spec/support/helpers/filtered_search_helpers.rb @@ -187,4 +187,110 @@ def close_dropdown_menu_if_visible toggle.click if toggle.visible? end end + + def select_tokens(*args, submit: true) + within '[data-testid="filtered-search-input"]' do + find_field('Search').click + + args.each do |token| + # Move mouse away to prevent invoking tooltips on usernames, which blocks the search input + find_button('Search').hover + + if token == '=' + click_on '= is' + else + click_on token + end + + wait_for_requests + end + end + + if submit + send_keys :enter + end + end + + def click_empty_filtered_search_bar + find('.gl-filtered-search-last-item').click + end + + def click_token_segment(value) + find('.gl-filtered-search-token-segment', text: value).click + end + + def submit_search_term(value) + click_empty_filtered_search_bar + send_keys(value, :enter) + end + + def filtered_search_suggestion_size + all('.gl-filtered-search-suggestion').size + end + + def expect_token_segment(value) + expect(page).to have_css '.gl-filtered-search-token-segment', text: value + end + + def expect_visible_suggestions_list + expect(page).to have_css('.gl-filtered-search-suggestion-list') + end + + def expect_hidden_suggestions_list + expect(page).not_to have_css('.gl-filtered-search-suggestion-list') + end + + def expect_suggestion(value) + expect(page).to have_css('.gl-filtered-search-suggestion-list', text: value) + end + + def expect_no_suggestion(value) + expect(page).not_to have_css('.gl-filtered-search-suggestion-list', text: value) + end + + def expect_filtered_search_suggestion_count(count) + expect(page).to have_css('.gl-filtered-search-suggestion', count: count) + end + + def expect_assignee_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Assignee = #{value}" + end + + def expect_author_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Author = #{value}" + end + + def expect_label_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Label = ~#{value}" + end + + def expect_negated_label_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Label != ~#{value}" + end + + def expect_milestone_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Milestone = %#{value}" + end + + def expect_negated_milestone_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Milestone != %#{value}" + end + + def expect_epic_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Epic = #{value}" + end + + def expect_weight_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Weight = %#{value}" + end + + def expect_search_term(value) + value.split(' ').each do |term| + expect(page).to have_css '.gl-filtered-search-term', text: term + end + end + + def expect_empty_search_term + expect(page).to have_css '.gl-filtered-search-term', text: '' + end end diff --git a/spec/support/shared_examples/features/issuables_user_dropdown_behaviors_shared_examples.rb b/spec/support/shared_examples/features/issuables_user_dropdown_behaviors_shared_examples.rb deleted file mode 100644 index 1848b4fffd919e876c803e4519208bd574151131..0000000000000000000000000000000000000000 --- a/spec/support/shared_examples/features/issuables_user_dropdown_behaviors_shared_examples.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -RSpec.shared_examples 'issuable user dropdown behaviors' do - include FilteredSearchHelpers - - before do - issuable # ensure we have at least one issuable - sign_in(user_in_dropdown) - end - - %w[author assignee].each do |dropdown| - describe "#{dropdown} dropdown", :js do - it 'only includes members of the project/group' do - visit issuables_path - - filtered_search.set("#{dropdown}:=") - - expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).to have_content(user_in_dropdown.name) - expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).not_to have_content(user_not_in_dropdown.name) - end - end - end -end