diff options
Diffstat (limited to 'spec/features/boards')
-rw-r--r-- | spec/features/boards/add_issues_modal_spec.rb | 270 | ||||
-rw-r--r-- | spec/features/boards/boards_spec.rb | 94 | ||||
-rw-r--r-- | spec/features/boards/focus_mode_spec.rb | 4 | ||||
-rw-r--r-- | spec/features/boards/modal_filter_spec.rb | 228 | ||||
-rw-r--r-- | spec/features/boards/multi_select_spec.rb | 4 | ||||
-rw-r--r-- | spec/features/boards/multiple_boards_spec.rb | 1 | ||||
-rw-r--r-- | spec/features/boards/new_issue_spec.rb | 34 | ||||
-rw-r--r-- | spec/features/boards/reload_boards_on_browser_back_spec.rb | 4 | ||||
-rw-r--r-- | spec/features/boards/sidebar_assignee_spec.rb | 122 | ||||
-rw-r--r-- | spec/features/boards/sidebar_due_date_spec.rb | 46 | ||||
-rw-r--r-- | spec/features/boards/sidebar_labels_spec.rb | 166 | ||||
-rw-r--r-- | spec/features/boards/sidebar_milestones_spec.rb | 65 | ||||
-rw-r--r-- | spec/features/boards/sidebar_spec.rb | 403 | ||||
-rw-r--r-- | spec/features/boards/sub_group_project_spec.rb | 3 | ||||
-rw-r--r-- | spec/features/boards/user_adds_lists_to_board_spec.rb | 11 |
15 files changed, 510 insertions, 945 deletions
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb deleted file mode 100644 index 8d0fa3e023b..00000000000 --- a/spec/features/boards/add_issues_modal_spec.rb +++ /dev/null @@ -1,270 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Issue Boards add issue modal', :js do - let(:project) { create(:project, :public) } - let(:board) { create(:board, project: project) } - let(:user) { create(:user) } - let!(:planning) { create(:label, project: project, name: 'Planning') } - let!(:label) { create(:label, project: project) } - let!(:list1) { create(:list, board: board, label: planning, position: 0) } - let!(:list2) { create(:list, board: board, label: label, position: 1) } - let!(:issue) { create(:issue, project: project, title: 'abc', description: 'def') } - let!(:issue2) { create(:issue, project: project, title: 'hij', description: 'klm') } - - before do - project.add_maintainer(user) - - sign_in(user) - - visit project_board_path(project, board) - wait_for_requests - end - - it 'resets filtered search state' do - visit project_board_path(project, board, search: 'testing') - - wait_for_requests - - click_button('Add issues') - - page.within('.add-issues-modal') do - expect(find('.form-control').value).to eq('') - expect(page).to have_selector('.clear-search', visible: false) - expect(find('.form-control')[:placeholder]).to eq('Search or filter results...') - end - end - - context 'modal interaction' do - before do - stub_feature_flags(add_issues_button: true) - end - - it 'opens modal' do - click_button('Add issues') - - expect(page).to have_selector('.add-issues-modal') - end - - it 'closes modal' do - click_button('Add issues') - - page.within('.add-issues-modal') do - find('.close').click - end - - expect(page).not_to have_selector('.add-issues-modal') - end - - it 'closes modal if cancel button clicked' do - click_button('Add issues') - - page.within('.add-issues-modal') do - click_button 'Cancel' - end - - expect(page).not_to have_selector('.add-issues-modal') - end - - it 'does not show tooltip on add issues button' do - button = page.find('.filter-dropdown-container button', text: 'Add issues') - - expect(button[:title]).not_to eq("Please add a list to your board first") - end - end - - context 'issues list' do - before do - stub_feature_flags(add_issues_button: true) - click_button('Add issues') - - wait_for_requests - end - - it 'loads issues' do - page.within('.add-issues-modal') do - page.within('.gl-tabs') do - expect(page).to have_content('2') - end - - expect(page).to have_selector('.board-card', count: 2) - end - end - - it 'shows selected issues tab and empty state message' do - page.within('.add-issues-modal') do - click_link 'Selected issues' - - expect(page).not_to have_selector('.board-card') - expect(page).to have_content("Go back to Open issues and select some issues to add to your board.") - end - end - - context 'list dropdown' do - it 'resets after deleting list' do - page.within('.add-issues-modal') do - expect(find('.add-issues-footer')).to have_button(planning.title) - - click_button 'Cancel' - end - - page.within(find('.board:nth-child(2)')) do - find('button[title="List settings"]').click - end - - page.within(find('.js-board-settings-sidebar')) do - accept_confirm { find('[data-testid="remove-list"]').click } - end - - click_button('Add issues') - - wait_for_requests - - page.within('.add-issues-modal') do - expect(find('.add-issues-footer')).not_to have_button(planning.title) - expect(find('.add-issues-footer')).to have_button(label.title) - end - end - end - - context 'search' do - it 'returns issues' do - page.within('.add-issues-modal') do - find('.form-control').native.send_keys(issue.title) - find('.form-control').native.send_keys(:enter) - - wait_for_requests - - expect(page).to have_selector('.board-card', count: 1) - end - end - - it 'returns no issues' do - page.within('.add-issues-modal') do - find('.form-control').native.send_keys('testing search') - find('.form-control').native.send_keys(:enter) - - wait_for_requests - - expect(page).not_to have_selector('.board-card') - expect(page).not_to have_content("You haven't added any issues to your project yet") - end - end - end - - context 'selecting issues' do - it 'selects single issue' do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - page.within('.gl-tabs') do - expect(page).to have_content('Selected issues 1') - end - end - end - - it 'changes button text' do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - expect(first('.add-issues-footer .btn')).to have_content('Add 1 issue') - end - end - - it 'changes button text with plural' do - page.within('.add-issues-modal') do - all('.board-card .js-board-card-number-container').each do |el| - el.click - end - - expect(first('.add-issues-footer .btn')).to have_content('Add 2 issues') - end - end - - it 'shows only selected issues on selected tab' do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - click_link 'Selected issues' - - expect(page).to have_selector('.board-card', count: 1) - end - end - - it 'selects all issues' do - page.within('.add-issues-modal') do - click_button 'Select all' - - expect(page).to have_selector('.is-active', count: 2) - end - end - - it 'deselects all issues' do - page.within('.add-issues-modal') do - click_button 'Select all' - - expect(page).to have_selector('.is-active', count: 2) - - click_button 'Deselect all' - - expect(page).not_to have_selector('.is-active') - end - end - - it "selects all that aren't already selected" do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - expect(page).to have_selector('.is-active', count: 1) - - click_button 'Select all' - - expect(page).to have_selector('.is-active', count: 2) - end - end - - it 'unselects from selected tab' do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - click_link 'Selected issues' - - first('.board-card .board-card-number').click - - expect(page).not_to have_selector('.is-active') - end - end - end - - context 'adding issues' do - it 'adds to board' do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - click_button 'Add 1 issue' - end - - page.within(find('.board:nth-child(2)')) do - expect(page).to have_selector('.board-card') - end - end - - it 'adds to second list' do - page.within('.add-issues-modal') do - first('.board-card .board-card-number').click - - click_button planning.title - - click_link label.title - - click_button 'Add 1 issue' - end - - page.within(find('.board:nth-child(3)')) do - expect(page).to have_selector('.board-card') - end - end - end - end -end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 2392f9d2f8a..ab544022bff 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Issue Boards', :js do +RSpec.describe 'Project issue boards', :js do include DragTo include MobileHelpers @@ -23,7 +23,7 @@ RSpec.describe 'Issue Boards', :js do context 'no lists' do before do - visit project_board_path(project, board) + visit_project_board_path_without_query_limit(project, board) end it 'creates default lists' do @@ -52,6 +52,7 @@ RSpec.describe 'Issue Boards', :js do let_it_be(:a_plus) { create(:label, project: project, name: 'A+') } let_it_be(:list1) { create(:list, board: board, label: planning, position: 0) } let_it_be(:list2) { create(:list, board: board, label: development, position: 1) } + let_it_be(:backlog_list) { create(:backlog_list, board: board) } let_it_be(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning], relative_position: 9) } let_it_be(:issue1) { create(:labeled_issue, project: project, title: 'aaa', description: '111', assignees: [user], labels: [planning], relative_position: 8) } @@ -68,7 +69,7 @@ RSpec.describe 'Issue Boards', :js do before do stub_feature_flags(board_new_list: false) - visit project_board_path(project, board) + visit_project_board_path_without_query_limit(project, board) wait_for_requests @@ -121,7 +122,8 @@ RSpec.describe 'Issue Boards', :js do context 'with the NOT queries feature flag disabled' do before do stub_feature_flags(not_issuable_queries: false) - visit project_board_path(project, board) + + visit_project_board_path_without_query_limit(project, board) end it 'does not have the != option' do @@ -141,7 +143,8 @@ RSpec.describe 'Issue Boards', :js do context 'with the NOT queries feature flag enabled' do before do stub_feature_flags(not_issuable_queries: true) - visit project_board_path(project, board) + + visit_project_board_path_without_query_limit(project, board) end it 'does not have the != option' do @@ -171,8 +174,7 @@ RSpec.describe 'Issue Boards', :js do it 'infinite scrolls list' do create_list(:labeled_issue, 50, project: project, labels: [planning]) - visit project_board_path(project, board) - wait_for_requests + visit_project_board_path_without_query_limit(project, board) page.within(find('.board:nth-child(2)')) do expect(page.find('.board-header')).to have_content('58') @@ -180,15 +182,19 @@ RSpec.describe 'Issue Boards', :js do expect(page).to have_content('Showing 20 of 58 issues') find('.board .board-list') - evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") - wait_for_requests + + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") + end expect(page).to have_selector('.board-card', count: 40) expect(page).to have_content('Showing 40 of 58 issues') find('.board .board-list') - evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") - wait_for_requests + + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") + end expect(page).to have_selector('.board-card', count: 58) expect(page).to have_content('Showing all issues') @@ -236,13 +242,13 @@ RSpec.describe 'Issue Boards', :js do wait_for_board_cards(4, 1) expect(find('.board:nth-child(2)')).to have_content(development.title) - expect(find('.board:nth-child(2)')).to have_content(planning.title) + expect(find('.board:nth-child(3)')).to have_content(planning.title) # Make sure list positions are preserved after a reload - visit project_board_path(project, board) + visit_project_board_path_without_query_limit(project, board) expect(find('.board:nth-child(2)')).to have_content(development.title) - expect(find('.board:nth-child(2)')).to have_content(planning.title) + expect(find('.board:nth-child(3)')).to have_content(planning.title) end it 'dragging does not duplicate list' do @@ -254,7 +260,8 @@ RSpec.describe 'Issue Boards', :js do expect(page).to have_selector(selector, text: development.title, count: 1) end - it 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do + # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/323551 + xit 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do drag(list_from_index: 1, from_index: 1, list_to_index: 2) wait_for_board_cards(2, 7) @@ -467,14 +474,16 @@ RSpec.describe 'Issue Boards', :js do end it 'removes filtered labels' do - set_filter("label", testing.title) - click_filter_link(testing.title) - submit_filter + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + set_filter("label", testing.title) + click_filter_link(testing.title) + submit_filter - wait_for_board_cards(2, 1) + wait_for_board_cards(2, 1) - find('.clear-search').click - submit_filter + find('.clear-search').click + submit_filter + end wait_for_board_cards(2, 8) end @@ -484,7 +493,9 @@ RSpec.describe 'Issue Boards', :js do set_filter("label", testing.title) click_filter_link(testing.title) - submit_filter + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + submit_filter + end wait_for_requests @@ -494,13 +505,18 @@ RSpec.describe 'Issue Boards', :js do expect(page).to have_content('Showing 20 of 51 issues') find('.board .board-list') - evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") + + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") + end expect(page).to have_selector('.board-card', count: 40) expect(page).to have_content('Showing 40 of 51 issues') find('.board .board-list') - evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight") + end expect(page).to have_selector('.board-card', count: 51) expect(page).to have_content('Showing all issues') @@ -569,7 +585,7 @@ RSpec.describe 'Issue Boards', :js do context 'keyboard shortcuts' do before do - visit project_board_path(project, board) + visit_project_board_path_without_query_limit(project, board) wait_for_requests end @@ -617,15 +633,19 @@ RSpec.describe 'Issue Boards', :js do def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true) # ensure there is enough horizontal space for four boards - resize_window(2000, 800) - - drag_to(selector: selector, - scrollable: '#board-app', - list_from_index: list_from_index, - from_index: from_index, - to_index: to_index, - list_to_index: list_to_index, - perform_drop: perform_drop) + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + resize_window(2000, 800) + + drag_to(selector: selector, + scrollable: '#board-app', + list_from_index: list_from_index, + from_index: from_index, + to_index: to_index, + list_to_index: list_to_index, + perform_drop: perform_drop) + end + + wait_for_requests end def wait_for_board_cards(board_number, expected_cards) @@ -666,4 +686,10 @@ RSpec.describe 'Issue Boards', :js do accept_confirm { find('[data-testid="remove-list"]').click } end end + + def visit_project_board_path_without_query_limit(project, board) + inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do + visit project_board_path(project, board) + end + end end diff --git a/spec/features/boards/focus_mode_spec.rb b/spec/features/boards/focus_mode_spec.rb index b1684ad69a6..2bd1e625236 100644 --- a/spec/features/boards/focus_mode_spec.rb +++ b/spec/features/boards/focus_mode_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Issue Boards focus mode', :js do wait_for_requests end - it 'shows focus mode button to guest users' do - expect(page).to have_selector('.board-extra-actions .js-focus-mode-btn') + it 'shows focus mode button to anonymous users' do + expect(page).to have_selector('.js-focus-mode-btn') end end diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb deleted file mode 100644 index 5aeb9eb5e50..00000000000 --- a/spec/features/boards/modal_filter_spec.rb +++ /dev/null @@ -1,228 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Issue Boards add issue modal filtering', :js do - let(:project) { create(:project, :public) } - let(:board) { create(:board, project: project) } - let(:planning) { create(:label, project: project, name: 'Planning') } - let!(:list1) { create(:list, board: board, label: planning, position: 0) } - let(:user) { create(:user) } - let(:user2) { create(:user) } - let!(:issue1) { create(:issue, project: project) } - - before do - project.add_maintainer(user) - - sign_in(user) - end - - it 'shows empty state when no results found' do - visit_board - - page.within('.add-issues-modal') do - find('.form-control').native.send_keys('testing empty state') - find('.form-control').native.send_keys(:enter) - - wait_for_requests - - expect(page).to have_content('There are no issues to show.') - end - end - - it 'restores filters when closing' do - visit_board - - set_filter('milestone') - click_filter_link('Upcoming') - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.board-card', count: 0) - - click_button 'Cancel' - end - - click_button('Add issues') - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.board-card', count: 1) - end - end - - it 'resotres filters after clicking clear button' do - visit_board - - set_filter('milestone') - click_filter_link('Upcoming') - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.board-card', count: 0) - - find('.clear-search').click - - wait_for_requests - - expect(page).to have_selector('.board-card', count: 1) - end - end - - context 'author' do - let!(:issue) { create(:issue, project: project, author: user2) } - - before do - project.add_developer(user2) - - visit_board - end - - it 'filters by selected user' do - set_filter('author') - click_filter_link(user2.name) - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: user2.name) - expect(page).to have_selector('.board-card', count: 1) - end - end - end - - context 'assignee' do - let!(:issue) { create(:issue, project: project, assignees: [user2]) } - - before do - project.add_developer(user2) - - visit_board - end - - it 'filters by unassigned' do - set_filter('assignee') - click_filter_link('None') - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: 'None') - expect(page).to have_selector('.board-card', count: 1) - end - end - - it 'filters by selected user' do - set_filter('assignee') - click_filter_link(user2.name) - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: user2.name) - expect(page).to have_selector('.board-card', count: 1) - end - end - end - - context 'milestone' do - let(:milestone) { create(:milestone, project: project) } - let!(:issue) { create(:issue, project: project, milestone: milestone) } - - before do - visit_board - end - - it 'filters by upcoming milestone' do - set_filter('milestone') - click_filter_link('Upcoming') - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: 'Upcoming') - expect(page).to have_selector('.board-card', count: 0) - end - end - - it 'filters by selected milestone' do - set_filter('milestone') - click_filter_link(milestone.name) - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: milestone.name) - expect(page).to have_selector('.board-card', count: 1) - end - end - end - - context 'label' do - let(:label) { create(:label, project: project) } - let!(:issue) { create(:labeled_issue, project: project, labels: [label]) } - - before do - visit_board - end - - it 'filters by no label' do - set_filter('label') - click_filter_link('None') - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: 'None') - expect(page).to have_selector('.board-card', count: 1) - end - end - - it 'filters by label' do - set_filter('label') - click_filter_link(label.title) - submit_filter - - page.within('.add-issues-modal') do - wait_for_requests - - expect(page).to have_selector('.js-visual-token', text: label.title) - expect(page).to have_selector('.board-card', count: 1) - end - end - end - - def visit_board - visit project_board_path(project, board) - wait_for_requests - - click_button('Add issues') - end - - def set_filter(type, text = '') - find('.add-issues-modal .filtered-search').native.send_keys("#{type}:=#{text}") - end - - def submit_filter - find('.add-issues-modal .filtered-search').native.send_keys(:enter) - end - - def click_filter_link(link_text) - page.within('.add-issues-modal .filtered-search-box') do - expect(page).to have_button(link_text) - - click_button(link_text) - end - end -end diff --git a/spec/features/boards/multi_select_spec.rb b/spec/features/boards/multi_select_spec.rb index 162455f75e6..ca322355b8f 100644 --- a/spec/features/boards/multi_select_spec.rb +++ b/spec/features/boards/multi_select_spec.rb @@ -41,6 +41,10 @@ RSpec.describe 'Multi Select Issue', :js do before do project.add_maintainer(user) + # multi-drag disabled with feature flag for now + # https://gitlab.com/gitlab-org/gitlab/-/issues/289797 + stub_feature_flags(graphql_board_lists: false) + sign_in(user) end diff --git a/spec/features/boards/multiple_boards_spec.rb b/spec/features/boards/multiple_boards_spec.rb index 2894d5c7666..219f24f60d7 100644 --- a/spec/features/boards/multiple_boards_spec.rb +++ b/spec/features/boards/multiple_boards_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Multiple Issue Boards', :js do let_it_be(:planning) { create(:label, project: project, name: 'Planning') } let_it_be(:board) { create(:board, name: 'board1', project: project) } let_it_be(:board2) { create(:board, name: 'board2', project: project) } + let(:parent) { project } let(:boards_path) { project_boards_path(project) } diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index f434ea0c66f..20ae569322c 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -3,10 +3,12 @@ require 'spec_helper' RSpec.describe 'Issue Boards new issue', :js do - let(:project) { create(:project, :public) } - let(:board) { create(:board, project: project) } - let!(:list) { create(:list, board: board, position: 0) } - let(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:board) { create(:board, project: project) } + let_it_be(:backlog_list) { create(:backlog_list, board: board) } + let_it_be(:label) { create(:label, project: project, name: 'Label 1') } + let_it_be(:list) { create(:list, board: board, label: label, position: 0) } + let_it_be(:user) { create(:user) } context 'authorized user' do before do @@ -15,6 +17,7 @@ RSpec.describe 'Issue Boards new issue', :js do sign_in(user) visit project_board_path(project, board) + wait_for_requests expect(page).to have_selector('.board', count: 3) @@ -57,7 +60,7 @@ RSpec.describe 'Issue Boards new issue', :js do page.within(first('.board-new-issue-form')) do find('.form-control').set('bug') - click_button 'Submit issue' + click_button 'Create issue' end wait_for_requests @@ -70,23 +73,24 @@ RSpec.describe 'Issue Boards new issue', :js do issue = project.issues.find_by_title('bug') expect(page).to have_content(issue.to_reference) - expect(page).to have_link(issue.title, href: issue_path(issue)) + expect(page).to have_link(issue.title, href: /#{issue_path(issue)}/) end end - it 'shows sidebar when creating new issue' do + # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/323446 + xit 'shows sidebar when creating new issue' do page.within(first('.board')) do find('.issue-count-badge-add-button').click end page.within(first('.board-new-issue-form')) do find('.form-control').set('bug') - click_button 'Submit issue' + click_button 'Create issue' end wait_for_requests - expect(page).to have_selector('.issue-boards-sidebar') + expect(page).to have_selector('[data-testid="issue-boards-sidebar"]') end it 'successfuly loads labels to be added to newly created issue' do @@ -96,17 +100,21 @@ RSpec.describe 'Issue Boards new issue', :js do page.within(first('.board-new-issue-form')) do find('.form-control').set('new issue') - click_button 'Submit issue' + click_button 'Create issue' end wait_for_requests - page.within(first('.issue-boards-sidebar')) do - find('.labels .edit-link').click + page.within(first('.board')) do + find('.board-card').click + end + + page.within(first('[data-testid="issue-boards-sidebar"]')) do + find('.labels [data-testid="edit-button"]').click wait_for_requests - expect(page).to have_selector('.labels .dropdown-content li a') + expect(page).to have_selector('.labels-select-contents-list .dropdown-content li a') end end end diff --git a/spec/features/boards/reload_boards_on_browser_back_spec.rb b/spec/features/boards/reload_boards_on_browser_back_spec.rb index 181cbcc9811..36682036d48 100644 --- a/spec/features/boards/reload_boards_on_browser_back_spec.rb +++ b/spec/features/boards/reload_boards_on_browser_back_spec.rb @@ -27,7 +27,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do fill_in 'issue_title', with: 'issue should be shown' - click_button 'Submit issue' + click_button 'Create issue' page.go_back wait_for_requests @@ -43,7 +43,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do issue = project.issues.find_by_title('issue should be shown') expect(page).to have_content(issue.to_reference) - expect(page).to have_link(issue.title, href: issue_path(issue)) + expect(page).to have_link(issue.title, href: /#{issue_path(issue)}/) end end end diff --git a/spec/features/boards/sidebar_assignee_spec.rb b/spec/features/boards/sidebar_assignee_spec.rb new file mode 100644 index 00000000000..e938612163f --- /dev/null +++ b/spec/features/boards/sidebar_assignee_spec.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Project issue boards sidebar assignee', :js do + include BoardHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:development) { create(:label, project: project, name: 'Development') } + let_it_be(:regression) { create(:label, project: project, name: 'Regression') } + let_it_be(:stretch) { create(:label, project: project, name: 'Stretch') } + + let!(:issue1) { create(:labeled_issue, project: project, assignees: [user], labels: [development], relative_position: 2) } + let!(:issue2) { create(:labeled_issue, project: project, labels: [development, stretch], relative_position: 1) } + let(:board) { create(:board, project: project) } + let!(:list) { create(:list, board: board, label: development, position: 0) } + let(:card) { find('.board:nth-child(2)').first('.board-card') } + + before do + project.add_maintainer(user) + + sign_in(user) + + visit project_board_path(project, board) + wait_for_requests + end + + context 'assignee' do + it 'updates the issues assignee' do + click_card(card) + + page.within('.assignee') do + click_button('Edit') + + wait_for_requests + + assignee = first('.gl-avatar-labeled').find('.gl-avatar-labeled-label').text + + page.within('.dropdown-menu-user') do + first('.gl-avatar-labeled').click + end + + click_button('Apply') + wait_for_requests + + expect(page).to have_content(assignee) + end + + expect(card).to have_selector('.avatar') + end + + it 'removes the assignee' do + card_two = find('.board:nth-child(2)').find('.board-card:nth-child(2)') + click_card(card_two) + + page.within('.assignee') do + click_button('Edit') + + wait_for_requests + + page.within('.dropdown-menu-user') do + find('[data-testid="unassign"]').click + end + + click_button('Apply') + wait_for_requests + + expect(page).to have_content('None') + end + + expect(card_two).not_to have_selector('.avatar') + end + + it 'assignees to current user' do + click_card(card) + + page.within(find('.assignee')) do + expect(page).to have_content('None') + + click_button 'assign yourself' + + wait_for_requests + + expect(page).to have_content(user.name) + end + + expect(card).to have_selector('.avatar') + end + + it 'updates assignee dropdown' do + click_card(card) + + page.within('.assignee') do + click_button('Edit') + + wait_for_requests + + assignee = first('.gl-avatar-labeled').find('.gl-avatar-labeled-label').text + + page.within('.dropdown-menu-user') do + first('.gl-avatar-labeled').click + end + + click_button('Apply') + wait_for_requests + + expect(page).to have_content(assignee) + end + + page.within(find('.board:nth-child(2)')) do + find('.board-card:nth-child(2)').click + end + + page.within('.assignee') do + click_button('Edit') + + expect(find('.dropdown-menu')).to have_selector('.gl-new-dropdown-item-check-icon') + end + end + end +end diff --git a/spec/features/boards/sidebar_due_date_spec.rb b/spec/features/boards/sidebar_due_date_spec.rb new file mode 100644 index 00000000000..141c574ffec --- /dev/null +++ b/spec/features/boards/sidebar_due_date_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Project issue boards sidebar due date', :js do + include BoardHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:issue) { create(:issue, project: project, relative_position: 1) } + let_it_be(:board) { create(:board, project: project) } + let_it_be(:list) { create(:list, board: board, position: 0) } + + let(:card) { find('.board:nth-child(1)').first('.board-card') } + + around do |example| + freeze_time { example.run } + end + + before do + project.add_maintainer(user) + + sign_in(user) + + visit project_board_path(project, board) + wait_for_requests + end + + context 'due date' do + it 'updates due date' do + click_card(card) + + page.within('[data-testid="sidebar-due-date"]') do + today = Date.today.day + + click_button 'Edit' + + click_button today.to_s + + wait_for_requests + + expect(page).to have_content(today.to_s(:medium)) + end + end + end +end diff --git a/spec/features/boards/sidebar_labels_spec.rb b/spec/features/boards/sidebar_labels_spec.rb new file mode 100644 index 00000000000..2f0230c61d8 --- /dev/null +++ b/spec/features/boards/sidebar_labels_spec.rb @@ -0,0 +1,166 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Project issue boards sidebar labels', :js do + include BoardHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:development) { create(:label, project: project, name: 'Development') } + let_it_be(:bug) { create(:label, project: project, name: 'Bug') } + let_it_be(:regression) { create(:label, project: project, name: 'Regression') } + let_it_be(:stretch) { create(:label, project: project, name: 'Stretch') } + let_it_be(:issue1) { create(:labeled_issue, project: project, labels: [development], relative_position: 2) } + let_it_be(:issue2) { create(:labeled_issue, project: project, labels: [development, stretch], relative_position: 1) } + let_it_be(:board) { create(:board, project: project) } + let_it_be(:list) { create(:list, board: board, label: development, position: 0) } + + let(:card) { find('.board:nth-child(2)').first('.board-card') } + + before do + project.add_maintainer(user) + + sign_in(user) + + visit project_board_path(project, board) + wait_for_requests + end + + context 'labels' do + # https://gitlab.com/gitlab-org/gitlab/-/issues/322725 + xit 'shows current labels when editing' do + click_card(card) + + page.within('.labels') do + click_link 'Edit' + + wait_for_requests + + page.within('.value') do + expect(page).to have_selector('.gl-label-text', count: 2) + expect(page).to have_content(development.title) + expect(page).to have_content(stretch.title) + end + end + end + + it 'adds a single label' do + click_card(card) + + page.within('.labels') do + click_button 'Edit' + + wait_for_requests + + click_link bug.title + + find('[data-testid="close-icon"]').click + + wait_for_requests + + page.within('.value') do + expect(page).to have_selector('.gl-label-text', count: 3) + expect(page).to have_content(bug.title) + end + end + + # 'Development' label does not show since the card is in a 'Development' list label + expect(card).to have_selector('.gl-label', count: 2) + expect(card).to have_content(bug.title) + end + + it 'adds a multiple labels' do + click_card(card) + + page.within('.labels') do + click_button 'Edit' + + wait_for_requests + + click_link bug.title + + click_link regression.title + + find('[data-testid="close-icon"]').click + + wait_for_requests + + page.within('.value') do + expect(page).to have_selector('.gl-label-text', count: 4) + expect(page).to have_content(bug.title) + expect(page).to have_content(regression.title) + end + end + + # 'Development' label does not show since the card is in a 'Development' list label + expect(card).to have_selector('.gl-label', count: 3) + expect(card).to have_content(bug.title) + expect(card).to have_content(regression.title) + end + + it 'removes a label' do + click_card(card) + + page.within('.labels') do + click_button 'Edit' + + wait_for_requests + + click_link stretch.title + + find('[data-testid="close-icon"]').click + + wait_for_requests + + page.within('.value') do + expect(page).to have_selector('.gl-label-text', count: 1) + expect(page).not_to have_content(stretch.title) + end + end + + # 'Development' label does not show since the card is in a 'Development' list label + expect(card).to have_selector('.gl-label-text', count: 0) + expect(card).not_to have_content(stretch.title) + end + + # https://gitlab.com/gitlab-org/gitlab/-/issues/324290 + xit 'creates project label' do + click_card(card) + + page.within('.labels') do + click_link 'Edit' + wait_for_requests + + click_link 'Create project label' + fill_in 'new_label_name', with: 'test label' + first('.suggest-colors-dropdown a').click + click_button 'Create' + wait_for_requests + + expect(page).to have_link 'test label' + end + expect(page).to have_selector('.board', count: 3) + end + + # https://gitlab.com/gitlab-org/gitlab/-/issues/324290 + xit 'creates project label and list' do + click_card(card) + + page.within('.labels') do + click_link 'Edit' + wait_for_requests + + click_link 'Create project label' + fill_in 'new_label_name', with: 'test label' + first('.suggest-colors-dropdown a').click + first('.js-add-list').click + click_button 'Create' + wait_for_requests + + expect(page).to have_link 'test label' + end + expect(page).to have_selector('.board', count: 4) + end + end +end diff --git a/spec/features/boards/sidebar_milestones_spec.rb b/spec/features/boards/sidebar_milestones_spec.rb new file mode 100644 index 00000000000..54182781a30 --- /dev/null +++ b/spec/features/boards/sidebar_milestones_spec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Project issue boards sidebar milestones', :js do + include BoardHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:milestone) { create(:milestone, project: project) } + let_it_be(:issue1) { create(:issue, project: project, relative_position: 1) } + let_it_be(:issue2) { create(:issue, project: project, milestone: milestone, relative_position: 2) } + let_it_be(:board) { create(:board, project: project) } + let_it_be(:list) { create(:list, board: board, position: 0) } + + let(:card1) { find('.board:nth-child(1) .board-card:nth-of-type(1)') } + let(:card2) { find('.board:nth-child(1) .board-card:nth-of-type(2)') } + + before do + project.add_maintainer(user) + + sign_in(user) + + visit project_board_path(project, board) + wait_for_requests + end + + context 'milestone' do + it 'adds a milestone' do + click_card(card1) + + page.within('[data-testid="sidebar-milestones"]') do + click_button 'Edit' + + wait_for_requests + + click_button milestone.title + + wait_for_requests + + page.within('.value') do + expect(page).to have_content(milestone.title) + end + end + end + + it 'removes a milestone' do + click_card(card2) + + page.within('[data-testid="sidebar-milestones"]') do + click_button 'Edit' + + wait_for_requests + + click_button "No milestone" + + wait_for_requests + + page.within('.value') do + expect(page).not_to have_content(milestone.title) + end + end + end + end +end diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index c79bf2abff1..977147c3c6b 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -2,412 +2,33 @@ require 'spec_helper' -RSpec.describe 'Issue Boards', :js do +RSpec.describe 'Project issue boards sidebar', :js do include BoardHelpers - include FilteredSearchHelpers - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:project) { create(:project, :public) } - let!(:milestone) { create(:milestone, project: project) } - let!(:development) { create(:label, project: project, name: 'Development') } - let!(:bug) { create(:label, project: project, name: 'Bug') } - let!(:regression) { create(:label, project: project, name: 'Regression') } - let!(:stretch) { create(:label, project: project, name: 'Stretch') } - let!(:issue1) { create(:labeled_issue, project: project, assignees: [user], milestone: milestone, labels: [development], relative_position: 2) } - let!(:issue2) { create(:labeled_issue, project: project, labels: [development, stretch], relative_position: 1) } - let(:board) { create(:board, project: project) } - let!(:list) { create(:list, board: board, label: development, position: 0) } - let(:card) { find('.board:nth-child(2)').first('.board-card') } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:board) { create(:board, project: project) } + let_it_be(:list) { create(:list, board: board, position: 0) } - let(:application_settings) { {} } - - around do |example| - freeze_time { example.run } - end + let_it_be(:issue, reload: true) { create(:issue, project: project, relative_position: 1) } before do project.add_maintainer(user) sign_in(user) - stub_application_setting(application_settings) - visit project_board_path(project, board) - wait_for_requests - end - - it 'shows sidebar when clicking issue' do - click_card(card) - - expect(page).to have_selector('.issue-boards-sidebar') - end - - it 'closes sidebar when clicking issue' do - click_card(card) - - expect(page).to have_selector('.issue-boards-sidebar') - - click_card(card) - - expect(page).not_to have_selector('.issue-boards-sidebar') - end - - it 'closes sidebar when clicking close button' do - click_card(card) - - expect(page).to have_selector('.issue-boards-sidebar') - - find('.gutter-toggle').click - - expect(page).not_to have_selector('.issue-boards-sidebar') - end - - it 'shows issue details when sidebar is open' do - click_card(card) - - page.within('.issue-boards-sidebar') do - expect(page).to have_content(issue2.title) - expect(page).to have_content(issue2.to_reference) - end - end - - context 'assignee' do - it 'updates the issues assignee' do - click_card(card) - - page.within('.assignee') do - click_button('Edit') - - wait_for_requests - - assignee = first('.gl-avatar-labeled').find('.gl-avatar-labeled-label').text - - page.within('.dropdown-menu-user') do - first('.gl-avatar-labeled').click - end - - click_button('Edit') - wait_for_requests - - expect(page).to have_content(assignee) - end - - expect(card).to have_selector('.avatar') - end - - it 'removes the assignee' do - card_two = find('.board:nth-child(2)').find('.board-card:nth-child(2)') - click_card(card_two) - - page.within('.assignee') do - click_button('Edit') - - wait_for_requests - - page.within('.dropdown-menu-user') do - find('[data-testid="unassign"]').click - end - - click_button('Edit') - wait_for_requests - - expect(page).to have_content('None') - end - - expect(card_two).not_to have_selector('.avatar') - end - - it 'assignees to current user' do - click_card(card) - - page.within(find('.assignee')) do - expect(page).to have_content('None') - - click_button 'assign yourself' - - wait_for_requests - - expect(page).to have_content(user.name) - end - - expect(card).to have_selector('.avatar') - end - - it 'updates assignee dropdown' do - click_card(card) - - page.within('.assignee') do - click_button('Edit') - - wait_for_requests - - assignee = first('.gl-avatar-labeled').find('.gl-avatar-labeled-label').text - - page.within('.dropdown-menu-user') do - first('.gl-avatar-labeled').click - end - - click_button('Edit') - wait_for_requests - - expect(page).to have_content(assignee) - end - - page.within(find('.board:nth-child(2)')) do - find('.board-card:nth-child(2)').click - end - - page.within('.assignee') do - click_button('Edit') - - expect(find('.dropdown-menu')).to have_selector('.gl-new-dropdown-item-check-icon') - end - end - end - - context 'milestone' do - it 'adds a milestone' do - click_card(card) - - page.within('.milestone') do - click_link 'Edit' - - wait_for_requests - - click_link milestone.title - - wait_for_requests - - page.within('.value') do - expect(page).to have_content(milestone.title) - end - end - end - - it 'removes a milestone' do - click_card(card) - page.within('.milestone') do - click_link 'Edit' - - wait_for_requests - - click_link "No milestone" - - wait_for_requests - - page.within('.value') do - expect(page).not_to have_content(milestone.title) - end - end - end - end - - context 'time tracking' do - let(:compare_meter_tooltip) { find('.time-tracking .time-tracking-content .compare-meter')['title'] } - - before do - issue2.timelogs.create(time_spent: 14400, user: user) - issue2.update!(time_estimate: 128800) - - click_card(card) - end - - it 'shows time tracking progress bar' do - expect(compare_meter_tooltip).to eq('Time remaining: 3d 7h 46m') - end - - context 'when time_tracking_limit_to_hours is true' do - let(:application_settings) { { time_tracking_limit_to_hours: true } } - - it 'shows time tracking progress bar' do - expect(compare_meter_tooltip).to eq('Time remaining: 31h 46m') - end - end - end - - context 'due date' do - it 'updates due date' do - click_card(card) - - page.within('.due_date') do - click_link 'Edit' - - click_button Date.today.day - - wait_for_requests - - expect(page).to have_content(Date.today.to_s(:medium)) - end - end + wait_for_requests end - context 'labels' do - it 'shows current labels when editing' do - click_card(card) - - page.within('.labels') do - click_link 'Edit' - - wait_for_requests - - page.within('.value') do - expect(page).to have_selector('.gl-label-text', count: 2) - expect(page).to have_content(development.title) - expect(page).to have_content(stretch.title) - end - end - end - - it 'adds a single label' do - click_card(card) - - page.within('.labels') do - click_link 'Edit' - - wait_for_requests - - click_link bug.title - - wait_for_requests - - find('.dropdown-menu-close-icon').click - - page.within('.value') do - expect(page).to have_selector('.gl-label-text', count: 3) - expect(page).to have_content(bug.title) - end - end - - # 'Development' label does not show since the card is in a 'Development' list label - expect(card).to have_selector('.gl-label', count: 2) - expect(card).to have_content(bug.title) - end - - it 'adds a multiple labels' do - click_card(card) + it_behaves_like 'issue boards sidebar' - page.within('.labels') do - click_link 'Edit' - - wait_for_requests - - click_link bug.title - - wait_for_requests - - click_link regression.title - - wait_for_requests - - find('.dropdown-menu-close-icon').click - - page.within('.value') do - expect(page).to have_selector('.gl-label-text', count: 4) - expect(page).to have_content(bug.title) - expect(page).to have_content(regression.title) - end - end - - # 'Development' label does not show since the card is in a 'Development' list label - expect(card).to have_selector('.gl-label', count: 3) - expect(card).to have_content(bug.title) - expect(card).to have_content(regression.title) - end - - it 'removes a label' do - click_card(card) - - page.within('.labels') do - click_link 'Edit' - - wait_for_requests - - within('.dropdown-menu-labels') do - click_link stretch.title - end - - wait_for_requests - - find('.dropdown-menu-close-icon').click - - page.within('.value') do - expect(page).to have_selector('.gl-label-text', count: 1) - expect(page).not_to have_content(stretch.title) - end - end - - # 'Development' label does not show since the card is in a 'Development' list label - expect(card).to have_selector('.gl-label-text', count: 0) - expect(card).not_to have_content(stretch.title) - end - - it 'creates project label' do - click_card(card) - - page.within('.labels') do - click_link 'Edit' - wait_for_requests - - click_link 'Create project label' - fill_in 'new_label_name', with: 'test label' - first('.suggest-colors-dropdown a').click - click_button 'Create' - wait_for_requests - - expect(page).to have_link 'test label' - end - expect(page).to have_selector('.board', count: 3) - end - - it 'creates project label and list' do - click_card(card) - - page.within('.labels') do - click_link 'Edit' - wait_for_requests - - click_link 'Create project label' - fill_in 'new_label_name', with: 'test label' - first('.suggest-colors-dropdown a').click - first('.js-add-list').click - click_button 'Create' - wait_for_requests - - expect(page).to have_link 'test label' - end - expect(page).to have_selector('.board', count: 4) - end + def first_card + find('.board:nth-child(1)').first("[data-testid='board_card']") end - context 'subscription' do - it 'changes issue subscription' do - click_card(card) - wait_for_requests - - page.within('.subscriptions') do - find('[data-testid="subscription-toggle"] button:not(.is-checked)').click - wait_for_requests - - expect(page).to have_css('[data-testid="subscription-toggle"] button.is-checked') - end - end - - it 'has checked subscription toggle when already subscribed' do - create(:subscription, user: user, project: project, subscribable: issue2, subscribed: true) - visit project_board_path(project, board) - wait_for_requests - - click_card(card) - wait_for_requests - - page.within('.subscriptions') do - find('[data-testid="subscription-toggle"] button.is-checked').click - wait_for_requests - - expect(page).to have_css('[data-testid="subscription-toggle"] button:not(.is-checked)') - end - end + def click_first_issue_card + click_card(first_card) end end diff --git a/spec/features/boards/sub_group_project_spec.rb b/spec/features/boards/sub_group_project_spec.rb index cd3d61726f6..bde5f061a67 100644 --- a/spec/features/boards/sub_group_project_spec.rb +++ b/spec/features/boards/sub_group_project_spec.rb @@ -21,7 +21,8 @@ RSpec.describe 'Sub-group project issue boards', :js do wait_for_requests end - it 'creates new label from sidebar' do + # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/324290 + xit 'creates new label from sidebar' do find('.board-card').click page.within '.labels' do diff --git a/spec/features/boards/user_adds_lists_to_board_spec.rb b/spec/features/boards/user_adds_lists_to_board_spec.rb index b9945207bb2..5128fc4004e 100644 --- a/spec/features/boards/user_adds_lists_to_board_spec.rb +++ b/spec/features/boards/user_adds_lists_to_board_spec.rb @@ -71,10 +71,13 @@ RSpec.describe 'User adds lists', :js do def select_label(board_new_list_enabled, label) if board_new_list_enabled - page.within('.board-add-new-list') do - find('label', text: label.title).click - click_button 'Add' - end + click_button 'Select a label' + + find('label', text: label.title).click + + click_button 'Add to board' + + wait_for_all_requests else page.within('.dropdown-menu-issues-board-new') do click_link label.title |