diff options
author | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 22:34:23 +0300 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2021-01-20 22:34:23 +0300 |
commit | 6438df3a1e0fb944485cebf07976160184697d72 (patch) | |
tree | 00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /spec/features/issues | |
parent | 42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff) |
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'spec/features/issues')
-rw-r--r-- | spec/features/issues/gfm_autocomplete_spec.rb | 163 | ||||
-rw-r--r-- | spec/features/issues/issue_sidebar_spec.rb | 358 | ||||
-rw-r--r-- | spec/features/issues/issue_state_spec.rb | 10 | ||||
-rw-r--r-- | spec/features/issues/user_comments_on_issue_spec.rb | 1 | ||||
-rw-r--r-- | spec/features/issues/user_creates_issue_spec.rb | 4 |
5 files changed, 324 insertions, 212 deletions
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 07bf821a590..9b2a11c4b0e 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -294,6 +294,15 @@ RSpec.describe 'GFM autocomplete', :js do user_item = find('.atwho-view li', text: user.username) expect(user_item).to have_content(user.username) end + + it 'does not limit quick actions autocomplete list to 5' do + note = find('#note-body') + page.within '.timeline-content-form' do + note.native.send_keys('/') + end + + expect(page).to have_selector('.atwho-view li', minimum: 6, visible: true) + end end context 'assignees' do @@ -426,36 +435,16 @@ RSpec.describe 'GFM autocomplete', :js do visit project_issue_path(project, issue) note = find('#note-body') - start_comment_with_emoji(note) + start_comment_with_emoji(note, '.atwho-view li') start_and_cancel_discussion note.fill_in(with: '') - start_comment_with_emoji(note) + start_comment_with_emoji(note, '.atwho-view li') note.native.send_keys(:enter) expect(note.value).to eql('Hello :100: ') end - - def start_comment_with_emoji(note) - note.native.send_keys('Hello :10') - - wait_for_requests - - find('.atwho-view li', text: '100') - end - - def start_and_cancel_discussion - click_button('Reply...') - - fill_in('note_note', with: 'Whoops!') - - page.accept_alert 'Are you sure you want to cancel creating this comment?' do - click_button('Cancel') - end - - wait_for_requests - end end shared_examples 'autocomplete suggestions' do @@ -599,6 +588,33 @@ RSpec.describe 'GFM autocomplete', :js do expect(page).not_to have_selector('.tribute-container', visible: true) end + it 'does not open autocomplete menu when ":" is prefixed by a number and letters' do + note = find('#note-body') + + # Number. + page.within '.timeline-content-form' do + note.native.send_keys('7:') + end + + expect(page).not_to have_selector('.tribute-container', visible: true) + + # ASCII letter. + page.within '.timeline-content-form' do + note.set('') + note.native.send_keys('w:') + end + + expect(page).not_to have_selector('.tribute-container', visible: true) + + # Non-ASCII letter. + page.within '.timeline-content-form' do + note.set('') + note.native.send_keys('Ё:') + end + + expect(page).not_to have_selector('.tribute-container', visible: true) + end + it 'selects the first item for assignee dropdowns' do page.within '.timeline-content-form' do find('#note-body').native.send_keys('@') @@ -624,6 +640,16 @@ RSpec.describe 'GFM autocomplete', :js do expect(find('.tribute-container ul', visible: true)).to have_content(user.name) end + it 'selects the first item for non-assignee dropdowns if a query is entered' do + page.within '.timeline-content-form' do + find('#note-body').native.send_keys(':1') + end + + wait_for_requests + + expect(find('.tribute-container ul', visible: true)).to have_selector('.highlight:first-of-type') + end + context 'when autocompleting for groups' do it 'shows the group when searching for the name of the group' do page.within '.timeline-content-form' do @@ -687,20 +713,34 @@ RSpec.describe 'GFM autocomplete', :js do expect_to_wrap(false, user_item, note, user.username) end - it 'triggers autocomplete after selecting a quick action' do + it 'does not wrap for emoji values' do note = find('#note-body') page.within '.timeline-content-form' do - note.native.send_keys('/as') + note.native.send_keys(":cartwheel_") end - find('.atwho-view li', text: '/assign') - note.native.send_keys(:tab) - note.native.send_keys(:right) + emoji_item = first('.tribute-container li', text: 'cartwheel_tone1', visible: true) - wait_for_requests + expect_to_wrap(false, emoji_item, note, 'cartwheel_tone1') + end - user_item = find('.tribute-container ul', text: user.username, visible: true) - expect(user_item).to have_content(user.username) + it 'does not open autocomplete if there is no space before' do + page.within '.timeline-content-form' do + find('#note-body').native.send_keys("hello:#{user.username[0..2]}") + end + + expect(page).not_to have_selector('.tribute-container') + end + + it 'autocompletes for quick actions' do + note = find('#note-body') + page.within '.timeline-content-form' do + note.native.send_keys('/as') + wait_for_requests + note.native.send_keys(:tab) + end + + expect(note.value).to have_text('/assign') end end @@ -719,15 +759,14 @@ RSpec.describe 'GFM autocomplete', :js do note = find('#note-body') page.within '.timeline-content-form' do - note.native.send_keys('/as') + note.native.send_keys('/assign ') + # The `/assign` ajax response might replace the one by `@` below causing a failed test + # so we need to wait for the `/assign` ajax request to finish first + wait_for_requests + note.native.send_keys('@') + wait_for_requests end - find('.atwho-view li', text: '/assign') - note.native.send_keys(:tab) - note.native.send_keys(:right) - - wait_for_requests - expect(find('.tribute-container ul', visible: true)).not_to have_content(user.username) expect(find('.tribute-container ul', visible: true)).to have_content(unassigned_user.username) end @@ -739,12 +778,14 @@ RSpec.describe 'GFM autocomplete', :js do page.within '.timeline-content-form' do note.native.send_keys('/assign @user2') note.native.send_keys(:enter) - note.native.send_keys('/assign @') - note.native.send_keys(:right) + note.native.send_keys('/assign ') + # The `/assign` ajax response might replace the one by `@` below causing a failed test + # so we need to wait for the `/assign` ajax request to finish first + wait_for_requests + note.native.send_keys('@') + wait_for_requests end - wait_for_requests - expect(find('.tribute-container ul', visible: true)).not_to have_content(user.username) expect(find('.tribute-container ul', visible: true)).to have_content(unassigned_user.username) end @@ -824,6 +865,26 @@ RSpec.describe 'GFM autocomplete', :js do end end + context 'when other notes are destroyed' do + let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) } + + # This is meant to protect against this issue https://gitlab.com/gitlab-org/gitlab/-/issues/228729 + it 'keeps autocomplete key listeners' do + visit project_issue_path(project, issue) + note = find('#note-body') + + start_comment_with_emoji(note, '.tribute-container li') + + start_and_cancel_discussion + + note.fill_in(with: '') + start_comment_with_emoji(note, '.tribute-container li') + note.native.send_keys(:enter) + + expect(note.value).to eql('Hello :100: ') + end + end + shared_examples 'autocomplete suggestions' do it 'suggests objects correctly' do page.within '.timeline-content-form' do @@ -913,4 +974,24 @@ RSpec.describe 'GFM autocomplete', :js do note.native.send_keys(text) end end + + def start_comment_with_emoji(note, selector) + note.native.send_keys('Hello :10') + + wait_for_requests + + find(selector, text: '100') + end + + def start_and_cancel_discussion + click_button('Reply...') + + fill_in('note_note', with: 'Whoops!') + + page.accept_alert 'Are you sure you want to cancel creating this comment?' do + click_button('Cancel') + end + + wait_for_requests + end end diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 94a1de06488..59fba5f65e0 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -13,256 +13,280 @@ RSpec.describe 'Issue Sidebar' do let!(:xss_label) { create(:label, project: project, title: '<script>alert("xss");</script>') } before do - sign_in(user) + stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") end - context 'when concerning the assignee', :js do - let(:user2) { create(:user) } - let(:issue2) { create(:issue, project: project, author: user2) } - - include_examples 'issuable invite members experiments' do - let(:issuable_path) { project_issue_path(project, issue2) } + context 'when signed in' do + before do + sign_in(user) end - context 'when user is a developer' do - before do - project.add_developer(user) - visit_issue(project, issue2) - - find('.block.assignee .edit-link').click + context 'when concerning the assignee', :js do + let(:user2) { create(:user) } + let(:issue2) { create(:issue, project: project, author: user2) } - wait_for_requests + include_examples 'issuable invite members experiments' do + let(:issuable_path) { project_issue_path(project, issue2) } end - it 'shows author in assignee dropdown' do - page.within '.dropdown-menu-user' do - expect(page).to have_content(user2.name) - end - end + context 'when user is a developer' do + before do + project.add_developer(user) + visit_issue(project, issue2) - it 'shows author when filtering assignee dropdown' do - page.within '.dropdown-menu-user' do - find('.dropdown-input-field').set(user2.name) + find('.block.assignee .edit-link').click wait_for_requests + end - expect(page).to have_content(user2.name) + it 'shows author in assignee dropdown' do + page.within '.dropdown-menu-user' do + expect(page).to have_content(user2.name) + end end - end - it 'assigns yourself' do - find('.block.assignee .dropdown-menu-toggle').click + it 'shows author when filtering assignee dropdown' do + page.within '.dropdown-menu-user' do + find('.dropdown-input-field').set(user2.name) - click_button 'assign yourself' + wait_for_requests - wait_for_requests + expect(page).to have_content(user2.name) + end + end - find('.block.assignee .edit-link').click + it 'assigns yourself' do + find('.block.assignee .dropdown-menu-toggle').click - page.within '.dropdown-menu-user' do - expect(page.find('.dropdown-header')).to be_visible - expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name) - end - end + click_button 'assign yourself' - it 'keeps your filtered term after filtering and dismissing the dropdown' do - find('.dropdown-input-field').set(user2.name) + wait_for_requests - wait_for_requests + find('.block.assignee .edit-link').click - page.within '.dropdown-menu-user' do - expect(page).not_to have_content 'Unassigned' - click_link user2.name + page.within '.dropdown-menu-user' do + expect(page.find('.dropdown-header')).to be_visible + expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name) + end end - find('.js-right-sidebar').click - find('.block.assignee .edit-link').click - - expect(page.all('.dropdown-menu-user li').length).to eq(1) - expect(find('.dropdown-input-field').value).to eq(user2.name) - end - end + it 'keeps your filtered term after filtering and dismissing the dropdown' do + find('.dropdown-input-field').set(user2.name) - it 'shows label text as "Apply" when assignees are changed' do - project.add_developer(user) - visit_issue(project, issue2) + wait_for_requests - find('.block.assignee .edit-link').click - wait_for_requests + page.within '.dropdown-menu-user' do + expect(page).not_to have_content 'Unassigned' + click_link user2.name + end - click_on 'Unassigned' + find('.js-right-sidebar').click + find('.block.assignee .edit-link').click - expect(page).to have_link('Apply') - end - end + expect(page.all('.dropdown-menu-user li').length).to eq(1) + expect(find('.dropdown-input-field').value).to eq(user2.name) + end + end - context 'as a allowed user' do - before do - project.add_developer(user) - visit_issue(project, issue) - end + it 'shows label text as "Apply" when assignees are changed' do + project.add_developer(user) + visit_issue(project, issue2) - context 'sidebar', :js do - it 'changes size when the screen size is smaller' do - sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' - # Resize the window - resize_screen_sm - # Make sure the sidebar is collapsed - find(sidebar_selector) - expect(page).to have_css(sidebar_selector) - # Once is collapsed let's open the sidebard and reload - open_issue_sidebar - refresh - find(sidebar_selector) - expect(page).to have_css(sidebar_selector) - # Restore the window size as it was including the sidebar - restore_window_size - open_issue_sidebar - end + find('.block.assignee .edit-link').click + wait_for_requests - it 'escapes XSS when viewing issue labels' do - page.within('.block.labels') do - click_on 'Edit' + click_on 'Unassigned' - expect(page).to have_content '<script>alert("xss");</script>' - end + expect(page).to have_link('Apply') end end - context 'editing issue labels', :js do + context 'as a allowed user' do before do - issue.update(labels: [label]) - page.within('.block.labels') do - click_on 'Edit' - end + project.add_developer(user) + visit_issue(project, issue) end - it 'shows the current set of labels' do - page.within('.issuable-show-labels') do - expect(page).to have_content label.title + context 'sidebar', :js do + it 'changes size when the screen size is smaller' do + sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' + # Resize the window + resize_screen_sm + # Make sure the sidebar is collapsed + find(sidebar_selector) + expect(page).to have_css(sidebar_selector) + # Once is collapsed let's open the sidebard and reload + open_issue_sidebar + refresh + find(sidebar_selector) + expect(page).to have_css(sidebar_selector) + # Restore the window size as it was including the sidebar + restore_window_size + open_issue_sidebar end - end - it 'shows option to create a project label' do - page.within('.block.labels') do - expect(page).to have_content 'Create project' + it 'escapes XSS when viewing issue labels' do + page.within('.block.labels') do + click_on 'Edit' + + expect(page).to have_content '<script>alert("xss");</script>' + end end end - context 'creating a project label', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27992' do + context 'editing issue labels', :js do before do + issue.update(labels: [label]) page.within('.block.labels') do - click_link 'Create project' + click_on 'Edit' end end - it 'shows dropdown switches to "create label" section' do - page.within('.block.labels') do - expect(page).to have_content 'Create project label' + it 'shows the current set of labels' do + page.within('.issuable-show-labels') do + expect(page).to have_content label.title end end - it 'adds new label' do + it 'shows option to create a project label' do page.within('.block.labels') do - fill_in 'new_label_name', with: 'wontfix' - page.find('.suggest-colors a', match: :first).click - page.find('button', text: 'Create').click + expect(page).to have_content 'Create project' + end + end - page.within('.dropdown-page-one') do - expect(page).to have_content 'wontfix' + context 'creating a project label', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27992' do + before do + page.within('.block.labels') do + click_link 'Create project' end end - end - it 'shows error message if label title is taken' do - page.within('.block.labels') do - fill_in 'new_label_name', with: label.title - page.find('.suggest-colors a', match: :first).click - page.find('button', text: 'Create').click + it 'shows dropdown switches to "create label" section' do + page.within('.block.labels') do + expect(page).to have_content 'Create project label' + end + end + + it 'adds new label' do + page.within('.block.labels') do + fill_in 'new_label_name', with: 'wontfix' + page.find('.suggest-colors a', match: :first).click + page.find('button', text: 'Create').click + + page.within('.dropdown-page-one') do + expect(page).to have_content 'wontfix' + end + end + end - page.within('.dropdown-page-two') do - expect(page).to have_content 'Title has already been taken' + it 'shows error message if label title is taken' do + page.within('.block.labels') do + fill_in 'new_label_name', with: label.title + page.find('.suggest-colors a', match: :first).click + page.find('button', text: 'Create').click + + page.within('.dropdown-page-two') do + expect(page).to have_content 'Title has already been taken' + end end end end end - end - context 'interacting with collapsed sidebar', :js do - collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' - expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded' - confidentiality_sidebar_block = '.block.confidentiality' - lock_sidebar_block = '.block.lock' - collapsed_sidebar_block_icon = '.sidebar-collapsed-icon' + context 'interacting with collapsed sidebar', :js do + collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' + expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded' + confidentiality_sidebar_block = '.block.confidentiality' + lock_sidebar_block = '.block.lock' + collapsed_sidebar_block_icon = '.sidebar-collapsed-icon' - before do - resize_screen_sm - end + before do + resize_screen_sm + end - it 'confidentiality block expands then collapses sidebar' do - expect(page).to have_css(collapsed_sidebar_selector) + it 'confidentiality block expands then collapses sidebar' do + expect(page).to have_css(collapsed_sidebar_selector) - page.within(confidentiality_sidebar_block) do - find(collapsed_sidebar_block_icon).click + page.within(confidentiality_sidebar_block) do + find(collapsed_sidebar_block_icon).click + end + + expect(page).to have_css(expanded_sidebar_selector) + + page.within(confidentiality_sidebar_block) do + page.find('button', text: 'Cancel').click + end + + expect(page).to have_css(collapsed_sidebar_selector) end - expect(page).to have_css(expanded_sidebar_selector) + it 'lock block expands then collapses sidebar' do + expect(page).to have_css(collapsed_sidebar_selector) + + page.within(lock_sidebar_block) do + find(collapsed_sidebar_block_icon).click + end + + expect(page).to have_css(expanded_sidebar_selector) + + page.within(lock_sidebar_block) do + page.find('button', text: 'Cancel').click + end - page.within(confidentiality_sidebar_block) do - page.find('button', text: 'Cancel').click + expect(page).to have_css(collapsed_sidebar_selector) end + end + end - expect(page).to have_css(collapsed_sidebar_selector) + context 'as a guest' do + before do + project.add_guest(user) + visit_issue(project, issue) end - it 'lock block expands then collapses sidebar' do - expect(page).to have_css(collapsed_sidebar_selector) + it 'does not have a option to edit labels' do + expect(page).not_to have_selector('.block.labels .js-sidebar-dropdown-toggle') + end - page.within(lock_sidebar_block) do - find(collapsed_sidebar_block_icon).click + context 'sidebar', :js do + it 'finds issue copy forwarding email' do + expect(find('[data-qa-selector="copy-forward-email"]').text).to eq "Issue email: #{issue.creatable_note_email_address(user)}" end + end - expect(page).to have_css(expanded_sidebar_selector) + context 'interacting with collapsed sidebar', :js do + collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' + expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded' + lock_sidebar_block = '.block.lock' + lock_button = '.block.lock .btn-close' + collapsed_sidebar_block_icon = '.sidebar-collapsed-icon' - page.within(lock_sidebar_block) do - page.find('button', text: 'Cancel').click + before do + resize_screen_sm end - expect(page).to have_css(collapsed_sidebar_selector) - end - end - end + it 'expands then does not show the lock dialog form' do + expect(page).to have_css(collapsed_sidebar_selector) - context 'as a guest' do - before do - project.add_guest(user) - visit_issue(project, issue) - end + page.within(lock_sidebar_block) do + find(collapsed_sidebar_block_icon).click + end - it 'does not have a option to edit labels' do - expect(page).not_to have_selector('.block.labels .js-sidebar-dropdown-toggle') + expect(page).to have_css(expanded_sidebar_selector) + expect(page).not_to have_selector(lock_button) + end + end end + end - context 'interacting with collapsed sidebar', :js do - collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' - expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded' - lock_sidebar_block = '.block.lock' - lock_button = '.block.lock .btn-close' - collapsed_sidebar_block_icon = '.sidebar-collapsed-icon' - + context 'when not signed in' do + context 'sidebar', :js do before do - resize_screen_sm + visit_issue(project, issue) end - it 'expands then does not show the lock dialog form' do - expect(page).to have_css(collapsed_sidebar_selector) - - page.within(lock_sidebar_block) do - find(collapsed_sidebar_block_icon).click - end - - expect(page).to have_css(expanded_sidebar_selector) - expect(page).not_to have_selector(lock_button) + it 'does not find issue email' do + expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]') end end end diff --git a/spec/features/issues/issue_state_spec.rb b/spec/features/issues/issue_state_spec.rb index 0ef6eb56dff..d5a115433aa 100644 --- a/spec/features/issues/issue_state_spec.rb +++ b/spec/features/issues/issue_state_spec.rb @@ -13,10 +13,13 @@ RSpec.describe 'issue state', :js do shared_examples 'issue closed' do |selector| it 'can close an issue' do + wait_for_requests + expect(find('.status-box')).to have_content 'Open' within selector do click_button 'Close issue' + wait_for_requests end expect(find('.status-box')).to have_content 'Closed' @@ -25,17 +28,20 @@ RSpec.describe 'issue state', :js do shared_examples 'issue reopened' do |selector| it 'can reopen an issue' do + wait_for_requests + expect(find('.status-box')).to have_content 'Closed' within selector do click_button 'Reopen issue' + wait_for_requests end expect(find('.status-box')).to have_content 'Open' end end - describe 'when open' do + describe 'when open', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297348' do context 'when clicking the top `Close issue` button', :aggregate_failures do let(:open_issue) { create(:issue, project: project) } @@ -57,7 +63,7 @@ RSpec.describe 'issue state', :js do end end - describe 'when closed' do + describe 'when closed', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297201' do context 'when clicking the top `Reopen issue` button', :aggregate_failures do let(:closed_issue) { create(:issue, project: project, state: 'closed') } diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb index 005d45d9c92..24a261f592b 100644 --- a/spec/features/issues/user_comments_on_issue_spec.rb +++ b/spec/features/issues/user_comments_on_issue_spec.rb @@ -10,6 +10,7 @@ RSpec.describe "User comments on issue", :js do let(:user) { create(:user) } before do + stub_feature_flags(tribute_autocomplete: false) project.add_guest(user) sign_in(user) diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index 668b4265948..98f9ed6c6a2 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -223,8 +223,8 @@ RSpec.describe "User creates issue" do expect(page).not_to have_selector('.epic-dropdown-container') end - it 'hides the milestone select' do - expect(page).not_to have_selector('.qa-issuable-milestone-dropdown') + it 'shows the milestone select' do + expect(page).to have_selector('.qa-issuable-milestone-dropdown') end it 'hides the weight input' do |