Commit a10cff85 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch 'cngo-remove-data-testids' into 'master'

Remove data-testids in favour of testing by label text

See merge request gitlab-org/gitlab!62208
parents 6bc59a79 885f3a75
...@@ -51,7 +51,6 @@ export default { ...@@ -51,7 +51,6 @@ export default {
</template> </template>
<div <div
v-if="issuableCount > -1" v-if="issuableCount > -1"
data-testid="issuable-count-note"
class="gl-justify-content-start gl-align-items-center gl-p-4 gl-border-b-solid gl-border-1 gl-border-gray-50" class="gl-justify-content-start gl-align-items-center gl-p-4 gl-border-b-solid gl-border-1 gl-border-gray-50"
> >
<gl-icon name="check" class="gl-color-green-400" /> <gl-icon name="check" class="gl-color-green-400" />
......
...@@ -72,9 +72,6 @@ export default { ...@@ -72,9 +72,6 @@ export default {
importModalId() { importModalId() {
return `${this.issuableType}-import-modal`; return `${this.issuableType}-import-modal`;
}, },
importButtonText() {
return this.showLabel ? this.$options.i18n.importIssuesText : null;
},
importButtonTooltipText() { importButtonTooltipText() {
return this.showLabel ? null : this.$options.i18n.importIssuesText; return this.showLabel ? null : this.$options.i18n.importIssuesText;
}, },
...@@ -90,29 +87,25 @@ export default { ...@@ -90,29 +87,25 @@ export default {
<gl-button-group> <gl-button-group>
<gl-button <gl-button
v-if="showExportButton" v-if="showExportButton"
v-gl-tooltip.hover="$options.i18n.exportAsCsvButtonText" v-gl-tooltip="$options.i18n.exportAsCsvButtonText"
v-gl-modal="exportModalId" v-gl-modal="exportModalId"
icon="export" icon="export"
:aria-label="$options.i18n.exportAsCsvButtonText" :aria-label="$options.i18n.exportAsCsvButtonText"
data-qa-selector="export_as_csv_button" data-qa-selector="export_as_csv_button"
data-testid="export-csv-button"
/> />
<gl-dropdown <gl-dropdown
v-if="showImportButton" v-if="showImportButton"
v-gl-tooltip.hover="importButtonTooltipText" v-gl-tooltip="importButtonTooltipText"
data-qa-selector="import_issues_dropdown" data-qa-selector="import_issues_dropdown"
data-testid="import-csv-dropdown" :text="$options.i18n.importIssuesText"
:text="importButtonText" :text-sr-only="!showLabel"
:icon="importButtonIcon" :icon="importButtonIcon"
> >
<gl-dropdown-item v-gl-modal="importModalId" data-testid="import-csv-link">{{ <gl-dropdown-item v-gl-modal="importModalId">{{ __('Import CSV') }}</gl-dropdown-item>
__('Import CSV')
}}</gl-dropdown-item>
<gl-dropdown-item <gl-dropdown-item
v-if="canEdit" v-if="canEdit"
:href="projectImportJiraPath" :href="projectImportJiraPath"
data-qa-selector="import_from_jira_link" data-qa-selector="import_from_jira_link"
data-testid="import-from-jira-link"
>{{ __('Import from Jira') }}</gl-dropdown-item >{{ __('Import from Jira') }}</gl-dropdown-item
> >
</gl-dropdown> </gl-dropdown>
......
...@@ -48,13 +48,7 @@ export default { ...@@ -48,13 +48,7 @@ export default {
<template> <template>
<gl-modal :modal-id="modalId" :title="__('Import issues')"> <gl-modal :modal-id="modalId" :title="__('Import issues')">
<form <form ref="form" :action="importCsvIssuesPath" enctype="multipart/form-data" method="post">
ref="form"
:action="importCsvIssuesPath"
enctype="multipart/form-data"
method="post"
data-testid="import-csv-form"
>
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" /> <input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
<p> <p>
{{ {{
......
...@@ -91,7 +91,7 @@ export default { ...@@ -91,7 +91,7 @@ export default {
<template> <template>
<div> <div>
<gl-button v-gl-modal="$options.modalId" variant="link" data-testid="issuable-email-modal-btn" <gl-button v-gl-modal="$options.modalId" variant="link"
><gl-sprintf :message="__('Email a new %{name} to this project')" ><gl-sprintf :message="__('Email a new %{name} to this project')"
><template #name>{{ issuableName }}</template></gl-sprintf ><template #name>{{ issuableName }}</template></gl-sprintf
></gl-button ></gl-button
...@@ -122,7 +122,6 @@ export default { ...@@ -122,7 +122,6 @@ export default {
:title="$options.i18n.sendEmail" :title="$options.i18n.sendEmail"
:aria-label="$options.i18n.sendEmail" :aria-label="$options.i18n.sendEmail"
icon="mail" icon="mail"
data-testid="mail-to-btn"
/> />
</template> </template>
</gl-form-input-group> </gl-form-input-group>
...@@ -156,12 +155,7 @@ export default { ...@@ -156,12 +155,7 @@ export default {
/></gl-link> /></gl-link>
</template> </template>
<template #resetLink="{ content }"> <template #resetLink="{ content }">
<gl-button <gl-button variant="link" @click="resetIncomingEmailToken">{{ content }}</gl-button>
variant="link"
data-testid="incoming-email-token-reset"
@click="resetIncomingEmailToken"
>{{ content }}</gl-button
>
</template> </template>
</gl-sprintf> </gl-sprintf>
</p> </p>
......
...@@ -91,11 +91,7 @@ export default { ...@@ -91,11 +91,7 @@ export default {
<template> <template>
<div :class="statusBoxClass" class="issuable-status-box status-box"> <div :class="statusBoxClass" class="issuable-status-box status-box">
<gl-icon <gl-icon :name="statusIconName" class="gl-display-block gl-sm-display-none!" />
:name="statusIconName"
class="gl-display-block gl-sm-display-none!"
data-testid="status-icon"
/>
<span class="gl-display-none gl-sm-display-block"> <span class="gl-display-none gl-sm-display-block">
{{ statusHumanName }} {{ statusHumanName }}
</span> </span>
......
...@@ -16,9 +16,7 @@ RSpec.describe 'Issues csv', :js do ...@@ -16,9 +16,7 @@ RSpec.describe 'Issues csv', :js do
def request_csv(params = {}) def request_csv(params = {})
visit project_issues_path(project, params) visit project_issues_path(project, params)
page.within('.nav-controls') do click_button 'Export as CSV'
find('[data-testid="export-csv-button"]').click
end
click_on 'Export issues' click_on 'Export issues'
end end
......
...@@ -16,11 +16,11 @@ RSpec.describe 'Issues > User resets their incoming email token' do ...@@ -16,11 +16,11 @@ RSpec.describe 'Issues > User resets their incoming email token' do
end end
it 'changes incoming email address token', :js do it 'changes incoming email address token', :js do
page.find('[data-testid="issuable-email-modal-btn"]').click click_button 'Email a new issue to this project'
page.within '#issuable-email-modal' do page.within '#issuable-email-modal' do
previous_token = page.find('input[type="text"]').value previous_token = page.find('input[type="text"]').value
page.find('[data-testid="incoming-email-token-reset"]').click click_button 'reset it'
wait_for_requests wait_for_requests
......
...@@ -12,15 +12,9 @@ RSpec.describe 'Merge Requests > Exports as CSV', :js do ...@@ -12,15 +12,9 @@ RSpec.describe 'Merge Requests > Exports as CSV', :js do
visit(project_merge_requests_path(project)) visit(project_merge_requests_path(project))
end end
subject { page.find('.nav-controls') }
it { is_expected.to have_selector '[data-testid="export-csv-button"]' }
context 'button is clicked' do context 'button is clicked' do
before do before do
page.within('.nav-controls') do click_button 'Export as CSV'
find('[data-testid="export-csv-button"]').click
end
end end
it 'shows a success message' do it 'shows a success message' do
......
import { GlModal, GlIcon, GlButton } from '@gitlab/ui'; import { GlModal, GlIcon, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component'; import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import CsvExportModal from '~/issuable/components/csv_export_modal.vue'; import CsvExportModal from '~/issuable/components/csv_export_modal.vue';
describe('CsvExportModal', () => { describe('CsvExportModal', () => {
...@@ -9,26 +8,24 @@ describe('CsvExportModal', () => { ...@@ -9,26 +8,24 @@ describe('CsvExportModal', () => {
function createComponent(options = {}) { function createComponent(options = {}) {
const { injectedProperties = {}, props = {} } = options; const { injectedProperties = {}, props = {} } = options;
return extendedWrapper( return mount(CsvExportModal, {
mount(CsvExportModal, { propsData: {
propsData: { modalId: 'csv-export-modal',
modalId: 'csv-export-modal', exportCsvPath: 'export/csv/path',
exportCsvPath: 'export/csv/path', issuableCount: 1,
issuableCount: 1, ...props,
...props, },
}, provide: {
provide: { issuableType: 'issues',
issuableType: 'issues', ...injectedProperties,
...injectedProperties, },
}, stubs: {
stubs: { GlModal: stubComponent(GlModal, {
GlModal: stubComponent(GlModal, { template:
template: '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>',
'<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>', }),
}), },
}, });
}),
);
} }
afterEach(() => { afterEach(() => {
...@@ -61,14 +58,13 @@ describe('CsvExportModal', () => { ...@@ -61,14 +58,13 @@ describe('CsvExportModal', () => {
describe('issuable count info text', () => { describe('issuable count info text', () => {
it('displays the info text when issuableCount is > -1', () => { it('displays the info text when issuableCount is > -1', () => {
wrapper = createComponent({ props: { issuableCount: 10 } }); wrapper = createComponent({ props: { issuableCount: 10 } });
expect(wrapper.findByTestId('issuable-count-note').exists()).toBe(true); expect(wrapper.text()).toContain('10 issues selected');
expect(wrapper.findByTestId('issuable-count-note').text()).toContain('10 issues selected');
expect(findIcon().exists()).toBe(true); expect(findIcon().exists()).toBe(true);
}); });
it("doesn't display the info text when issuableCount is -1", () => { it("doesn't display the info text when issuableCount is -1", () => {
wrapper = createComponent({ props: { issuableCount: -1 } }); wrapper = createComponent({ props: { issuableCount: -1 } });
expect(wrapper.findByTestId('issuable-count-note').exists()).toBe(false); expect(wrapper.text()).not.toContain('issues selected');
}); });
}); });
......
import { shallowMount } from '@vue/test-utils'; import { GlButton, GlDropdown } from '@gitlab/ui';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
import CsvExportModal from '~/issuable/components/csv_export_modal.vue'; import CsvExportModal from '~/issuable/components/csv_export_modal.vue';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue'; import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import CsvImportModal from '~/issuable/components/csv_import_modal.vue'; import CsvImportModal from '~/issuable/components/csv_import_modal.vue';
...@@ -14,35 +14,33 @@ describe('CsvImportExportButtons', () => { ...@@ -14,35 +14,33 @@ describe('CsvImportExportButtons', () => {
function createComponent(injectedProperties = {}) { function createComponent(injectedProperties = {}) {
glModalDirective = jest.fn(); glModalDirective = jest.fn();
return extendedWrapper( return mountExtended(CsvImportExportButtons, {
shallowMount(CsvImportExportButtons, { directives: {
directives: { GlTooltip: createMockDirective(),
GlTooltip: createMockDirective(), glModal: {
glModal: { bind(_, { value }) {
bind(_, { value }) { glModalDirective(value);
glModalDirective(value);
},
}, },
}, },
provide: { },
...injectedProperties, provide: {
}, ...injectedProperties,
propsData: { },
exportCsvPath, propsData: {
issuableCount, exportCsvPath,
}, issuableCount,
}), },
); });
} }
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
const findExportCsvButton = () => wrapper.findByTestId('export-csv-button'); const findExportCsvButton = () => wrapper.findComponent(GlButton);
const findImportDropdown = () => wrapper.findByTestId('import-csv-dropdown'); const findImportDropdown = () => wrapper.findComponent(GlDropdown);
const findImportCsvButton = () => wrapper.findByTestId('import-csv-dropdown'); const findImportCsvButton = () => wrapper.findByRole('menuitem', { name: 'Import CSV' });
const findImportFromJiraLink = () => wrapper.findByTestId('import-from-jira-link'); const findImportFromJiraLink = () => wrapper.findByRole('menuitem', { name: 'Import from Jira' });
const findExportCsvModal = () => wrapper.findComponent(CsvExportModal); const findExportCsvModal = () => wrapper.findComponent(CsvExportModal);
const findImportCsvModal = () => wrapper.findComponent(CsvImportModal); const findImportCsvModal = () => wrapper.findComponent(CsvImportModal);
...@@ -97,7 +95,7 @@ describe('CsvImportExportButtons', () => { ...@@ -97,7 +95,7 @@ describe('CsvImportExportButtons', () => {
expect(findImportDropdown().exists()).toBe(true); expect(findImportDropdown().exists()).toBe(true);
}); });
it('renders the import button', () => { it('renders the import csv menu item', () => {
expect(findImportCsvButton().exists()).toBe(true); expect(findImportCsvButton().exists()).toBe(true);
}); });
...@@ -106,8 +104,11 @@ describe('CsvImportExportButtons', () => { ...@@ -106,8 +104,11 @@ describe('CsvImportExportButtons', () => {
wrapper = createComponent({ showImportButton: true, showLabel: false }); wrapper = createComponent({ showImportButton: true, showLabel: false });
}); });
it('does not have a button text', () => { it('hides button text', () => {
expect(findImportCsvButton().props('text')).toBe(null); expect(findImportDropdown().props()).toMatchObject({
text: 'Import issues',
textSrOnly: true,
});
}); });
it('import button has a tooltip', () => { it('import button has a tooltip', () => {
...@@ -124,7 +125,10 @@ describe('CsvImportExportButtons', () => { ...@@ -124,7 +125,10 @@ describe('CsvImportExportButtons', () => {
}); });
it('displays a button text', () => { it('displays a button text', () => {
expect(findImportCsvButton().props('text')).toBe('Import issues'); expect(findImportDropdown().props()).toMatchObject({
text: 'Import issues',
textSrOnly: false,
});
}); });
it('import button has no tooltip', () => { it('import button has no tooltip', () => {
......
import { GlModal } from '@gitlab/ui'; import { GlButton, GlModal } from '@gitlab/ui';
import { getByRole, getByLabelText } from '@testing-library/dom';
import { mount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component'; import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
import CsvImportModal from '~/issuable/components/csv_import_modal.vue'; import CsvImportModal from '~/issuable/components/csv_import_modal.vue';
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' })); jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
...@@ -13,23 +11,21 @@ describe('CsvImportModal', () => { ...@@ -13,23 +11,21 @@ describe('CsvImportModal', () => {
function createComponent(options = {}) { function createComponent(options = {}) {
const { injectedProperties = {}, props = {} } = options; const { injectedProperties = {}, props = {} } = options;
return extendedWrapper( return mountExtended(CsvImportModal, {
mount(CsvImportModal, { propsData: {
propsData: { modalId: 'csv-import-modal',
modalId: 'csv-import-modal', ...props,
...props, },
}, provide: {
provide: { issuableType: 'issues',
issuableType: 'issues', ...injectedProperties,
...injectedProperties, },
}, stubs: {
stubs: { GlModal: stubComponent(GlModal, {
GlModal: stubComponent(GlModal, { template: '<div><slot></slot><slot name="modal-footer"></slot></div>',
template: '<div><slot></slot><slot name="modal-footer"></slot></div>', }),
}), },
}, });
}),
);
} }
beforeEach(() => { beforeEach(() => {
...@@ -41,9 +37,9 @@ describe('CsvImportModal', () => { ...@@ -41,9 +37,9 @@ describe('CsvImportModal', () => {
}); });
const findModal = () => wrapper.findComponent(GlModal); const findModal = () => wrapper.findComponent(GlModal);
const findPrimaryButton = () => getByRole(wrapper.element, 'button', { name: 'Import issues' }); const findPrimaryButton = () => wrapper.findComponent(GlButton);
const findForm = () => wrapper.findByTestId('import-csv-form'); const findForm = () => wrapper.find('form');
const findFileInput = () => getByLabelText(wrapper.element, 'Upload CSV file'); const findFileInput = () => wrapper.findByLabelText('Upload CSV file');
const findAuthenticityToken = () => new FormData(findForm().element).get('authenticity_token'); const findAuthenticityToken = () => new FormData(findForm().element).get('authenticity_token');
describe('template', () => { describe('template', () => {
...@@ -76,8 +72,8 @@ describe('CsvImportModal', () => { ...@@ -76,8 +72,8 @@ describe('CsvImportModal', () => {
expect(findPrimaryButton()).toExist(); expect(findPrimaryButton()).toExist();
}); });
it('submits the form when the primary action is clicked', async () => { it('submits the form when the primary action is clicked', () => {
findPrimaryButton().click(); findPrimaryButton().trigger('click');
expect(formSubmitSpy).toHaveBeenCalled(); expect(formSubmitSpy).toHaveBeenCalled();
}); });
......
...@@ -58,10 +58,11 @@ describe('IssuableByEmail', () => { ...@@ -58,10 +58,11 @@ describe('IssuableByEmail', () => {
mockAxios.restore(); mockAxios.restore();
}); });
const findFormInputGroup = () => wrapper.find(GlFormInputGroup); const findButton = () => wrapper.findComponent(GlButton);
const findFormInputGroup = () => wrapper.findComponent(GlFormInputGroup);
const clickResetEmail = async () => { const clickResetEmail = async () => {
wrapper.findByTestId('incoming-email-token-reset').vm.$emit('click'); wrapper.findAllComponents(GlButton).at(2).trigger('click');
await waitForPromises(); await waitForPromises();
}; };
...@@ -75,14 +76,14 @@ describe('IssuableByEmail', () => { ...@@ -75,14 +76,14 @@ describe('IssuableByEmail', () => {
'renders a link with "$buttonText" when type is "$issuableType"', 'renders a link with "$buttonText" when type is "$issuableType"',
({ issuableType, buttonText }) => { ({ issuableType, buttonText }) => {
wrapper = createComponent({ issuableType }); wrapper = createComponent({ issuableType });
expect(wrapper.findByTestId('issuable-email-modal-btn').text()).toBe(buttonText); expect(findButton().text()).toBe(buttonText);
}, },
); );
it('opens the modal when the user clicks the button', () => { it('opens the modal when the user clicks the button', () => {
wrapper = createComponent(); wrapper = createComponent();
wrapper.findByTestId('issuable-email-modal-btn').vm.$emit('click'); findButton().trigger('click');
expect(glModalDirective).toHaveBeenCalled(); expect(glModalDirective).toHaveBeenCalled();
}); });
...@@ -105,7 +106,7 @@ describe('IssuableByEmail', () => { ...@@ -105,7 +106,7 @@ describe('IssuableByEmail', () => {
initialEmail, initialEmail,
}); });
expect(wrapper.findByTestId('mail-to-btn').attributes('href')).toBe( expect(wrapper.findAllComponents(GlButton).at(1).attributes('href')).toBe(
`mailto:${initialEmail}?subject=${subject}&body=${body}`, `mailto:${initialEmail}?subject=${subject}&body=${body}`,
); );
}); });
......
import { GlSprintf } from '@gitlab/ui'; import { GlIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import StatusBox from '~/issuable/components/status_box.vue'; import StatusBox from '~/issuable/components/status_box.vue';
...@@ -64,7 +64,7 @@ describe('Merge request status box component', () => { ...@@ -64,7 +64,7 @@ describe('Merge request status box component', () => {
initialState: testCase.state, initialState: testCase.state,
}); });
expect(wrapper.find('[data-testid="status-icon"]').props('name')).toBe(testCase.icon); expect(wrapper.findComponent(GlIcon).props('name')).toBe(testCase.icon);
}); });
}); });
}); });
......
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