gitlab-org--gitlab-foss/spec/features/boards/boards_spec.rb
Mike Greiling 519ffa1ebf
Merge branch 'master' into sh-headless-chrome-support
* master: (297 commits)
  Fix deletion of container registry or images returning an error
  The fog-aliyun gem had a bug in v0.1.0 for file storage creation/update. This merge requests update the gem to v0.2.0 which contains the fix:
  Decrease ABC threshold to 54.28
  Update VERSION to 10.2.0-pre
  Update CHANGELOG.md for 10.1.0
  Document `CI_SHARED_ENVIRONMENT` and `CI_DISPOSABLE_ENVIRONMENT`
  Fix the external URLs generated for online view of HTML artifacts
  Use title as placeholder instead of issue title for reusability
  Fix failure in current_settings_spec.rb
  Clarify the difference between project_update and project_rename
  URI decode Page-Title header to preserve UTF-8 characters
  Update Gitaly version to v0.49.0
  Decrease Perceived Complexity threshold to 14
  Resolve "Remove help text regarding group issues on group issues page (and group merge requests page)"
  Force non diff resolved discussion to display when collapse toggled
  Added submodule support in multi-file editor
  add note about after_script being run separately
  Check for element before evaluate_script
  Merge branch 'master-i18n' into 'master'
  Update Prometheus gem to fix problems with other files overwriting current file
  ...
2017-10-23 10:32:14 +03:00

606 lines
19 KiB
Ruby

require 'rails_helper'
describe 'Issue Boards', :js do
include CookieHelper
include DragTo
let(:group) { create(:group, :nested) }
let(:project) { create(:project, :public, namespace: group) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let!(:user2) { create(:user) }
before do
project.team << [user, :master]
project.team << [user2, :master]
set_cookie('sidebar_collapsed', 'true')
sign_in(user)
end
context 'no lists' do
before do
visit project_board_path(project, board)
wait_for_requests
expect(page).to have_selector('.board', count: 3)
end
it 'shows blank state' do
expect(page).to have_content('Welcome to your Issue Board!')
end
it 'shows tooltip on add issues button' do
button = page.find('.filter-dropdown-container button', text: 'Add issues')
expect(button[:"data-original-title"]).to eq("Please add a list to your board first")
end
it 'hides the blank state when clicking nevermind button' do
page.within(find('.board-blank-state')) do
click_button("Nevermind, I'll use my own")
end
expect(page).to have_selector('.board', count: 2)
end
it 'creates default lists' do
lists = ['Backlog', 'To Do', 'Doing', 'Closed']
page.within(find('.board-blank-state')) do
click_button('Add default lists')
end
wait_for_requests
expect(page).to have_selector('.board', count: 4)
page.all('.board').each_with_index do |list, i|
expect(list.find('.board-title')).to have_content(lists[i])
end
end
end
context 'with lists' do
let(:milestone) { create(:milestone, project: project) }
let(:planning) { create(:label, project: project, name: 'Planning', description: 'Test') }
let(:development) { create(:label, project: project, name: 'Development') }
let(:testing) { create(:label, project: project, name: 'Testing') }
let(:bug) { create(:label, project: project, name: 'Bug') }
let!(:backlog) { create(:label, project: project, name: 'Backlog') }
let!(:closed) { create(:label, project: project, name: 'Closed') }
let!(:accepting) { create(:label, project: project, name: 'Accepting Merge Requests') }
let!(:list1) { create(:list, board: board, label: planning, position: 0) }
let!(:list2) { create(:list, board: board, label: development, position: 1) }
let!(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning], relative_position: 9) }
let!(:issue1) { create(:labeled_issue, project: project, title: 'aaa', description: '111', assignees: [user], labels: [planning], relative_position: 8) }
let!(:issue2) { create(:labeled_issue, project: project, title: 'bbb', description: '222', author: user2, labels: [planning], relative_position: 7) }
let!(:issue3) { create(:labeled_issue, project: project, title: 'ccc', description: '333', labels: [planning], relative_position: 6) }
let!(:issue4) { create(:labeled_issue, project: project, title: 'ddd', description: '444', labels: [planning], relative_position: 5) }
let!(:issue5) { create(:labeled_issue, project: project, title: 'eee', description: '555', labels: [planning], milestone: milestone, relative_position: 4) }
let!(:issue6) { create(:labeled_issue, project: project, title: 'fff', description: '666', labels: [planning, development], relative_position: 3) }
let!(:issue7) { create(:labeled_issue, project: project, title: 'ggg', description: '777', labels: [development], relative_position: 2) }
let!(:issue8) { create(:closed_issue, project: project, title: 'hhh', description: '888') }
let!(:issue9) { create(:labeled_issue, project: project, title: 'iii', description: '999', labels: [planning, testing, bug, accepting], relative_position: 1) }
before do
visit project_board_path(project, board)
wait_for_requests
expect(page).to have_selector('.board', count: 4)
expect(find('.board:nth-child(2)')).to have_selector('.card')
expect(find('.board:nth-child(3)')).to have_selector('.card')
expect(find('.board:nth-child(4)')).to have_selector('.card')
end
it 'shows description tooltip on list title' do
page.within('.board:nth-child(2)') do
expect(find('.board-title span.has-tooltip')[:title]).to eq('Test')
end
end
it 'shows issues in lists' do
wait_for_board_cards(2, 8)
wait_for_board_cards(3, 2)
end
it 'shows confidential issues with icon' do
page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.confidential-icon', count: 1)
end
end
it 'search closed list' do
find('.filtered-search').set(issue8.title)
find('.filtered-search').native.send_keys(:enter)
wait_for_requests
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(4)')).to have_selector('.card', count: 1)
end
it 'search list' do
find('.filtered-search').set(issue5.title)
find('.filtered-search').native.send_keys(:enter)
wait_for_requests
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 1)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(4)')).to have_selector('.card', count: 0)
end
it 'allows user to delete board' do
page.within(find('.board:nth-child(2)')) do
accept_confirm { find('.board-delete').click }
end
wait_for_requests
expect(page).to have_selector('.board', count: 3)
end
it 'removes checkmark in new list dropdown after deleting' do
click_button 'Add list'
wait_for_requests
find('.dropdown-menu-close').click
page.within(find('.board:nth-child(2)')) do
accept_confirm { find('.board-delete').click }
end
wait_for_requests
expect(page).to have_selector('.board', count: 3)
end
it 'infinite scrolls list' do
50.times do
create(:labeled_issue, project: project, labels: [planning])
end
visit project_board_path(project, board)
wait_for_requests
page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('58')
expect(page).to have_selector('.card', count: 20)
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
expect(page).to have_selector('.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
expect(page).to have_selector('.card', count: 58)
expect(page).to have_content('Showing all issues')
end
end
context 'closed' do
it 'shows list of closed issues' do
wait_for_board_cards(4, 1)
wait_for_requests
end
it 'moves issue to closed' do
drag(list_from_index: 1, list_to_index: 3)
wait_for_board_cards(2, 7)
wait_for_board_cards(3, 2)
wait_for_board_cards(4, 2)
expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
expect(find('.board:nth-child(4)')).to have_selector('.card', count: 2)
expect(find('.board:nth-child(4)')).to have_content(issue9.title)
expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
end
it 'removes all of the same issue to closed' do
drag(list_from_index: 1, list_to_index: 3)
wait_for_board_cards(2, 7)
wait_for_board_cards(3, 2)
wait_for_board_cards(4, 2)
expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
expect(find('.board:nth-child(4)')).to have_content(issue9.title)
expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
end
end
context 'lists' do
it 'changes position of list' do
drag(list_from_index: 2, list_to_index: 1, selector: '.board-header')
wait_for_board_cards(2, 2)
wait_for_board_cards(3, 8)
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)
end
it 'issue moves between lists' do
drag(list_from_index: 1, from_index: 1, list_to_index: 2)
wait_for_board_cards(2, 7)
wait_for_board_cards(3, 2)
wait_for_board_cards(4, 1)
expect(find('.board:nth-child(3)')).to have_content(issue6.title)
expect(find('.board:nth-child(3)').all('.card').last).to have_content(development.title)
end
it 'issue moves between lists' do
drag(list_from_index: 2, list_to_index: 1)
wait_for_board_cards(2, 9)
wait_for_board_cards(3, 1)
wait_for_board_cards(4, 1)
expect(find('.board:nth-child(2)')).to have_content(issue7.title)
expect(find('.board:nth-child(2)').all('.card').first).to have_content(planning.title)
end
it 'issue moves from closed' do
drag(list_from_index: 2, list_to_index: 3)
wait_for_board_cards(2, 8)
wait_for_board_cards(3, 1)
wait_for_board_cards(4, 2)
expect(find('.board:nth-child(4)')).to have_content(issue8.title)
end
context 'issue card' do
it 'shows assignee' do
page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.avatar', count: 1)
end
end
end
context 'new list' do
it 'shows all labels in new list dropdown' do
click_button 'Add list'
wait_for_requests
page.within('.dropdown-menu-issues-board-new') do
expect(page).to have_content(planning.title)
expect(page).to have_content(development.title)
expect(page).to have_content(testing.title)
end
end
it 'creates new list for label' do
click_button 'Add list'
wait_for_requests
page.within('.dropdown-menu-issues-board-new') do
click_link testing.title
end
wait_for_requests
expect(page).to have_selector('.board', count: 5)
end
it 'creates new list for Backlog label' do
click_button 'Add list'
wait_for_requests
page.within('.dropdown-menu-issues-board-new') do
click_link backlog.title
end
wait_for_requests
expect(page).to have_selector('.board', count: 5)
end
it 'creates new list for Closed label' do
click_button 'Add list'
wait_for_requests
page.within('.dropdown-menu-issues-board-new') do
click_link closed.title
end
wait_for_requests
expect(page).to have_selector('.board', count: 5)
end
it 'keeps dropdown open after adding new list' do
click_button 'Add list'
wait_for_requests
page.within('.dropdown-menu-issues-board-new') do
click_link closed.title
end
wait_for_requests
expect(page).to have_css('#js-add-list.open')
end
it 'creates new list from a new label' do
click_button 'Add list'
wait_for_requests
click_link 'Create new label'
fill_in('new_label_name', with: 'Testing New Label')
first('.suggest-colors a').click
click_button 'Create'
wait_for_requests
wait_for_requests
expect(page).to have_selector('.board', count: 5)
end
end
end
context 'filtering' do
it 'filters by author' do
set_filter("author", user2.username)
click_filter_link(user2.username)
submit_filter
wait_for_requests
wait_for_board_cards(2, 1)
wait_for_empty_boards((3..4))
end
it 'filters by assignee' do
set_filter("assignee", user.username)
click_filter_link(user.username)
submit_filter
wait_for_requests
wait_for_board_cards(2, 1)
wait_for_empty_boards((3..4))
end
it 'filters by milestone' do
set_filter("milestone", "\"#{milestone.title}")
click_filter_link(milestone.title)
submit_filter
wait_for_requests
wait_for_board_cards(2, 1)
wait_for_board_cards(3, 0)
wait_for_board_cards(4, 0)
end
it 'filters by label' do
set_filter("label", testing.title)
click_filter_link(testing.title)
submit_filter
wait_for_requests
wait_for_board_cards(2, 1)
wait_for_empty_boards((3..4))
end
it 'filters by label with space after reload' do
set_filter("label", "\"#{accepting.title}")
click_filter_link(accepting.title)
submit_filter
# Test after reload
page.evaluate_script 'window.location.reload()'
wait_for_board_cards(2, 1)
wait_for_empty_boards((3..4))
wait_for_requests
page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('1')
expect(page).to have_selector('.card', count: 1)
end
page.within(find('.board:nth-child(3)')) do
expect(page.find('.board-header')).to have_content('0')
expect(page).to have_selector('.card', count: 0)
end
end
it 'removes filtered labels' do
set_filter("label", testing.title)
click_filter_link(testing.title)
submit_filter
wait_for_board_cards(2, 1)
find('.clear-search').click
submit_filter
wait_for_board_cards(2, 8)
end
it 'infinite scrolls list with label filter' do
50.times do
create(:labeled_issue, project: project, labels: [planning, testing])
end
set_filter("label", testing.title)
click_filter_link(testing.title)
submit_filter
wait_for_requests
page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('51')
expect(page).to have_selector('.card', count: 20)
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")
expect(page).to have_selector('.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")
expect(page).to have_selector('.card', count: 51)
expect(page).to have_content('Showing all issues')
end
end
it 'filters by multiple labels' do
set_filter("label", testing.title)
click_filter_link(testing.title)
set_filter("label", bug.title)
click_filter_link(bug.title)
submit_filter
wait_for_requests
wait_for_board_cards(2, 1)
wait_for_empty_boards((3..4))
end
it 'filters by clicking label button on issue' do
page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.card', count: 8)
expect(find('.card', match: :first)).to have_content(bug.title)
click_button(bug.title)
wait_for_requests
end
page.within('.tokens-container') do
expect(page).to have_content(bug.title)
end
wait_for_requests
wait_for_board_cards(2, 1)
wait_for_empty_boards((3..4))
end
it 'removes label filter by clicking label button on issue' do
page.within(find('.board:nth-child(2)')) do
page.within(find('.card', match: :first)) do
click_button(bug.title)
end
wait_for_requests
expect(page).to have_selector('.card', count: 1)
end
wait_for_requests
end
end
end
context 'keyboard shortcuts' do
before do
visit project_board_path(project, board)
wait_for_requests
end
it 'allows user to use keyboard shortcuts' do
find('body').native.send_keys('i')
expect(page).to have_content('New Issue')
end
end
context 'signed out user' do
before do
sign_out(:user)
visit project_board_path(project, board)
wait_for_requests
end
it 'displays lists' do
expect(page).to have_selector('.board')
end
it 'does not show create new list' do
expect(page).not_to have_selector('.js-new-board-list')
end
it 'does not allow dragging' do
expect(page).not_to have_selector('.user-can-drag')
end
end
context 'as guest user' do
let(:user_guest) { create(:user) }
before do
project.team << [user_guest, :guest]
sign_out(:user)
sign_in(user_guest)
visit project_board_path(project, board)
wait_for_requests
end
it 'does not show create new list' do
expect(page).not_to have_selector('.js-new-board-list')
end
end
def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0)
# ensure there is enough horizontal space for four boards
page.current_window.resize_to(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)
end
def wait_for_board_cards(board_number, expected_cards)
page.within(find(".board:nth-child(#{board_number})")) do
expect(page.find('.board-header')).to have_content(expected_cards.to_s)
expect(page).to have_selector('.card', count: expected_cards)
end
end
def wait_for_empty_boards(board_numbers)
board_numbers.each do |board|
wait_for_board_cards(board, 0)
end
end
def set_filter(type, text)
find('.filtered-search').native.send_keys("#{type}:#{text}")
end
def submit_filter
find('.filtered-search').native.send_keys(:enter)
end
def click_filter_link(link_text)
page.within('.filtered-search-box') do
expect(page).to have_button(link_text)
click_button(link_text)
end
end
end