Commit 3f50a5d4 authored by Peter Hegman's avatar Peter Hegman Committed by Nicolò Maria Mezzopera

Add missing QA selectors

Add missing QA selectors to new Vue group members view
parent 533b95f9
...@@ -5,7 +5,7 @@ import { parseDataAttributes } from 'ee_else_ce/groups/members/utils'; ...@@ -5,7 +5,7 @@ import { parseDataAttributes } from 'ee_else_ce/groups/members/utils';
import App from './components/app.vue'; import App from './components/app.vue';
import membersModule from '~/vuex_shared/modules/members'; import membersModule from '~/vuex_shared/modules/members';
export const initGroupMembersApp = (el, tableFields, requestFormatter) => { export const initGroupMembersApp = (el, tableFields, tableAttrs, requestFormatter) => {
if (!el) { if (!el) {
return () => {}; return () => {};
} }
...@@ -18,6 +18,7 @@ export const initGroupMembersApp = (el, tableFields, requestFormatter) => { ...@@ -18,6 +18,7 @@ export const initGroupMembersApp = (el, tableFields, requestFormatter) => {
...parseDataAttributes(el), ...parseDataAttributes(el),
currentUserId: gon.current_user_id || null, currentUserId: gon.current_user_id || null,
tableFields, tableFields,
tableAttrs,
requestFormatter, requestFormatter,
}), }),
}); });
......
...@@ -25,21 +25,25 @@ const SHARED_FIELDS = ['account', 'expires', 'maxRole', 'expiration', 'actions'] ...@@ -25,21 +25,25 @@ const SHARED_FIELDS = ['account', 'expires', 'maxRole', 'expiration', 'actions']
initGroupMembersApp( initGroupMembersApp(
document.querySelector('.js-group-members-list'), document.querySelector('.js-group-members-list'),
SHARED_FIELDS.concat(['source', 'granted']), SHARED_FIELDS.concat(['source', 'granted']),
{ tr: { 'data-qa-selector': 'member_row' } },
memberRequestFormatter, memberRequestFormatter,
); );
initGroupMembersApp( initGroupMembersApp(
document.querySelector('.js-group-linked-list'), document.querySelector('.js-group-linked-list'),
SHARED_FIELDS.concat('granted'), SHARED_FIELDS.concat('granted'),
{ table: { 'data-qa-selector': 'groups_list' }, tr: { 'data-qa-selector': 'group_row' } },
groupLinkRequestFormatter, groupLinkRequestFormatter,
); );
initGroupMembersApp( initGroupMembersApp(
document.querySelector('.js-group-invited-members-list'), document.querySelector('.js-group-invited-members-list'),
SHARED_FIELDS.concat('invited'), SHARED_FIELDS.concat('invited'),
{},
memberRequestFormatter, memberRequestFormatter,
); );
initGroupMembersApp( initGroupMembersApp(
document.querySelector('.js-group-access-requests-list'), document.querySelector('.js-group-access-requests-list'),
SHARED_FIELDS.concat('requested'), SHARED_FIELDS.concat('requested'),
{},
memberRequestFormatter, memberRequestFormatter,
); );
......
...@@ -39,7 +39,7 @@ export default { ...@@ -39,7 +39,7 @@ export default {
), ),
}, },
computed: { computed: {
...mapState(['members', 'tableFields', 'currentUserId', 'sourceId']), ...mapState(['members', 'tableFields', 'tableAttrs', 'currentUserId', 'sourceId']),
filteredFields() { filteredFields() {
return FIELDS.filter(field => this.tableFields.includes(field.key) && this.showField(field)); return FIELDS.filter(field => this.tableFields.includes(field.key) && this.showField(field));
}, },
...@@ -79,6 +79,7 @@ export default { ...@@ -79,6 +79,7 @@ export default {
<template> <template>
<div> <div>
<gl-table <gl-table
v-bind="tableAttrs.table"
class="members-table" class="members-table"
data-testid="members-table" data-testid="members-table"
head-variant="white" head-variant="white"
...@@ -89,6 +90,7 @@ export default { ...@@ -89,6 +90,7 @@ export default {
thead-class="border-bottom" thead-class="border-bottom"
:empty-text="__('No members found')" :empty-text="__('No members found')"
show-empty show-empty
:tbody-tr-attr="tableAttrs.tr"
> >
<template #cell(account)="{ item: member }"> <template #cell(account)="{ item: member }">
<members-table-cell #default="{ memberType, isCurrentUser }" :member="member"> <members-table-cell #default="{ memberType, isCurrentUser }" :member="member">
......
...@@ -35,6 +35,14 @@ export default { ...@@ -35,6 +35,14 @@ export default {
}, },
mounted() { mounted() {
this.isDesktop = bp.isDesktop(); this.isDesktop = bp.isDesktop();
// Bootstrap Vue and GlDropdown to not support adding attributes to the dropdown toggle
// This can be changed once https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1060 is implemented
const dropdownToggle = this.$refs.glDropdown.$el.querySelector('.dropdown-toggle');
if (dropdownToggle) {
dropdownToggle.setAttribute('data-qa-selector', 'access_level_dropdown');
}
}, },
methods: { methods: {
...mapActions(['updateMemberRole']), ...mapActions(['updateMemberRole']),
...@@ -63,6 +71,7 @@ export default { ...@@ -63,6 +71,7 @@ export default {
<template> <template>
<gl-dropdown <gl-dropdown
ref="glDropdown"
:right="!isDesktop" :right="!isDesktop"
:text="member.accessLevel.stringValue" :text="member.accessLevel.stringValue"
:header-text="__('Change permissions')" :header-text="__('Change permissions')"
...@@ -73,6 +82,7 @@ export default { ...@@ -73,6 +82,7 @@ export default {
:key="value" :key="value"
is-check-item is-check-item
:is-checked="value === member.accessLevel.integerValue" :is-checked="value === member.accessLevel.integerValue"
data-qa-selector="access_level_link"
@click="handleSelect(value, name)" @click="handleSelect(value, name)"
> >
{{ name }} {{ name }}
......
...@@ -3,6 +3,7 @@ export default ({ ...@@ -3,6 +3,7 @@ export default ({
sourceId, sourceId,
currentUserId, currentUserId,
tableFields, tableFields,
tableAttrs,
memberPath, memberPath,
requestFormatter, requestFormatter,
}) => ({ }) => ({
...@@ -10,6 +11,7 @@ export default ({ ...@@ -10,6 +11,7 @@ export default ({
sourceId, sourceId,
currentUserId, currentUserId,
tableFields, tableFields,
tableAttrs,
memberPath, memberPath,
requestFormatter, requestFormatter,
showError: false, showError: false,
......
...@@ -6,7 +6,7 @@ describe('initGroupMembersApp', () => { ...@@ -6,7 +6,7 @@ describe('initGroupMembersApp', () => {
let vm; let vm;
const createVm = () => { const createVm = () => {
vm = initGroupMembersApp(el, ['account'], () => ({})); vm = initGroupMembersApp(el, ['account'], {}, () => ({}));
}; };
beforeEach(() => { beforeEach(() => {
......
...@@ -15,6 +15,10 @@ describe('MemberList', () => { ...@@ -15,6 +15,10 @@ describe('MemberList', () => {
state: { state: {
members: [], members: [],
tableFields: [], tableFields: [],
tableAttrs: {
table: { 'data-qa-selector': 'members_list' },
tr: { 'data-qa-selector': 'member_row' },
},
sourceId: 1, sourceId: 1,
currentUserId: 1, currentUserId: 1,
...state, ...state,
......
...@@ -16,17 +16,24 @@ module QA ...@@ -16,17 +16,24 @@ module QA
element :invite_member_button element :invite_member_button
end end
view 'app/views/shared/members/_member.html.haml' do view 'app/assets/javascripts/pages/groups/group_members/index.js' do
element :member_row element :member_row
element :groups_list
element :group_row
end
view 'app/assets/javascripts/vue_shared/components/members/table/role_dropdown.vue' do
element :access_level_dropdown element :access_level_dropdown
element :access_level_link
end
view 'app/assets/javascripts/vue_shared/components/members/action_buttons/remove_member_button.vue' do
element :delete_member_button element :delete_member_button
element :developer_access_level_link, 'qa_selector: "#{role.downcase}_access_level_link"' # rubocop:disable QA/ElementWithPattern, Lint/InterpolationCheck
end end
view 'app/views/groups/group_members/index.html.haml' do view 'app/views/groups/group_members/index.html.haml' do
element :invite_group_tab element :invite_group_tab
element :groups_list_tab element :groups_list_tab
element :groups_list
end end
view 'app/views/shared/members/_invite_group.html.haml' do view 'app/views/shared/members/_invite_group.html.haml' do
...@@ -34,10 +41,6 @@ module QA ...@@ -34,10 +41,6 @@ module QA
element :invite_group_button element :invite_group_button
end end
view 'app/views/shared/members/_group.html.haml' do
element :group_row
end
def select_group(group_name) def select_group(group_name)
click_element :group_select_field click_element :group_select_field
search_and_select(group_name) search_and_select(group_name)
...@@ -57,7 +60,7 @@ module QA ...@@ -57,7 +60,7 @@ module QA
def update_access_level(username, access_level) def update_access_level(username, access_level)
within_element(:member_row, text: username) do within_element(:member_row, text: username) do
click_element :access_level_dropdown click_element :access_level_dropdown
click_element "#{access_level.downcase}_access_level_link" click_element :access_level_link, text: access_level
end end
end end
......
...@@ -85,8 +85,10 @@ module QA ...@@ -85,8 +85,10 @@ module QA
it_behaves_like 'audit event', ['Changed name'] it_behaves_like 'audit event', ['Changed name']
end end
context 'Add user, change access level, remove user', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/734' do context 'Add user, change access level, remove user', :requires_admin, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/734' do
before do before do
Runtime::Feature.enable('vue_group_members_list', group: group)
sign_in sign_in
group.visit! group.visit!
Page::Group::Menu.perform(&:click_group_members_item) Page::Group::Menu.perform(&:click_group_members_item)
...@@ -97,6 +99,10 @@ module QA ...@@ -97,6 +99,10 @@ module QA
end end
end end
after do
Runtime::Feature.disable('vue_group_members_list', group: group)
end
it_behaves_like 'audit event', ['Added user access as Guest', 'Changed access level', 'Removed user access'] it_behaves_like 'audit event', ['Added user access as Guest', 'Changed access level', 'Removed user access']
end end
......
...@@ -32,6 +32,11 @@ module QA ...@@ -32,6 +32,11 @@ module QA
before do before do
source_group_with_members.add_member(maintainer_user, Resource::Members::AccessLevel::MAINTAINER) source_group_with_members.add_member(maintainer_user, Resource::Members::AccessLevel::MAINTAINER)
Runtime::Feature.enable('vue_group_members_list', group: target_group_with_project)
end
after do
Runtime::Feature.disable('vue_group_members_list', group: target_group_with_project)
end end
it 'can be shared with another group with correct access level', :requires_admin, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/945' do it 'can be shared with another group with correct access level', :requires_admin, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/945' do
......
...@@ -9,7 +9,12 @@ describe('initGroupMembersApp', () => { ...@@ -9,7 +9,12 @@ describe('initGroupMembersApp', () => {
let wrapper; let wrapper;
const setup = () => { const setup = () => {
vm = initGroupMembersApp(el, ['account'], () => ({})); vm = initGroupMembersApp(
el,
['account'],
{ table: { 'data-qa-selector': 'members_list' } },
() => ({}),
);
wrapper = createWrapper(vm); wrapper = createWrapper(vm);
}; };
...@@ -68,6 +73,12 @@ describe('initGroupMembersApp', () => { ...@@ -68,6 +73,12 @@ describe('initGroupMembersApp', () => {
expect(vm.$store.state.tableFields).toEqual(['account']); expect(vm.$store.state.tableFields).toEqual(['account']);
}); });
it('sets `tableAttrs` in Vuex store', () => {
setup();
expect(vm.$store.state.tableAttrs).toEqual({ table: { 'data-qa-selector': 'members_list' } });
});
it('sets `requestFormatter` in Vuex store', () => { it('sets `requestFormatter` in Vuex store', () => {
setup(); setup();
......
...@@ -5,7 +5,7 @@ import { ...@@ -5,7 +5,7 @@ import {
getByTestId as getByTestIdHelper, getByTestId as getByTestIdHelper,
within, within,
} from '@testing-library/dom'; } from '@testing-library/dom';
import { GlBadge } from '@gitlab/ui'; import { GlBadge, GlTable } from '@gitlab/ui';
import MembersTable from '~/vue_shared/components/members/table/members_table.vue'; import MembersTable from '~/vue_shared/components/members/table/members_table.vue';
import MemberAvatar from '~/vue_shared/components/members/table/member_avatar.vue'; import MemberAvatar from '~/vue_shared/components/members/table/member_avatar.vue';
import MemberSource from '~/vue_shared/components/members/table/member_source.vue'; import MemberSource from '~/vue_shared/components/members/table/member_source.vue';
...@@ -28,6 +28,10 @@ describe('MemberList', () => { ...@@ -28,6 +28,10 @@ describe('MemberList', () => {
state: { state: {
members: [], members: [],
tableFields: [], tableFields: [],
tableAttrs: {
table: { 'data-qa-selector': 'members_list' },
tr: { 'data-qa-selector': 'member_row' },
},
sourceId: 1, sourceId: 1,
currentUserId: 1, currentUserId: 1,
...state, ...state,
...@@ -58,6 +62,8 @@ describe('MemberList', () => { ...@@ -58,6 +62,8 @@ describe('MemberList', () => {
const getByTestId = (id, options) => const getByTestId = (id, options) =>
createWrapper(getByTestIdHelper(wrapper.element, id, options)); createWrapper(getByTestIdHelper(wrapper.element, id, options));
const findTable = () => wrapper.find(GlTable);
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null; wrapper = null;
...@@ -187,4 +193,20 @@ describe('MemberList', () => { ...@@ -187,4 +193,20 @@ describe('MemberList', () => {
expect(initUserPopoversMock).toHaveBeenCalled(); expect(initUserPopoversMock).toHaveBeenCalled();
}); });
it('adds QA selector to table', () => {
createComponent();
expect(findTable().attributes('data-qa-selector')).toBe('members_list');
});
it('adds QA selector to table row', () => {
createComponent();
expect(
findTable()
.find('tbody tr')
.attributes('data-qa-selector'),
).toBe('member_row');
});
}); });
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