Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-17 09:12:03 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-17 09:12:03 +0300
commita17e8b168778e5a107928671fd2829ab284e612d (patch)
tree604569b4f05927a8a5d4871bd15af411149907a3 /spec
parent493d6f7512116b4cae9b37bbb6535f4492f6a4e6 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_block_spec.js17
-rw-r--r--spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js189
-rw-r--r--spec/frontend/issues/show/components/incidents/mock_data.js28
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js117
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js14
-rw-r--r--spec/services/database/consistency_check_service_spec.rb53
-rw-r--r--spec/services/git/branch_push_service_spec.rb2
-rw-r--r--spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb4
8 files changed, 297 insertions, 127 deletions
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
index b7385eddcc9..772cc75a205 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
@@ -20,8 +20,7 @@ describe('RelatedIssuesBlock', () => {
const findToggleButton = () => wrapper.findByTestId('toggle-links');
const findRelatedIssuesBody = () => wrapper.findByTestId('related-issues-body');
- const findIssueCountBadgeAddButton = () =>
- wrapper.find('[data-testid="related-issues-plus-button"]');
+ const findIssueCountBadgeAddButton = () => wrapper.findByTestId('related-issues-plus-button');
afterEach(() => {
if (wrapper) {
@@ -240,6 +239,7 @@ describe('RelatedIssuesBlock', () => {
wrapper = shallowMountExtended(RelatedIssuesBlock, {
propsData: {
pathIdSeparator: PathIdSeparator.Issue,
+ relatedIssues: [issuable1, issuable2, issuable3],
issuableType: issuableTypesMap.ISSUE,
},
});
@@ -247,6 +247,7 @@ describe('RelatedIssuesBlock', () => {
it('is expanded by default', () => {
expect(findToggleButton().props('icon')).toBe('chevron-lg-up');
+ expect(findToggleButton().props('disabled')).toBe(false);
expect(findRelatedIssuesBody().exists()).toBe(true);
});
@@ -258,4 +259,16 @@ describe('RelatedIssuesBlock', () => {
expect(findRelatedIssuesBody().exists()).toBe(false);
});
});
+
+ it('toggle button is disabled when issue has no related items', () => {
+ wrapper = shallowMountExtended(RelatedIssuesBlock, {
+ propsData: {
+ pathIdSeparator: PathIdSeparator.Issue,
+ relatedIssues: [],
+ issuableType: 'issue',
+ },
+ });
+
+ expect(findToggleButton().props('disabled')).toBe(true);
+ });
});
diff --git a/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js b/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js
new file mode 100644
index 00000000000..3ab2bb3460b
--- /dev/null
+++ b/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js
@@ -0,0 +1,189 @@
+import VueApollo from 'vue-apollo';
+import Vue from 'vue';
+import { GlDatepicker } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import CreateTimelineEvent from '~/issues/show/components/incidents/create_timeline_event.vue';
+import TimelineEventsForm from '~/issues/show/components/incidents/timeline_events_form.vue';
+import createTimelineEventMutation from '~/issues/show/components/incidents/graphql/queries/create_timeline_event.mutation.graphql';
+import getTimelineEvents from '~/issues/show/components/incidents/graphql/queries/get_timeline_events.query.graphql';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { createAlert } from '~/flash';
+import { useFakeDate } from 'helpers/fake_date';
+import {
+ timelineEventsCreateEventResponse,
+ timelineEventsCreateEventError,
+ mockGetTimelineData,
+} from './mock_data';
+
+Vue.use(VueApollo);
+
+jest.mock('~/flash');
+
+const fakeDate = '2020-07-08T00:00:00.000Z';
+
+const mockInputData = {
+ incidentId: 'gid://gitlab/Issue/1',
+ note: 'test',
+ occurredAt: '2020-07-08T00:00:00.000Z',
+};
+
+describe('Create Timeline events', () => {
+ useFakeDate(fakeDate);
+ let wrapper;
+ let responseSpy;
+ let apolloProvider;
+
+ const findSubmitButton = () => wrapper.findByText(__('Save'));
+ const findSubmitAndAddButton = () =>
+ wrapper.findByText(s__('Incident|Save and add another event'));
+ const findCancelButton = () => wrapper.findByText(__('Cancel'));
+ const findDatePicker = () => wrapper.findComponent(GlDatepicker);
+ const findNoteInput = () => wrapper.findByTestId('input-note');
+ const setNoteInput = () => {
+ const textarea = findNoteInput().element;
+ textarea.value = mockInputData.note;
+ textarea.dispatchEvent(new Event('input'));
+ };
+ const findHourInput = () => wrapper.findByTestId('input-hours');
+ const findMinuteInput = () => wrapper.findByTestId('input-minutes');
+ const setDatetime = () => {
+ const inputDate = new Date(mockInputData.occurredAt);
+ findDatePicker().vm.$emit('input', inputDate);
+ findHourInput().vm.$emit('input', inputDate.getHours());
+ findMinuteInput().vm.$emit('input', inputDate.getMinutes());
+ };
+ const fillForm = () => {
+ setDatetime();
+ setNoteInput();
+ };
+
+ function createMockApolloProvider() {
+ const requestHandlers = [[createTimelineEventMutation, responseSpy]];
+ const mockApollo = createMockApollo(requestHandlers);
+
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getTimelineEvents,
+ data: mockGetTimelineData,
+ variables: {
+ fullPath: 'group/project',
+ incidentId: 'gid://gitlab/Issue/1',
+ },
+ });
+
+ return mockApollo;
+ }
+
+ const mountComponent = () => {
+ wrapper = mountExtended(CreateTimelineEvent, {
+ propsData: {
+ hasTimelineEvents: true,
+ },
+ provide: {
+ fullPath: 'group/project',
+ issuableId: '1',
+ },
+ apolloProvider,
+ });
+ };
+
+ beforeEach(() => {
+ responseSpy = jest.fn().mockResolvedValue(timelineEventsCreateEventResponse);
+ apolloProvider = createMockApolloProvider();
+ });
+
+ afterEach(() => {
+ createAlert.mockReset();
+ wrapper.destroy();
+ });
+
+ describe('createIncidentTimelineEvent', () => {
+ const closeFormEvent = { 'hide-new-timeline-events-form': [[]] };
+
+ const expectedData = {
+ input: mockInputData,
+ };
+
+ beforeEach(() => {
+ mountComponent();
+ fillForm();
+ });
+
+ describe('on submit', () => {
+ beforeEach(async () => {
+ findSubmitButton().trigger('click');
+ await waitForPromises();
+ });
+
+ it('should call the mutation with the right variables', () => {
+ expect(responseSpy).toHaveBeenCalledWith(expectedData);
+ });
+
+ it('should close the form on successful addition', () => {
+ expect(wrapper.emitted()).toEqual(closeFormEvent);
+ });
+ });
+
+ describe('on submit and add', () => {
+ beforeEach(async () => {
+ findSubmitAndAddButton().trigger('click');
+ await waitForPromises();
+ });
+
+ it('should keep the form open for save and add another', () => {
+ expect(wrapper.emitted()).toEqual({});
+ });
+ });
+
+ describe('on cancel', () => {
+ beforeEach(async () => {
+ findCancelButton().trigger('click');
+ await waitForPromises();
+ });
+
+ it('should close the form', () => {
+ expect(wrapper.emitted()).toEqual(closeFormEvent);
+ });
+ });
+ });
+
+ describe('error handling', () => {
+ it('should show an error when submission returns an error', async () => {
+ const expectedAlertArgs = {
+ message: `Error creating incident timeline event: ${timelineEventsCreateEventError.data.timelineEventCreate.errors[0]}`,
+ };
+ responseSpy.mockResolvedValueOnce(timelineEventsCreateEventError);
+ mountComponent();
+
+ findSubmitButton().trigger('click');
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalledWith(expectedAlertArgs);
+ });
+
+ it('should show an error when submission fails', async () => {
+ const expectedAlertArgs = {
+ captureError: true,
+ error: new Error(),
+ message: 'Something went wrong while creating the incident timeline event.',
+ };
+ responseSpy.mockRejectedValueOnce();
+ mountComponent();
+
+ findSubmitButton().trigger('click');
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalledWith(expectedAlertArgs);
+ });
+
+ it('should keep the form open on failed addition', async () => {
+ responseSpy.mockResolvedValueOnce(timelineEventsCreateEventError);
+ mountComponent();
+
+ await wrapper.findComponent(TimelineEventsForm).vm.$emit('save-event', mockInputData);
+ await waitForPromises;
+ expect(wrapper.emitted()).toEqual({});
+ });
+ });
+});
diff --git a/spec/frontend/issues/show/components/incidents/mock_data.js b/spec/frontend/issues/show/components/incidents/mock_data.js
index afc6099caf4..75c0a7350ae 100644
--- a/spec/frontend/issues/show/components/incidents/mock_data.js
+++ b/spec/frontend/issues/show/components/incidents/mock_data.js
@@ -72,10 +72,14 @@ export const timelineEventsQueryEmptyResponse = {
};
export const timelineEventsCreateEventResponse = {
- timelineEvent: {
- ...mockEvents[0],
+ data: {
+ timelineEventCreate: {
+ timelineEvent: {
+ ...mockEvents[0],
+ },
+ errors: [],
+ },
},
- errors: [],
};
export const timelineEventsCreateEventError = {
@@ -103,3 +107,21 @@ const timelineEventDeleteData = (errors = []) => {
export const timelineEventsDeleteEventResponse = timelineEventDeleteData();
export const timelineEventsDeleteEventError = timelineEventDeleteData(['Item does not exist']);
+
+export const mockGetTimelineData = {
+ project: {
+ id: 'gid://gitlab/Project/19',
+ incidentManagementTimelineEvents: {
+ nodes: [
+ {
+ id: 'gid://gitlab/IncidentManagement::TimelineEvent/8',
+ note: 'another one2',
+ noteHtml: '<p>another one2</p>',
+ action: 'comment',
+ occurredAt: '2022-07-01T12:47:00Z',
+ createdAt: '2022-07-20T12:47:40Z',
+ },
+ ],
+ },
+ },
+};
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
index 620cdfc53b0..cd2cbb63246 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
@@ -3,49 +3,33 @@ import Vue, { nextTick } from 'vue';
import { GlDatepicker } from '@gitlab/ui';
import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import IncidentTimelineEventForm from '~/issues/show/components/incidents/timeline_events_form.vue';
-import createTimelineEventMutation from '~/issues/show/components/incidents/graphql/queries/create_timeline_event.mutation.graphql';
-import createMockApollo from 'helpers/mock_apollo_helper';
+import TimelineEventsForm from '~/issues/show/components/incidents/timeline_events_form.vue';
import { createAlert } from '~/flash';
import { useFakeDate } from 'helpers/fake_date';
-import { timelineEventsCreateEventResponse, timelineEventsCreateEventError } from './mock_data';
Vue.use(VueApollo);
jest.mock('~/flash');
-const addEventResponse = jest.fn().mockResolvedValue(timelineEventsCreateEventResponse);
-
-function createMockApolloProvider(response = addEventResponse) {
- const requestHandlers = [[createTimelineEventMutation, response]];
- return createMockApollo(requestHandlers);
-}
+const fakeDate = '2020-07-08T00:00:00.000Z';
describe('Timeline events form', () => {
// July 8 2020
- useFakeDate(2020, 6, 8);
+ useFakeDate(fakeDate);
let wrapper;
- const mountComponent = ({ mockApollo, mountMethod = shallowMountExtended, stubs }) => {
- wrapper = mountMethod(IncidentTimelineEventForm, {
+ const mountComponent = ({ mountMethod = shallowMountExtended }) => {
+ wrapper = mountMethod(TimelineEventsForm, {
propsData: {
hasTimelineEvents: true,
+ isEventProcessed: false,
},
- provide: {
- fullPath: 'group/project',
- issuableId: '1',
- },
- apolloProvider: mockApollo,
- stubs,
});
};
afterEach(() => {
- addEventResponse.mockReset();
createAlert.mockReset();
- if (wrapper) {
- wrapper.destroy();
- }
+ wrapper.destroy();
});
const findSubmitButton = () => wrapper.findByText('Save');
@@ -75,24 +59,28 @@ describe('Timeline events form', () => {
};
describe('form button behaviour', () => {
- const closeFormEvent = { 'hide-incident-timeline-event-form': [[]] };
beforeEach(() => {
- mountComponent({ mockApollo: createMockApolloProvider(), mountMethod: mountExtended });
+ mountComponent({ mountMethod: mountExtended });
});
- it('should close the form on submit', async () => {
+ it('should save event on submit', async () => {
await submitForm();
- expect(wrapper.emitted()).toEqual(closeFormEvent);
+
+ expect(wrapper.emitted()).toEqual({
+ 'save-event': [[{ note: '', occurredAt: fakeDate }, false]],
+ });
});
- it('should not close the form on "submit and add another"', async () => {
+ it('should save event on "submit and add another"', async () => {
await submitFormAndAddAnother();
- expect(wrapper.emitted()).toEqual({});
+ expect(wrapper.emitted()).toEqual({
+ 'save-event': [[{ note: '', occurredAt: fakeDate }, true]],
+ });
});
- it('should close the form on cancel', async () => {
+ it('should emit cancel on cancel', async () => {
await cancelForm();
- expect(wrapper.emitted()).toEqual(closeFormEvent);
+ expect(wrapper.emitted()).toEqual({ cancel: [[]] });
});
it('should clear the form', async () => {
@@ -111,71 +99,4 @@ describe('Timeline events form', () => {
expect(findMinuteInput().element.value).toBe('0');
});
});
-
- describe('addTimelineEventQuery', () => {
- const expectedData = {
- input: {
- incidentId: 'gid://gitlab/Issue/1',
- note: '',
- occurredAt: '2020-07-08T00:00:00.000Z',
- },
- };
-
- let mockApollo;
-
- beforeEach(() => {
- mockApollo = createMockApolloProvider();
- mountComponent({ mockApollo, mountMethod: mountExtended });
- });
-
- it('should call the mutation with the right variables', async () => {
- await submitForm();
-
- expect(addEventResponse).toHaveBeenCalledWith(expectedData);
- });
-
- it('should call the mutation with user selected variables', async () => {
- const expectedUserSelectedData = {
- input: {
- ...expectedData.input,
- occurredAt: '2021-08-12T05:45:00.000Z',
- },
- };
-
- setDatetime();
-
- await nextTick();
- await submitForm();
-
- expect(addEventResponse).toHaveBeenCalledWith(expectedUserSelectedData);
- });
- });
-
- describe('error handling', () => {
- it('should show an error when submission returns an error', async () => {
- const expectedAlertArgs = {
- message: 'Error creating incident timeline event: Create error',
- };
- addEventResponse.mockResolvedValueOnce(timelineEventsCreateEventError);
- mountComponent({ mockApollo: createMockApolloProvider(), mountMethod: mountExtended });
-
- await submitForm();
-
- expect(createAlert).toHaveBeenCalledWith(expectedAlertArgs);
- });
-
- it('should show an error when submission fails', async () => {
- const expectedAlertArgs = {
- captureError: true,
- error: new Error(),
- message: 'Something went wrong while creating the incident timeline event.',
- };
- addEventResponse.mockRejectedValueOnce();
- mountComponent({ mockApollo: createMockApolloProvider(), mountMethod: mountExtended });
-
- await submitForm();
-
- expect(createAlert).toHaveBeenCalledWith(expectedAlertArgs);
- });
- });
});
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js
index 2d87851a761..2cdb971395d 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js
@@ -5,7 +5,7 @@ import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_help
import waitForPromises from 'helpers/wait_for_promises';
import TimelineEventsTab from '~/issues/show/components/incidents/timeline_events_tab.vue';
import IncidentTimelineEventsList from '~/issues/show/components/incidents/timeline_events_list.vue';
-import IncidentTimelineEventForm from '~/issues/show/components/incidents/timeline_events_form.vue';
+import CreateTimelineEvent from '~/issues/show/components/incidents/create_timeline_event.vue';
import timelineEventsQuery from '~/issues/show/components/incidents/graphql/queries/get_timeline_events.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createAlert } from '~/flash';
@@ -53,7 +53,7 @@ describe('TimelineEventsTab', () => {
const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findTimelineEventsList = () => wrapper.findComponent(IncidentTimelineEventsList);
- const findTimelineEventForm = () => wrapper.findComponent(IncidentTimelineEventForm);
+ const findCreateTimelineEvent = () => wrapper.findComponent(CreateTimelineEvent);
const findAddEventButton = () => wrapper.findByText(timelineTabI18n.addEventButton);
describe('Timeline events tab', () => {
@@ -143,18 +143,18 @@ describe('TimelineEventsTab', () => {
});
it('should not show a form by default', () => {
- expect(findTimelineEventForm().isVisible()).toBe(false);
+ expect(findCreateTimelineEvent().isVisible()).toBe(false);
});
it('should show a form when button is clicked', async () => {
await findAddEventButton().trigger('click');
- expect(findTimelineEventForm().isVisible()).toBe(true);
+ expect(findCreateTimelineEvent().isVisible()).toBe(true);
});
it('should clear the form when button is clicked', async () => {
const mockClear = jest.fn();
- wrapper.vm.$refs.eventForm.clear = mockClear;
+ wrapper.vm.$refs.createEventForm.clearForm = mockClear;
await findAddEventButton().trigger('click');
@@ -165,9 +165,9 @@ describe('TimelineEventsTab', () => {
// open the form
await findAddEventButton().trigger('click');
- await findTimelineEventForm().vm.$emit('hide-incident-timeline-event-form');
+ await findCreateTimelineEvent().vm.$emit('hide-new-timeline-events-form');
- expect(findTimelineEventForm().isVisible()).toBe(false);
+ expect(findCreateTimelineEvent().isVisible()).toBe(false);
});
});
});
diff --git a/spec/services/database/consistency_check_service_spec.rb b/spec/services/database/consistency_check_service_spec.rb
index 2e642451432..6695e4b5e9f 100644
--- a/spec/services/database/consistency_check_service_spec.rb
+++ b/spec/services/database/consistency_check_service_spec.rb
@@ -24,9 +24,27 @@ RSpec.describe Database::ConsistencyCheckService do
)
end
- describe '#random_start_id' do
- let(:batch_size) { 5 }
+ describe '#min_id' do
+ before do
+ create_list(:namespace, 3)
+ end
+ it 'returns the id of the first record in the database' do
+ expect(subject.send(:min_id)).to eq(Namespace.first.id)
+ end
+ end
+
+ describe '#max_id' do
+ before do
+ create_list(:namespace, 3)
+ end
+
+ it 'returns the id of the first record in the database' do
+ expect(subject.send(:max_id)).to eq(Namespace.last.id)
+ end
+ end
+
+ describe '#random_start_id' do
before do
create_list(:namespace, 50) # This will also create Ci::NameSpaceMirror objects
end
@@ -58,12 +76,11 @@ RSpec.describe Database::ConsistencyCheckService do
end
context 'no cursor has been saved before' do
- let(:selected_start_id) { Namespace.order(:id).limit(5).pluck(:id).last }
- let(:expected_next_start_id) { selected_start_id + batch_size * max_batches }
+ let(:min_id) { Namespace.first.id }
+ let(:max_id) { Namespace.last.id }
before do
create_list(:namespace, 50) # This will also create Ci::NameSpaceMirror objects
- expect(consistency_check_service).to receive(:random_start_id).and_return(selected_start_id)
end
it 'picks a random start_id' do
@@ -72,17 +89,21 @@ RSpec.describe Database::ConsistencyCheckService do
matches: 10,
mismatches: 0,
mismatches_details: [],
- start_id: selected_start_id,
- next_start_id: expected_next_start_id
+ start_id: be_between(min_id, max_id),
+ next_start_id: be_between(min_id, max_id)
}
- expect(consistency_check_service.execute).to eq(expected_result)
+ expect(consistency_check_service).to receive(:rand).with(min_id..max_id).and_call_original
+ result = consistency_check_service.execute
+ expect(result).to match(expected_result)
end
it 'calls the ConsistencyCheckService with the expected parameters' do
+ expect(consistency_check_service).to receive(:random_start_id).and_return(min_id)
+
allow_next_instance_of(Gitlab::Database::ConsistencyChecker) do |instance|
- expect(instance).to receive(:execute).with(start_id: selected_start_id).and_return({
+ expect(instance).to receive(:execute).with(start_id: min_id).and_return({
batches: 2,
- next_start_id: expected_next_start_id,
+ next_start_id: min_id + batch_size,
matches: 10,
mismatches: 0,
mismatches_details: []
@@ -98,17 +119,19 @@ RSpec.describe Database::ConsistencyCheckService do
expected_result = {
batches: 2,
- start_id: selected_start_id,
- next_start_id: expected_next_start_id,
matches: 10,
mismatches: 0,
- mismatches_details: []
+ mismatches_details: [],
+ start_id: be_between(min_id, max_id),
+ next_start_id: be_between(min_id, max_id)
}
- expect(consistency_check_service.execute).to eq(expected_result)
+ result = consistency_check_service.execute
+ expect(result).to match(expected_result)
end
it 'saves the next_start_id in Redis for he next iteration' do
- expect(consistency_check_service).to receive(:save_next_start_id).with(expected_next_start_id).and_call_original
+ expect(consistency_check_service).to receive(:save_next_start_id)
+ .with(be_between(min_id, max_id)).and_call_original
consistency_check_service.execute
end
end
diff --git a/spec/services/git/branch_push_service_spec.rb b/spec/services/git/branch_push_service_spec.rb
index 36a723db9e8..6280f1263c3 100644
--- a/spec/services/git/branch_push_service_spec.rb
+++ b/spec/services/git/branch_push_service_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Git::BranchPushService, services: true do
include RepoHelpers
let_it_be(:user) { create(:user) }
- let_it_be(:project, reload: true) { create(:project, :repository) }
+ let_it_be_with_refind(:project) { create(:project, :repository) }
let(:blankrev) { Gitlab::Git::BLANK_SHA }
let(:oldrev) { sample_commit.parent_id }
diff --git a/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb b/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb
index 345dfbce423..95c0a76d726 100644
--- a/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb
+++ b/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb
@@ -16,7 +16,9 @@ RSpec.shared_examples 'date sidebar widget' do
page.within('[data-testid="sidebar-due-date"]') do
today = Date.today.day
- click_button 'Edit'
+ button = find_button('Edit')
+ scroll_to(button)
+ button.click
click_button today.to_s