Commit f864b843 authored by Mark Lapierre's avatar Mark Lapierre

Merge branch 'tests-for-multiple-assignees-on-issues' into 'master'

Tests for multiple assignees on issues

Closes gitlab-org/quality/testcases#235 and gitlab-org/quality/testcases#176

See merge request gitlab-org/gitlab!17345
parents 64c60a33 8fa54f9e
...@@ -42,6 +42,7 @@ export default { ...@@ -42,6 +42,7 @@ export default {
:width="imgSize" :width="imgSize"
:class="`s${imgSize}`" :class="`s${imgSize}`"
class="avatar avatar-inline m-0" class="avatar avatar-inline m-0"
data-qa-selector="avatar_image"
/> />
<i v-if="hasMergeIcon" aria-hidden="true" class="fa fa-exclamation-triangle merge-icon"></i> <i v-if="hasMergeIcon" aria-hidden="true" class="fa fa-exclamation-triangle merge-icon"></i>
</span> </span>
......
...@@ -32,13 +32,14 @@ export default { ...@@ -32,13 +32,14 @@ export default {
}; };
</script> </script>
<template> <template>
<div class="title hide-collapsed"> <div class="title hide-collapsed" data-qa-selector="assignee_title">
{{ assigneeTitle }} {{ assigneeTitle }}
<i v-if="loading" aria-hidden="true" class="fa fa-spinner fa-spin block-loading"></i> <i v-if="loading" aria-hidden="true" class="fa fa-spinner fa-spin block-loading"></i>
<a <a
v-if="editable" v-if="editable"
class="js-sidebar-dropdown-toggle edit-link float-right" class="js-sidebar-dropdown-toggle edit-link float-right"
href="#" href="#"
data-qa-selector="assignee_edit_link"
data-track-event="click_edit_button" data-track-event="click_edit_button"
data-track-label="right_sidebar" data-track-label="right_sidebar"
data-track-property="assignee" data-track-property="assignee"
......
...@@ -85,7 +85,12 @@ export default { ...@@ -85,7 +85,12 @@ export default {
</div> </div>
</div> </div>
<div v-if="renderShowMoreSection" class="user-list-more"> <div v-if="renderShowMoreSection" class="user-list-more">
<button type="button" class="btn-link" @click="toggleShowLess"> <button
type="button"
class="btn-link"
data-qa-selector="more_assignees_link"
@click="toggleShowLess"
>
<template v-if="showLess"> <template v-if="showLess">
{{ hiddenAssigneesLabel }} {{ hiddenAssigneesLabel }}
</template> </template>
......
...@@ -76,7 +76,7 @@ module ProjectsHelper ...@@ -76,7 +76,7 @@ module ProjectsHelper
link_to(author_html, user_path(author), class: "author-link js-user-link #{"#{opts[:extra_class]}" if opts[:extra_class]} #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}", data: data_attrs).html_safe link_to(author_html, user_path(author), class: "author-link js-user-link #{"#{opts[:extra_class]}" if opts[:extra_class]} #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}", data: data_attrs).html_safe
else else
title = opts[:title].sub(":name", sanitize(author.name)) title = opts[:title].sub(":name", sanitize(author.name))
link_to(author_html, user_path(author), class: "author-link has-tooltip", title: title, data: { container: 'body' }).html_safe link_to(author_html, user_path(author), class: "author-link has-tooltip", title: title, data: { container: 'body', qa_selector: 'assignee_link' }).html_safe
end end
end end
......
...@@ -7,4 +7,4 @@ ...@@ -7,4 +7,4 @@
= link_to_member(@project, assignee, name: false, title: "Assigned to :name") = link_to_member(@project, assignee, name: false, title: "Assigned to :name")
- if more_assignees_count.positive? - if more_assignees_count.positive?
%span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', 'original-title' => "+#{more_assignees_count} more assignees" } } +#{more_assignees_count} %span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', 'original-title' => "+#{more_assignees_count} more assignees", qa_selector: 'avatar_counter' } } +#{more_assignees_count}
...@@ -131,6 +131,10 @@ module QA ...@@ -131,6 +131,10 @@ module QA
has_no_css?('.fa-spinner', wait: Capybara.default_max_wait_time) has_no_css?('.fa-spinner', wait: Capybara.default_max_wait_time)
end end
def finished_loading_block?
has_no_css?('.fa-spinner.block-loading', wait: Capybara.default_max_wait_time)
end
def wait_for_animated_element(name) def wait_for_animated_element(name)
# It would be ideal if we could detect when the animation is complete # It would be ideal if we could detect when the animation is complete
# but in some cases there's nothing we can easily access via capybara # but in some cases there's nothing we can easily access via capybara
......
...@@ -5,14 +5,30 @@ module QA ...@@ -5,14 +5,30 @@ module QA
module Project module Project
module Issue module Issue
class Index < Page::Base class Index < Page::Base
view 'app/helpers/projects_helper.rb' do
element :assignee_link
end
view 'app/views/projects/issues/_issue.html.haml' do view 'app/views/projects/issues/_issue.html.haml' do
element :issue_link, 'link_to issue.title' # rubocop:disable QA/ElementWithPattern element :issue_link, 'link_to issue.title' # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/shared/issuable/_assignees.html.haml' do
element :avatar_counter
end
view 'app/views/shared/issuable/_nav.html.haml' do view 'app/views/shared/issuable/_nav.html.haml' do
element :closed_issues_link element :closed_issues_link
end end
def assignee_link_count
all_elements(:assignee_link).count
end
def avatar_counter
find_element(:avatar_counter)
end
def click_issue_link(title) def click_issue_link(title)
click_link(title) click_link(title)
end end
......
...@@ -22,24 +22,54 @@ module QA ...@@ -22,24 +22,54 @@ module QA
element :noteable_note_item element :noteable_note_item
end end
view 'app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue' do
element :avatar_image
end
view 'app/assets/javascripts/sidebar/components/assignees/assignee_title.vue' do
element :assignee_edit_link
element :assignee_title
end
view 'app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue' do
element :more_assignees_link
end
view 'app/helpers/dropdowns_helper.rb' do view 'app/helpers/dropdowns_helper.rb' do
element :dropdown_input_field element :dropdown_input_field
end end
view 'app/views/shared/notes/_form.html.haml' do view 'app/views/shared/issuable/_close_reopen_button.html.haml' do
element :new_note_form, 'new-note' # rubocop:disable QA/ElementWithPattern element :reopen_issue_button
element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/shared/issuable/_sidebar.html.haml' do view 'app/views/shared/issuable/_sidebar.html.haml' do
element :assignee_block
element :labels_block element :labels_block
element :edit_link_labels element :edit_link_labels
element :dropdown_menu_labels element :dropdown_menu_labels
element :milestone_link element :milestone_link
end end
view 'app/views/shared/issuable/_close_reopen_button.html.haml' do view 'app/views/shared/notes/_form.html.haml' do
element :reopen_issue_button element :new_note_form, 'new-note' # rubocop:disable QA/ElementWithPattern
element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern
end
def assign(user)
click_element(:assignee_edit_link)
select_user(user.username)
click_body
end
def assignee_title
find_element(:assignee_title)
end
def avatar_image_count
wait_assignees_block_finish_loading do
all_elements(:avatar_image).count
end
end end
def click_milestone_link def click_milestone_link
...@@ -66,6 +96,10 @@ module QA ...@@ -66,6 +96,10 @@ module QA
end end
end end
def more_assignees_link
find_element(:more_assignees_link)
end
def select_all_activities_filter def select_all_activities_filter
select_filter_with_text('Show all activity') select_filter_with_text('Show all activity')
end end
...@@ -103,6 +137,10 @@ module QA ...@@ -103,6 +137,10 @@ module QA
find_element(:labels_block) find_element(:labels_block)
end end
def toggle_more_assignees_link
click_element(:more_assignees_link)
end
private private
def select_filter_with_text(text) def select_filter_with_text(text)
...@@ -112,6 +150,20 @@ module QA ...@@ -112,6 +150,20 @@ module QA
find_element(:filter_options, text: text).click find_element(:filter_options, text: text).click
end end
end end
def select_user(username)
find("#{element_selector_css(:assignee_block)} input").set(username)
find('.dropdown-menu-user-link', text: "@#{username}").click
end
def wait_assignees_block_finish_loading
within_element(:assignee_block) do
wait(reload: false, max: 10, interval: 1) do
finished_loading_block?
yield
end
end
end
end end
end end
end end
......
...@@ -145,6 +145,38 @@ module QA ...@@ -145,6 +145,38 @@ module QA
ENV['GITLAB_QA_PASSWORD_2'] ENV['GITLAB_QA_PASSWORD_2']
end end
def gitlab_qa_username_3
ENV['GITLAB_QA_USERNAME_3'] || 'gitlab-qa-user3'
end
def gitlab_qa_password_3
ENV['GITLAB_QA_PASSWORD_3']
end
def gitlab_qa_username_4
ENV['GITLAB_QA_USERNAME_4'] || 'gitlab-qa-user4'
end
def gitlab_qa_password_4
ENV['GITLAB_QA_PASSWORD_4']
end
def gitlab_qa_username_5
ENV['GITLAB_QA_USERNAME_5'] || 'gitlab-qa-user5'
end
def gitlab_qa_password_5
ENV['GITLAB_QA_PASSWORD_5']
end
def gitlab_qa_username_6
ENV['GITLAB_QA_USERNAME_6'] || 'gitlab-qa-user6'
end
def gitlab_qa_password_6
ENV['GITLAB_QA_PASSWORD_6']
end
def knapsack? def knapsack?
!!(ENV['KNAPSACK_GENERATE_REPORT'] || ENV['KNAPSACK_REPORT_PATH'] || ENV['KNAPSACK_TEST_FILE_PATTERN']) !!(ENV['KNAPSACK_GENERATE_REPORT'] || ENV['KNAPSACK_REPORT_PATH'] || ENV['KNAPSACK_TEST_FILE_PATTERN'])
end end
......
# frozen_string_literal: true
module QA
context 'Plan' do
describe 'Multiple assignees per issue' do
before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
user_1 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
user_2 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
user_3 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_3, Runtime::Env.gitlab_qa_password_3)
user_4 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_4, Runtime::Env.gitlab_qa_password_4)
project = Resource::Project.fabricate_via_api! do |resource|
resource.name = 'project-to-test-issue-with-multiple-assignees'
end
project.add_member(user_1)
project.add_member(user_2)
project.add_member(user_3)
project.add_member(user_4)
Resource::Issue.fabricate_via_api! do |issue|
issue.title = issue.title = 'issue-to-test-multiple-assignees'
issue.project = project
issue.assignee_ids = [
user_1.id,
user_2.id,
user_3.id,
user_4.id
]
end
project.visit!
end
it 'shows four assignees in the issues list' do
Page::Project::Menu.perform(&:click_issues)
Page::Project::Issue::Index.perform do |index|
expect(index.assignee_link_count).to be 4
end
end
end
end
end
# frozen_string_literal: true
module QA
context 'Plan' do
describe 'Multiple assignees per issue' do
before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
user_1 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
user_2 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
user_3 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_3, Runtime::Env.gitlab_qa_password_3)
user_4 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_4, Runtime::Env.gitlab_qa_password_4)
user_5 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_5, Runtime::Env.gitlab_qa_password_5)
user_6 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_6, Runtime::Env.gitlab_qa_password_6)
@project = Resource::Project.fabricate_via_api! do |resource|
resource.name = 'project-to-test-issue-with-multiple-assignees'
end
@project.add_member(user_1)
@project.add_member(user_2)
@project.add_member(user_3)
@project.add_member(user_4)
@project.add_member(user_5)
@project.add_member(user_6)
@issue = Resource::Issue.fabricate_via_api! do |issue|
issue.title = issue.title = 'issue-to-test-multiple-assignees'
issue.project = @project
issue.assignee_ids = [
user_1.id,
user_2.id,
user_3.id,
user_4.id,
user_5.id,
user_6.id
]
end
end
it 'shows the first three assignees and a +n sign in the issues list' do
@project.visit!
Page::Project::Menu.perform(&:click_issues)
Page::Project::Issue::Index.perform do |index|
expect(index.assignee_link_count).to be 3
expect(index.avatar_counter).to be_visible
expect(index.avatar_counter).to have_content('+3')
end
end
it 'shows the first five assignees and a +n more link in the issue page' do
@issue.visit!
Page::Project::Issue::Show.perform do |show|
expect(show.avatar_image_count).to be 5
expect(show.more_assignees_link).to be_visible
expect(show.more_assignees_link).to have_content('+ 1 more')
show.toggle_more_assignees_link
expect(show.avatar_image_count).to be 6
expect(show.more_assignees_link).to have_content('- show less')
end
end
end
end
end
# frozen_string_literal: true
module QA
context 'Plan' do
describe 'Multiple assignees per issue' do
before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
user_1 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
@user_2 = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
project = Resource::Project.fabricate_via_api! do |resource|
resource.name = 'project-to-test-issue-with-multiple-assignees'
end
project.add_member(user_1)
project.add_member(@user_2)
@issue = Resource::Issue.fabricate_via_api! do |issue|
issue.title = issue.title = 'issue-to-test-multiple-assignees'
issue.project = project
issue.assignee_ids = [user_1.id]
end
end
it 'assigns one more user to an issue via the browser UI' do
@issue.visit!
Page::Project::Issue::Show.perform do |show|
show.assign(@user_2)
expect(show.avatar_image_count).to be 2
expect(show.assignee_title).to have_content '2 Assignees'
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment