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
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared')
-rw-r--r--spec/frontend/vue_shared/alert_details/alert_details_spec.js6
-rw-r--r--spec/frontend/vue_shared/alert_details/alert_metrics_spec.js4
-rw-r--r--spec/frontend/vue_shared/alert_details/alert_status_spec.js2
-rw-r--r--spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js4
-rw-r--r--spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_spec.js4
-rw-r--r--spec/frontend/vue_shared/alert_details/system_notes/alert_management_system_note_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/actions_button_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/alert_details_table_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/changed_file_icon_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/ci_icon_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/clipboard_button_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/clone_dropdown_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/color_picker/color_picker_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/commit_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/confirm_modal_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/dismissible_alert_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/dismissible_container_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js77
-rw-r--r--spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/expand_button_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/file_icon_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/file_row_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/file_tree_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js44
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js8
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/gitlab_version_check_spec.js31
-rw-r--r--spec/frontend/vue_shared/components/gl_modal_vuex_spec.js10
-rw-r--r--spec/frontend/vue_shared/components/help_popover_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/integration_help_text_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js7
-rw-r--r--spec/frontend/vue_shared/components/markdown/header_spec.js17
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/memory_graph_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js81
-rw-r--r--spec/frontend/vue_shared/components/navigation_tabs_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/notes/noteable_warning_spec.js13
-rw-r--r--spec/frontend/vue_shared/components/notes/placeholder_note_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js18
-rw-r--r--spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/pagination_links_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/project_avatar_spec.js36
-rw-r--r--spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/project_selector/project_selector_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/registry/code_instruction_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/registry/details_row_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/registry/history_item_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/registry/list_item_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/registry/metadata_item_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/registry/registry_search_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/registry/title_area_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js41
-rw-r--r--spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/security_reports/help_icon_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js32
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js16
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js16
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/sidebar/todo_button_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/source_editor_spec.js26
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js29
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js9
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js2
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js3
-rw-r--r--spec/frontend/vue_shared/components/split_button_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/table_pagination_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/user_access_role_badge_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js45
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js64
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js64
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/user_popover/user_popover_spec.js39
-rw-r--r--spec/frontend/vue_shared/components/user_select_spec.js95
-rw-r--r--spec/frontend/vue_shared/components/web_ide_link_spec.js10
-rw-r--r--spec/frontend/vue_shared/issuable/create/components/issuable_create_root_spec.js4
-rw-r--r--spec/frontend/vue_shared/issuable/create/components/issuable_form_spec.js14
-rw-r--r--spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js48
-rw-r--r--spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js12
-rw-r--r--spec/frontend/vue_shared/issuable/list/mock_data.js1
-rw-r--r--spec/frontend/vue_shared/issuable/show/components/issuable_body_spec.js10
-rw-r--r--spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js6
-rw-r--r--spec/frontend/vue_shared/issuable/show/components/issuable_header_spec.js12
-rw-r--r--spec/frontend/vue_shared/issuable/show/components/issuable_show_root_spec.js22
-rw-r--r--spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js4
-rw-r--r--spec/frontend/vue_shared/security_reports/security_reports_app_spec.js4
107 files changed, 861 insertions, 525 deletions
diff --git a/spec/frontend/vue_shared/alert_details/alert_details_spec.js b/spec/frontend/vue_shared/alert_details/alert_details_spec.js
index ce51af31a70..59e21b2ff40 100644
--- a/spec/frontend/vue_shared/alert_details/alert_details_spec.js
+++ b/spec/frontend/vue_shared/alert_details/alert_details_spec.js
@@ -285,14 +285,14 @@ describe('AlertDetails', () => {
});
it('displays a loading state when loading', () => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
});
describe('error state', () => {
it('displays a error state correctly', () => {
mountComponent({ data: { errored: true } });
- expect(wrapper.find(GlAlert).exists()).toBe(true);
+ expect(wrapper.findComponent(GlAlert).exists()).toBe(true);
});
it('renders html-errors correctly', () => {
@@ -304,7 +304,7 @@ describe('AlertDetails', () => {
it('does not display an error when dismissed', () => {
mountComponent({ data: { errored: true, isErrorDismissed: true } });
- expect(wrapper.find(GlAlert).exists()).toBe(false);
+ expect(wrapper.findComponent(GlAlert).exists()).toBe(false);
});
});
diff --git a/spec/frontend/vue_shared/alert_details/alert_metrics_spec.js b/spec/frontend/vue_shared/alert_details/alert_metrics_spec.js
index 1216681038f..cf04c1eb24a 100644
--- a/spec/frontend/vue_shared/alert_details/alert_metrics_spec.js
+++ b/spec/frontend/vue_shared/alert_details/alert_metrics_spec.js
@@ -28,8 +28,8 @@ describe('Alert Metrics', () => {
});
}
- const findChart = () => wrapper.find(MetricEmbed);
- const findEmptyState = () => wrapper.find({ ref: 'emptyState' });
+ const findChart = () => wrapper.findComponent(MetricEmbed);
+ const findEmptyState = () => wrapper.findComponent({ ref: 'emptyState' });
afterEach(() => {
if (wrapper) {
diff --git a/spec/frontend/vue_shared/alert_details/alert_status_spec.js b/spec/frontend/vue_shared/alert_details/alert_status_spec.js
index ba3b0335a8e..2a37ff2b784 100644
--- a/spec/frontend/vue_shared/alert_details/alert_status_spec.js
+++ b/spec/frontend/vue_shared/alert_details/alert_status_spec.js
@@ -13,7 +13,7 @@ describe('AlertManagementStatus', () => {
let wrapper;
const findStatusDropdown = () => wrapper.findComponent(GlDropdown);
const findFirstStatusOption = () => findStatusDropdown().findComponent(GlDropdownItem);
- const findAllStatusOptions = () => findStatusDropdown().findAll(GlDropdownItem);
+ const findAllStatusOptions = () => findStatusDropdown().findAllComponents(GlDropdownItem);
const findStatusDropdownHeader = () => wrapper.findByTestId('dropdown-header');
const selectFirstStatusOption = () => {
diff --git a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js
index 29569734621..5a0ee5a59ba 100644
--- a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js
+++ b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js
@@ -128,7 +128,7 @@ describe('Alert Details Sidebar Assignees', () => {
wrapper.setData({ isDropdownSearching: false });
await nextTick();
- wrapper.find(SidebarAssignee).vm.$emit('update-alert-assignees', 'root');
+ wrapper.findComponent(SidebarAssignee).vm.$emit('update-alert-assignees', 'root');
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: AlertSetAssignees,
@@ -156,7 +156,7 @@ describe('Alert Details Sidebar Assignees', () => {
jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(errorMutationResult);
await nextTick();
- const SideBarAssigneeItem = wrapper.findAll(SidebarAssignee).at(0);
+ const SideBarAssigneeItem = wrapper.findAllComponents(SidebarAssignee).at(0);
await SideBarAssigneeItem.vm.$emit('update-alert-assignees');
expect(wrapper.emitted('alert-error')).toBeDefined();
});
diff --git a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_spec.js b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_spec.js
index ef75e038bff..3b38349622f 100644
--- a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_spec.js
+++ b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_spec.js
@@ -65,7 +65,7 @@ describe('Alert Details Sidebar', () => {
mountMethod: mount,
alert: mockAlert,
});
- expect(wrapper.find(SidebarAssignees).exists()).toBe(true);
+ expect(wrapper.findComponent(SidebarAssignees).exists()).toBe(true);
});
it('should render side bar status dropdown', () => {
@@ -73,7 +73,7 @@ describe('Alert Details Sidebar', () => {
mountMethod: mount,
alert: mockAlert,
});
- expect(wrapper.find(SidebarStatus).exists()).toBe(true);
+ expect(wrapper.findComponent(SidebarStatus).exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/alert_details/system_notes/alert_management_system_note_spec.js b/spec/frontend/vue_shared/alert_details/system_notes/alert_management_system_note_spec.js
index a5a9fb55737..6a750bb99c0 100644
--- a/spec/frontend/vue_shared/alert_details/system_notes/alert_management_system_note_spec.js
+++ b/spec/frontend/vue_shared/alert_details/system_notes/alert_management_system_note_spec.js
@@ -31,7 +31,7 @@ describe('Alert Details System Note', () => {
it('renders the correct system note', () => {
const noteId = wrapper.find('.note-wrapper').attributes('id');
- const iconName = wrapper.find(GlIcon).attributes('name');
+ const iconName = wrapper.findComponent(GlIcon).attributes('name');
expect(noteId).toBe('note_1628');
expect(iconName).toBe(mockAlert.notes.nodes[0].systemNoteIconName);
diff --git a/spec/frontend/vue_shared/components/actions_button_spec.js b/spec/frontend/vue_shared/components/actions_button_spec.js
index e5b7b693cb5..07c53c04723 100644
--- a/spec/frontend/vue_shared/components/actions_button_spec.js
+++ b/spec/frontend/vue_shared/components/actions_button_spec.js
@@ -45,9 +45,9 @@ describe('Actions button component', () => {
return directiveBinding.value;
};
- const findButton = () => wrapper.find(GlButton);
+ const findButton = () => wrapper.findComponent(GlButton);
const findButtonTooltip = () => getTooltip(findButton());
- const findDropdown = () => wrapper.find(GlDropdown);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownTooltip = () => getTooltip(findDropdown());
const parseDropdownItems = () =>
findDropdown()
diff --git a/spec/frontend/vue_shared/components/alert_details_table_spec.js b/spec/frontend/vue_shared/components/alert_details_table_spec.js
index b9a8a5bee97..8a9ee4699bd 100644
--- a/spec/frontend/vue_shared/components/alert_details_table_spec.js
+++ b/spec/frontend/vue_shared/components/alert_details_table_spec.js
@@ -74,7 +74,7 @@ describe('AlertDetails', () => {
});
it('displays a loading state when loading', () => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
});
@@ -130,7 +130,7 @@ describe('AlertDetails', () => {
environmentData = { name: null, path: null };
mountComponent();
- expect(findTableFieldValueByKey('Environment').text()).toBeFalsy();
+ expect(findTableFieldValueByKey('Environment').text()).toBe('');
});
});
diff --git a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
index d14f3e5559f..ce7fd40937f 100644
--- a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
@@ -43,6 +43,6 @@ describe('Blob Rich Viewer component', () => {
});
it('is using Markdown View Field', () => {
- expect(wrapper.find(MarkdownFieldView).exists()).toBe(true);
+ expect(wrapper.findComponent(MarkdownFieldView).exists()).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/components/changed_file_icon_spec.js b/spec/frontend/vue_shared/components/changed_file_icon_spec.js
index 6b9658a6d18..ea708b6f3fe 100644
--- a/spec/frontend/vue_shared/components/changed_file_icon_spec.js
+++ b/spec/frontend/vue_shared/components/changed_file_icon_spec.js
@@ -25,7 +25,7 @@ describe('Changed file icon', () => {
wrapper.destroy();
});
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const findIconName = () => findIcon().props('name');
const findIconClasses = () => findIcon().classes();
const findTooltipText = () => wrapper.attributes('title');
@@ -51,7 +51,7 @@ describe('Changed file icon', () => {
showTooltip: false,
});
- expect(findTooltipText()).toBeFalsy();
+ expect(findTooltipText()).toBeUndefined();
});
describe.each`
@@ -87,7 +87,7 @@ describe('Changed file icon', () => {
});
it('does not have tooltip text', () => {
- expect(findTooltipText()).toBeFalsy();
+ expect(findTooltipText()).toBeUndefined();
});
});
diff --git a/spec/frontend/vue_shared/components/ci_icon_spec.js b/spec/frontend/vue_shared/components/ci_icon_spec.js
index 1b502f9587c..2064bee9673 100644
--- a/spec/frontend/vue_shared/components/ci_icon_spec.js
+++ b/spec/frontend/vue_shared/components/ci_icon_spec.js
@@ -22,7 +22,7 @@ describe('CI Icon component', () => {
});
expect(wrapper.find('span').exists()).toBe(true);
- expect(wrapper.find(GlIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
});
describe('active icons', () => {
diff --git a/spec/frontend/vue_shared/components/clipboard_button_spec.js b/spec/frontend/vue_shared/components/clipboard_button_spec.js
index fca5e664a96..b18b00e70bb 100644
--- a/spec/frontend/vue_shared/components/clipboard_button_spec.js
+++ b/spec/frontend/vue_shared/components/clipboard_button_spec.js
@@ -21,7 +21,7 @@ describe('clipboard button', () => {
});
};
- const findButton = () => wrapper.find(GlButton);
+ const findButton = () => wrapper.findComponent(GlButton);
const expectConfirmationTooltip = async ({ event, message }) => {
const title = 'Copy this value';
diff --git a/spec/frontend/vue_shared/components/clone_dropdown_spec.js b/spec/frontend/vue_shared/components/clone_dropdown_spec.js
index eefd1838988..31c08260dd0 100644
--- a/spec/frontend/vue_shared/components/clone_dropdown_spec.js
+++ b/spec/frontend/vue_shared/components/clone_dropdown_spec.js
@@ -38,9 +38,9 @@ describe('Clone Dropdown Button', () => {
${'HTTP'} | ${1} | ${httpLink}
`('renders correct link and a copy-button for $name', ({ index, value }) => {
createComponent();
- const group = wrapper.findAll(GlFormInputGroup).at(index);
+ const group = wrapper.findAllComponents(GlFormInputGroup).at(index);
expect(group.props('value')).toBe(value);
- expect(group.find(GlFormInputGroup).exists()).toBe(true);
+ expect(group.findComponent(GlFormInputGroup).exists()).toBe(true);
});
it.each`
@@ -50,8 +50,8 @@ describe('Clone Dropdown Button', () => {
`('does not fail if only $name is set', ({ name, value }) => {
createComponent({ [name]: value });
- expect(wrapper.find(GlFormInputGroup).props('value')).toBe(value);
- expect(wrapper.findAll(GlDropdownSectionHeader).length).toBe(1);
+ expect(wrapper.findComponent(GlFormInputGroup).props('value')).toBe(value);
+ expect(wrapper.findAllComponents(GlDropdownSectionHeader).length).toBe(1);
});
});
@@ -63,12 +63,12 @@ describe('Clone Dropdown Button', () => {
`('allows null values for the props', ({ name, value }) => {
createComponent({ ...defaultPropsData, [name]: value });
- expect(wrapper.findAll(GlDropdownSectionHeader).length).toBe(1);
+ expect(wrapper.findAllComponents(GlDropdownSectionHeader).length).toBe(1);
});
it('correctly calculates httpLabel for HTTPS protocol', () => {
createComponent({ httpLink: httpsLink });
- expect(wrapper.find(GlDropdownSectionHeader).text()).toContain('HTTPS');
+ expect(wrapper.findComponent(GlDropdownSectionHeader).text()).toContain('HTTPS');
});
});
});
diff --git a/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js b/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
index 8cbe0630426..060048c4bbd 100644
--- a/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
+++ b/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
@@ -16,14 +16,14 @@ describe('ColorPicker', () => {
const setColor = '#000000';
const invalidText = 'Please enter a valid hex (#RRGGBB or #RGB) color value';
- const findGlFormGroup = () => wrapper.find(GlFormGroup);
+ const findGlFormGroup = () => wrapper.findComponent(GlFormGroup);
const colorPreview = () => wrapper.find('[data-testid="color-preview"]');
- const colorPicker = () => wrapper.find(GlFormInput);
+ const colorPicker = () => wrapper.findComponent(GlFormInput);
const colorInput = () => wrapper.find('input[type="color"]');
- const colorTextInput = () => wrapper.find(GlFormInputGroup).find('input[type="text"]');
+ const colorTextInput = () => wrapper.findComponent(GlFormInputGroup).find('input[type="text"]');
const invalidFeedback = () => wrapper.find('.invalid-feedback');
- const description = () => wrapper.find(GlFormGroup).attributes('description');
- const presetColors = () => wrapper.findAll(GlLink);
+ const description = () => wrapper.findComponent(GlFormGroup).attributes('description');
+ const presetColors = () => wrapper.findAllComponents(GlLink);
beforeEach(() => {
gon.suggested_label_colors = {
diff --git a/spec/frontend/vue_shared/components/commit_spec.js b/spec/frontend/vue_shared/components/commit_spec.js
index d91853e7b79..1893e127f6f 100644
--- a/spec/frontend/vue_shared/components/commit_spec.js
+++ b/spec/frontend/vue_shared/components/commit_spec.js
@@ -9,11 +9,11 @@ describe('Commit component', () => {
let wrapper;
const findIcon = (name) => {
- const icons = wrapper.findAll(GlIcon).filter((c) => c.attributes('name') === name);
+ const icons = wrapper.findAllComponents(GlIcon).filter((c) => c.attributes('name') === name);
return icons.length ? icons.at(0) : icons;
};
- const findUserAvatar = () => wrapper.find(UserAvatarLink);
+ const findUserAvatar = () => wrapper.findComponent(UserAvatarLink);
const findRefName = () => wrapper.findByTestId('ref-name');
const createComponent = (propsData) => {
@@ -47,7 +47,7 @@ describe('Commit component', () => {
},
});
- expect(wrapper.find('.icon-container').find(GlIcon).exists()).toBe(true);
+ expect(wrapper.find('.icon-container').findComponent(GlIcon).exists()).toBe(true);
});
describe('Given all the props', () => {
diff --git a/spec/frontend/vue_shared/components/confirm_modal_spec.js b/spec/frontend/vue_shared/components/confirm_modal_spec.js
index 3ca1c943398..c1e682a1aae 100644
--- a/spec/frontend/vue_shared/components/confirm_modal_spec.js
+++ b/spec/frontend/vue_shared/components/confirm_modal_spec.js
@@ -51,13 +51,13 @@ describe('vue_shared/components/confirm_modal', () => {
wrapper.destroy();
});
- const findModal = () => wrapper.find(GlModalStub);
+ const findModal = () => wrapper.findComponent(GlModalStub);
const findForm = () => wrapper.find('form');
const findFormData = () =>
findForm()
.findAll('input')
.wrappers.map((x) => ({ name: x.attributes('name'), value: x.attributes('value') }));
- const findDomElementListener = () => wrapper.find(DomElementListener);
+ const findDomElementListener = () => wrapper.findComponent(DomElementListener);
const triggerOpenWithEventHub = (modalData) => {
eventHub.$emit(EVENT_OPEN_CONFIRM_MODAL, modalData);
};
@@ -104,7 +104,7 @@ describe('vue_shared/components/confirm_modal', () => {
});
it('renders GlModal with data', () => {
- expect(findModal().exists()).toBeTruthy();
+ expect(findModal().exists()).toBe(true);
expect(findModal().attributes()).toEqual(
expect.objectContaining({
oktitle: MOCK_MODAL_DATA.modalAttributes.okTitle,
diff --git a/spec/frontend/vue_shared/components/dismissible_alert_spec.js b/spec/frontend/vue_shared/components/dismissible_alert_spec.js
index 879d4aba441..8b1189f25d5 100644
--- a/spec/frontend/vue_shared/components/dismissible_alert_spec.js
+++ b/spec/frontend/vue_shared/components/dismissible_alert_spec.js
@@ -20,7 +20,7 @@ describe('vue_shared/components/dismissible_alert', () => {
wrapper.destroy();
});
- const findAlert = () => wrapper.find(GlAlert);
+ const findAlert = () => wrapper.findComponent(GlAlert);
describe('default', () => {
beforeEach(() => {
@@ -45,7 +45,7 @@ describe('vue_shared/components/dismissible_alert', () => {
});
it('emmits alertDismissed', () => {
- expect(wrapper.emitted('alertDismissed')).toBeTruthy();
+ expect(wrapper.emitted()).toHaveProperty('alertDismissed');
});
});
});
diff --git a/spec/frontend/vue_shared/components/dismissible_container_spec.js b/spec/frontend/vue_shared/components/dismissible_container_spec.js
index b8aeea38e77..f7030f38709 100644
--- a/spec/frontend/vue_shared/components/dismissible_container_spec.js
+++ b/spec/frontend/vue_shared/components/dismissible_container_spec.js
@@ -33,7 +33,7 @@ describe('DismissibleContainer', () => {
button.trigger('click');
- expect(wrapper.emitted().dismiss).toBeTruthy();
+ expect(wrapper.emitted().dismiss).toEqual(expect.any(Array));
});
});
diff --git a/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js b/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js
index 08e5d828b8f..e34ed31b4bf 100644
--- a/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js
+++ b/spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js
@@ -1,80 +1,71 @@
-import Vue from 'vue';
+import { mount } from '@vue/test-utils';
+import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
-import { mountComponentWithSlots } from 'helpers/vue_mount_component_helper';
-import dropdownButtonComponent from '~/vue_shared/components/dropdown/dropdown_button.vue';
+describe('DropdownButton component', () => {
+ let wrapper;
-const defaultLabel = 'Select';
-const customLabel = 'Select project';
+ const defaultLabel = 'Select';
+ const customLabel = 'Select project';
-const createComponent = (props, slots = {}) => {
- const Component = Vue.extend(dropdownButtonComponent);
-
- return mountComponentWithSlots(Component, { props, slots });
-};
-
-describe('DropdownButtonComponent', () => {
- let vm;
-
- beforeEach(() => {
- vm = createComponent();
- });
+ const createComponent = (props, slots = {}) => {
+ wrapper = mount(DropdownButton, { propsData: props, slots });
+ };
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('computed', () => {
describe('dropdownToggleText', () => {
it('returns default toggle text', () => {
- expect(vm.toggleText).toBe(defaultLabel);
+ createComponent();
+
+ expect(wrapper.vm.toggleText).toBe(defaultLabel);
});
it('returns custom toggle text when provided via props', () => {
- const vmEmptyLabels = createComponent({ toggleText: customLabel });
+ createComponent({ toggleText: customLabel });
- expect(vmEmptyLabels.toggleText).toBe(customLabel);
- vmEmptyLabels.$destroy();
+ expect(wrapper.vm.toggleText).toBe(customLabel);
});
});
});
describe('template', () => {
it('renders component container element of type `button`', () => {
- expect(vm.$el.nodeName).toBe('BUTTON');
+ createComponent();
+
+ expect(wrapper.element.nodeName).toBe('BUTTON');
});
it('renders component container element with required data attributes', () => {
- expect(vm.$el.dataset.abilityName).toBe(vm.abilityName);
- expect(vm.$el.dataset.fieldName).toBe(vm.fieldName);
- expect(vm.$el.dataset.issueUpdate).toBe(vm.updatePath);
- expect(vm.$el.dataset.labels).toBe(vm.labelsPath);
- expect(vm.$el.dataset.namespacePath).toBe(vm.namespace);
- expect(vm.$el.dataset.showAny).not.toBeDefined();
+ createComponent();
+
+ expect(wrapper.element.dataset.abilityName).toBe(wrapper.vm.abilityName);
+ expect(wrapper.element.dataset.fieldName).toBe(wrapper.vm.fieldName);
+ expect(wrapper.element.dataset.issueUpdate).toBe(wrapper.vm.updatePath);
+ expect(wrapper.element.dataset.labels).toBe(wrapper.vm.labelsPath);
+ expect(wrapper.element.dataset.namespacePath).toBe(wrapper.vm.namespace);
+ expect(wrapper.element.dataset.showAny).toBeUndefined();
});
it('renders dropdown toggle text element', () => {
- const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text');
+ createComponent();
- expect(dropdownToggleTextEl).not.toBeNull();
- expect(dropdownToggleTextEl.innerText.trim()).toBe(defaultLabel);
+ expect(wrapper.find('.dropdown-toggle-text').text()).toBe(defaultLabel);
});
it('renders dropdown button icon', () => {
- const dropdownIconEl = vm.$el.querySelector('[data-testid="chevron-down-icon"]');
+ createComponent();
- expect(dropdownIconEl).not.toBeNull();
+ expect(wrapper.find('[data-testid="chevron-down-icon"]').exists()).toBe(true);
});
it('renders slot, if default slot exists', () => {
- vm = createComponent(
- {},
- {
- default: ['Lorem Ipsum Dolar'],
- },
- );
-
- expect(vm.$el.querySelector('.dropdown-toggle-text')).toBeNull();
- expect(vm.$el).toHaveText('Lorem Ipsum Dolar');
+ createComponent({}, { default: ['Lorem Ipsum Dolar'] });
+
+ expect(wrapper.find('.dropdown-toggle-text').exists()).toBe(false);
+ expect(wrapper.text()).toBe('Lorem Ipsum Dolar');
});
});
});
diff --git a/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js b/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
index 084d0559665..dd3e55c82bb 100644
--- a/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
+++ b/spec/frontend/vue_shared/components/dropdown/dropdown_widget_spec.js
@@ -8,7 +8,7 @@ describe('DropdownWidget component', () => {
let wrapper;
const findDropdown = () => wrapper.findComponent(GlDropdown);
- const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findSearch = () => wrapper.findComponent(GlSearchBoxByType);
const createComponent = ({ props = {} } = {}) => {
diff --git a/spec/frontend/vue_shared/components/expand_button_spec.js b/spec/frontend/vue_shared/components/expand_button_spec.js
index 87d6ed6b21f..170c947e520 100644
--- a/spec/frontend/vue_shared/components/expand_button_spec.js
+++ b/spec/frontend/vue_shared/components/expand_button_spec.js
@@ -37,11 +37,11 @@ describe('Expand button', () => {
});
it('renders no text when short text is not provided', () => {
- expect(wrapper.find(ExpandButton).text()).toBe('');
+ expect(wrapper.findComponent(ExpandButton).text()).toBe('');
});
it('does not render expanded text', () => {
- expect(wrapper.find(ExpandButton).text().trim()).not.toBe(text.short);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).not.toBe(text.short);
});
describe('when short text is provided', () => {
@@ -55,13 +55,13 @@ describe('Expand button', () => {
});
it('renders short text', () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.short);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.short);
});
it('renders button before text', () => {
expect(expanderPrependEl().isVisible()).toBe(true);
expect(expanderAppendEl().isVisible()).toBe(false);
- expect(wrapper.find(ExpandButton).element).toMatchSnapshot();
+ expect(wrapper.findComponent(ExpandButton).element).toMatchSnapshot();
});
});
@@ -81,7 +81,7 @@ describe('Expand button', () => {
});
it('renders the expanded text', () => {
- expect(wrapper.find(ExpandButton).text()).toContain(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text()).toContain(text.expanded);
});
describe('when short text is provided', () => {
@@ -98,13 +98,13 @@ describe('Expand button', () => {
});
it('only renders expanded text', () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.expanded);
});
it('renders button after text', () => {
expect(expanderPrependEl().isVisible()).toBe(false);
expect(expanderAppendEl().isVisible()).toBe(true);
- expect(wrapper.find(ExpandButton).element).toMatchSnapshot();
+ expect(wrapper.findComponent(ExpandButton).element).toMatchSnapshot();
});
});
});
@@ -124,11 +124,11 @@ describe('Expand button', () => {
});
it('clicking hides expanded text', async () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.expanded);
expanderAppendEl().trigger('click');
await nextTick();
- expect(wrapper.find(ExpandButton).text().trim()).not.toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).not.toBe(text.expanded);
});
describe('when short text is provided', () => {
@@ -145,11 +145,11 @@ describe('Expand button', () => {
});
it('clicking reveals short text', async () => {
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.expanded);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.expanded);
expanderAppendEl().trigger('click');
await nextTick();
- expect(wrapper.find(ExpandButton).text().trim()).toBe(text.short);
+ expect(wrapper.findComponent(ExpandButton).text().trim()).toBe(text.short);
});
});
});
diff --git a/spec/frontend/vue_shared/components/file_icon_spec.js b/spec/frontend/vue_shared/components/file_icon_spec.js
index b0e623520a8..3f4bfc86b67 100644
--- a/spec/frontend/vue_shared/components/file_icon_spec.js
+++ b/spec/frontend/vue_shared/components/file_icon_spec.js
@@ -6,7 +6,7 @@ import { FILE_SYMLINK_MODE } from '~/vue_shared/constants';
describe('File Icon component', () => {
let wrapper;
const findSvgIcon = () => wrapper.find('svg');
- const findGlIcon = () => wrapper.find(GlIcon);
+ const findGlIcon = () => wrapper.findComponent(GlIcon);
const getIconName = () =>
findSvgIcon()
.find('use')
@@ -61,7 +61,7 @@ describe('File Icon component', () => {
loading: true,
});
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
it('should add a special class and a size class', () => {
diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js
index 62fb29c455c..f5a545891d5 100644
--- a/spec/frontend/vue_shared/components/file_row_spec.js
+++ b/spec/frontend/vue_shared/components/file_row_spec.js
@@ -119,7 +119,7 @@ describe('File row component', () => {
level: 0,
});
- expect(wrapper.find(FileHeader).exists()).toBe(true);
+ expect(wrapper.findComponent(FileHeader).exists()).toBe(true);
});
it('matches the current route against encoded file URL', () => {
@@ -164,6 +164,6 @@ describe('File row component', () => {
level: 0,
});
- expect(wrapper.find(FileIcon).props('submodule')).toBe(submodule);
+ expect(wrapper.findComponent(FileIcon).props('submodule')).toBe(submodule);
});
});
diff --git a/spec/frontend/vue_shared/components/file_tree_spec.js b/spec/frontend/vue_shared/components/file_tree_spec.js
index 39a7c7a2b3a..e8818e09dc0 100644
--- a/spec/frontend/vue_shared/components/file_tree_spec.js
+++ b/spec/frontend/vue_shared/components/file_tree_spec.js
@@ -25,8 +25,8 @@ describe('File Tree component', () => {
});
};
- const findFileRow = () => wrapper.find(MockFileRow);
- const findChildrenTrees = () => wrapper.findAll(FileTree).wrappers.slice(1);
+ const findFileRow = () => wrapper.findComponent(MockFileRow);
+ const findChildrenTrees = () => wrapper.findAllComponents(FileTree).wrappers.slice(1);
const findChildrenTreeProps = () =>
findChildrenTrees().map((x) => ({
...x.props(),
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
index e44bc8771f5..1b9ca8e6092 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
@@ -88,10 +88,10 @@ describe('FilteredSearchBarRoot', () => {
expect(wrapper.vm.filterValue).toEqual([]);
expect(wrapper.vm.selectedSortOption).toBe(mockSortOptions[0]);
expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.descending);
- expect(wrapper.find(GlButtonGroup).exists()).toBe(true);
- expect(wrapper.find(GlButton).exists()).toBe(true);
- expect(wrapper.find(GlDropdown).exists()).toBe(true);
- expect(wrapper.find(GlDropdownItem).exists()).toBe(true);
+ expect(wrapper.findComponent(GlButtonGroup).exists()).toBe(true);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdown).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdownItem).exists()).toBe(true);
});
it('does not initialize `selectedSortOption` and `selectedSortDirection` when `sortOptions` is not applied and hides the sort dropdown', () => {
@@ -99,10 +99,10 @@ describe('FilteredSearchBarRoot', () => {
expect(wrapperNoSort.vm.filterValue).toEqual([]);
expect(wrapperNoSort.vm.selectedSortOption).toBe(undefined);
- expect(wrapperNoSort.find(GlButtonGroup).exists()).toBe(false);
- expect(wrapperNoSort.find(GlButton).exists()).toBe(false);
- expect(wrapperNoSort.find(GlDropdown).exists()).toBe(false);
- expect(wrapperNoSort.find(GlDropdownItem).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlButtonGroup).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlButton).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlDropdown).exists()).toBe(false);
+ expect(wrapperNoSort.findComponent(GlDropdownItem).exists()).toBe(false);
});
});
@@ -217,7 +217,7 @@ describe('FilteredSearchBarRoot', () => {
it('emits component event `onFilter` with empty array and true when initially selected filter value was cleared', async () => {
wrapper = createComponent({ initialFilterValue: [tokenValueLabel] });
- wrapper.find(GlFilteredSearch).vm.$emit('clear');
+ wrapper.findComponent(GlFilteredSearch).vm.$emit('clear');
await nextTick();
expect(wrapper.emitted('onFilter')[0]).toEqual([[], true]);
@@ -362,7 +362,7 @@ describe('FilteredSearchBarRoot', () => {
it('calls `blurSearchInput` method to remove focus from filter input field', () => {
jest.spyOn(wrapper.vm, 'blurSearchInput');
- wrapper.find(GlFilteredSearch).vm.$emit('submit', mockFilters);
+ wrapper.findComponent(GlFilteredSearch).vm.$emit('submit', mockFilters);
expect(wrapper.vm.blurSearchInput).toHaveBeenCalled();
});
@@ -392,7 +392,7 @@ describe('FilteredSearchBarRoot', () => {
});
it('renders gl-filtered-search component', () => {
- const glFilteredSearchEl = wrapper.find(GlFilteredSearch);
+ const glFilteredSearchEl = wrapper.findComponent(GlFilteredSearch);
expect(glFilteredSearchEl.props('placeholder')).toBe('Filter requirements');
expect(glFilteredSearchEl.props('availableTokens')).toEqual(mockAvailableTokens);
@@ -404,8 +404,10 @@ describe('FilteredSearchBarRoot', () => {
showCheckbox: true,
});
- expect(wrapperWithCheckbox.find(GlFormCheckbox).exists()).toBe(true);
- expect(wrapperWithCheckbox.find(GlFormCheckbox).attributes('checked')).not.toBeDefined();
+ expect(wrapperWithCheckbox.findComponent(GlFormCheckbox).exists()).toBe(true);
+ expect(
+ wrapperWithCheckbox.findComponent(GlFormCheckbox).attributes('checked'),
+ ).not.toBeDefined();
wrapperWithCheckbox.destroy();
@@ -414,7 +416,7 @@ describe('FilteredSearchBarRoot', () => {
checkboxChecked: true,
});
- expect(wrapperWithCheckbox.find(GlFormCheckbox).attributes('checked')).toBe('true');
+ expect(wrapperWithCheckbox.findComponent(GlFormCheckbox).attributes('checked')).toBe('true');
wrapperWithCheckbox.destroy();
});
@@ -448,7 +450,7 @@ describe('FilteredSearchBarRoot', () => {
await nextTick();
- expect(wrapperFullMount.find(GlDropdownItem).text()).toBe('Membership := Direct');
+ expect(wrapperFullMount.findComponent(GlDropdownItem).text()).toBe('Membership := Direct');
wrapperFullMount.destroy();
});
@@ -466,20 +468,20 @@ describe('FilteredSearchBarRoot', () => {
await nextTick();
- expect(wrapperFullMount.find(GlDropdownItem).text()).toBe('Membership := exclude');
+ expect(wrapperFullMount.findComponent(GlDropdownItem).text()).toBe('Membership := exclude');
wrapperFullMount.destroy();
});
});
it('renders sort dropdown component', () => {
- expect(wrapper.find(GlButtonGroup).exists()).toBe(true);
- expect(wrapper.find(GlDropdown).exists()).toBe(true);
- expect(wrapper.find(GlDropdown).props('text')).toBe(mockSortOptions[0].title);
+ expect(wrapper.findComponent(GlButtonGroup).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdown).exists()).toBe(true);
+ expect(wrapper.findComponent(GlDropdown).props('text')).toBe(mockSortOptions[0].title);
});
it('renders sort dropdown items', () => {
- const dropdownItemsEl = wrapper.findAll(GlDropdownItem);
+ const dropdownItemsEl = wrapper.findAllComponents(GlDropdownItem);
expect(dropdownItemsEl).toHaveLength(mockSortOptions.length);
expect(dropdownItemsEl.at(0).text()).toBe(mockSortOptions[0].title);
@@ -488,7 +490,7 @@ describe('FilteredSearchBarRoot', () => {
});
it('renders sort direction button', () => {
- const sortButtonEl = wrapper.find(GlButton);
+ const sortButtonEl = wrapper.findComponent(GlButton);
expect(sortButtonEl.attributes('title')).toBe('Sort direction: Descending');
expect(sortButtonEl.props('icon')).toBe('sort-highest');
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
index 86d1f21fd04..a6713b7e7e4 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
@@ -66,12 +66,14 @@ export const mockMilestones = [
export const mockCrmContacts = [
{
+ __typename: 'CustomerRelationsContact',
id: 'gid://gitlab/CustomerRelations::Contact/1',
firstName: 'John',
lastName: 'Smith',
email: 'john@smith.com',
},
{
+ __typename: 'CustomerRelationsContact',
id: 'gid://gitlab/CustomerRelations::Contact/2',
firstName: 'Andy',
lastName: 'Green',
@@ -81,10 +83,12 @@ export const mockCrmContacts = [
export const mockCrmOrganizations = [
{
+ __typename: 'CustomerRelationsOrganization',
id: 'gid://gitlab/CustomerRelations::Organization/1',
name: 'First Org Ltd.',
},
{
+ __typename: 'CustomerRelationsOrganization',
id: 'gid://gitlab/CustomerRelations::Organization/2',
name: 'Organizer S.p.a.',
},
@@ -102,11 +106,9 @@ export const mockProjectCrmContactsQueryResponse = {
__typename: 'CustomerRelationsContactConnection',
nodes: [
{
- __typename: 'CustomerRelationsContact',
...mockCrmContacts[0],
},
{
- __typename: 'CustomerRelationsContact',
...mockCrmContacts[1],
},
],
@@ -128,11 +130,9 @@ export const mockProjectCrmOrganizationsQueryResponse = {
__typename: 'CustomerRelationsOrganizationConnection',
nodes: [
{
- __typename: 'CustomerRelationsOrganization',
...mockCrmOrganizations[0],
},
{
- __typename: 'CustomerRelationsOrganization',
...mockCrmOrganizations[1],
},
],
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
index 3f24d5df858..302dfabffb2 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
@@ -195,7 +195,7 @@ describe('AuthorToken', () => {
});
await nextTick();
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Author, =, "Administrator"
@@ -207,7 +207,7 @@ describe('AuthorToken', () => {
it('renders token value with correct avatarUrl from author object', async () => {
const getAvatarEl = () =>
- wrapper.findAll(GlFilteredSearchTokenSegment).at(2).findComponent(GlAvatar);
+ wrapper.findAllComponents(GlFilteredSearchTokenSegment).at(2).findComponent(GlAvatar);
wrapper = createComponent({
value: { data: mockAuthors[0].username },
@@ -252,7 +252,7 @@ describe('AuthorToken', () => {
await activateSuggestionsList();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultAuthors.length + currentUserLength);
defaultAuthors.forEach((label, index) => {
@@ -266,12 +266,12 @@ describe('AuthorToken', () => {
config: { ...mockAuthorToken, defaultAuthors: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', async () => {
@@ -283,7 +283,7 @@ describe('AuthorToken', () => {
await activateSuggestionsList();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(2 + currentUserLength);
expect(suggestions.at(0).text()).toBe(DEFAULT_NONE_ANY[0].text);
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
index 7b495ec9bee..1de35daa3a5 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/branch_token_spec.js
@@ -114,7 +114,7 @@ describe('BranchToken', () => {
describe('template', () => {
const defaultBranches = DEFAULT_NONE_ANY;
async function showSuggestions() {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
@@ -133,11 +133,11 @@ describe('BranchToken', () => {
});
it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFilteredSearchToken).exists()).toBe(true);
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3);
expect(tokenSegments.at(2).text()).toBe(mockBranches[0].name);
@@ -150,7 +150,7 @@ describe('BranchToken', () => {
stubs: { Portal: true },
});
await showSuggestions();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultBranches.length);
defaultBranches.forEach((branch, index) => {
@@ -166,8 +166,8 @@ describe('BranchToken', () => {
});
await showSuggestions();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders no suggestions as default', async () => {
@@ -177,7 +177,7 @@ describe('BranchToken', () => {
stubs: { Portal: true },
});
await showSuggestions();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(0);
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js
index 157e021fc60..c9879987931 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_contact_token_spec.js
@@ -195,7 +195,7 @@ describe('CrmContactToken', () => {
value: { data: '1' },
});
- const baseTokenEl = wrapper.find(BaseToken);
+ const baseTokenEl = wrapper.findComponent(BaseToken);
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
@@ -210,7 +210,7 @@ describe('CrmContactToken', () => {
value: { data: `${getIdFromGraphQLId(contact.id)}` },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Contact, =, Contact name
expect(tokenSegments.at(2).text()).toBe(`${contact.firstName} ${contact.lastName}`); // Contact name
@@ -222,12 +222,12 @@ describe('CrmContactToken', () => {
config: { ...mockCrmContactToken, defaultContacts },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultContacts.length);
defaultContacts.forEach((contact, index) => {
@@ -241,13 +241,13 @@ describe('CrmContactToken', () => {
config: { ...mockCrmContactToken, defaultContacts: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
@@ -256,11 +256,11 @@ describe('CrmContactToken', () => {
config: { ...mockCrmContactToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
DEFAULT_NONE_ANY.forEach((contact, index) => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js
index 977f8bbef61..16333b052e6 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/crm_organization_token_spec.js
@@ -194,7 +194,7 @@ describe('CrmOrganizationToken', () => {
value: { data: '1' },
});
- const baseTokenEl = wrapper.find(BaseToken);
+ const baseTokenEl = wrapper.findComponent(BaseToken);
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
@@ -209,7 +209,7 @@ describe('CrmOrganizationToken', () => {
value: { data: `${getIdFromGraphQLId(organization.id)}` },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Organization, =, Organization name
expect(tokenSegments.at(2).text()).toBe(organization.name); // Organization name
@@ -221,12 +221,12 @@ describe('CrmOrganizationToken', () => {
config: { ...mockCrmOrganizationToken, defaultOrganizations },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultOrganizations.length);
defaultOrganizations.forEach((organization, index) => {
@@ -240,13 +240,13 @@ describe('CrmOrganizationToken', () => {
config: { ...mockCrmOrganizationToken, defaultOrganizations: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
@@ -255,11 +255,11 @@ describe('CrmOrganizationToken', () => {
config: { ...mockCrmOrganizationToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
DEFAULT_NONE_ANY.forEach((organization, index) => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
index dcb0d095b1b..bf4a6eb7635 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/emoji_token_spec.js
@@ -135,14 +135,16 @@ describe('EmojiToken', () => {
});
it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFilteredSearchToken).exists()).toBe(true);
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // My Reaction, =, "thumbsup"
- expect(tokenSegments.at(2).find(GlEmoji).attributes('data-name')).toEqual('thumbsup');
+ expect(tokenSegments.at(2).findComponent(GlEmoji).attributes('data-name')).toEqual(
+ 'thumbsup',
+ );
});
it('renders provided defaultEmojis as suggestions', async () => {
@@ -151,12 +153,12 @@ describe('EmojiToken', () => {
config: { ...mockReactionEmojiToken, defaultEmojis },
stubs: { Portal: true, GlEmoji },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultEmojis.length);
defaultEmojis.forEach((emoji, index) => {
@@ -170,13 +172,13 @@ describe('EmojiToken', () => {
config: { ...mockReactionEmojiToken, defaultEmojis: [] },
stubs: { Portal: true, GlEmoji },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_LABEL_NONE` and `DEFAULT_LABEL_ANY` as default suggestions', async () => {
@@ -185,12 +187,12 @@ describe('EmojiToken', () => {
config: { ...mockReactionEmojiToken },
stubs: { Portal: true, GlEmoji },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(2);
expect(suggestions.at(0).text()).toBe(DEFAULT_LABEL_NONE.text);
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
index 51161a1a0ef..01e281884ed 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
@@ -156,7 +156,7 @@ describe('LabelToken', () => {
});
it('renders base-token component', () => {
- const baseTokenEl = wrapper.find(BaseToken);
+ const baseTokenEl = wrapper.findComponent(BaseToken);
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
@@ -166,7 +166,7 @@ describe('LabelToken', () => {
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Label, =, "Foo Label"
expect(tokenSegments.at(2).text()).toBe(`~${mockRegularLabel.title}`); // "Foo Label"
@@ -181,12 +181,12 @@ describe('LabelToken', () => {
config: { ...mockLabelToken, defaultLabels },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultLabels.length);
defaultLabels.forEach((label, index) => {
@@ -200,13 +200,13 @@ describe('LabelToken', () => {
config: { ...mockLabelToken, defaultLabels: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_NONE_ANY` as default suggestions', () => {
@@ -215,11 +215,11 @@ describe('LabelToken', () => {
config: { ...mockLabelToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_NONE_ANY.length);
DEFAULT_NONE_ANY.forEach((label, index) => {
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
index 7c545f76c0b..f71ba51fc5b 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/milestone_token_spec.js
@@ -155,11 +155,11 @@ describe('MilestoneToken', () => {
});
it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFilteredSearchToken).exists()).toBe(true);
});
it('renders token item when value is selected', () => {
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Milestone, =, '%"4.0"'
expect(tokenSegments.at(2).text()).toBe(`%${mockRegularMilestone.title}`); // "4.0 RC1"
@@ -171,12 +171,12 @@ describe('MilestoneToken', () => {
config: { ...mockMilestoneToken, defaultMilestones },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(defaultMilestones.length);
defaultMilestones.forEach((milestone, index) => {
@@ -190,13 +190,13 @@ describe('MilestoneToken', () => {
config: { ...mockMilestoneToken, defaultMilestones: [] },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
- expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
+ expect(wrapper.findComponent(GlFilteredSearchSuggestion).exists()).toBe(false);
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_MILESTONES` as default suggestions', async () => {
@@ -205,12 +205,12 @@ describe('MilestoneToken', () => {
config: { ...mockMilestoneToken },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
const suggestionsSegment = tokenSegments.at(2);
suggestionsSegment.vm.$emit('activate');
await nextTick();
- const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
+ const suggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion);
expect(suggestions).toHaveLength(DEFAULT_MILESTONES.length);
DEFAULT_MILESTONES.forEach((milestone, index) => {
diff --git a/spec/frontend/vue_shared/components/gitlab_version_check_spec.js b/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
index b180e8c12dd..6699ae5fb69 100644
--- a/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
+++ b/spec/frontend/vue_shared/components/gitlab_version_check_spec.js
@@ -26,13 +26,44 @@ describe('GitlabVersionCheck', () => {
wrapper = shallowMount(GitlabVersionCheck);
};
+ const dummyGon = {
+ relative_url_root: '/',
+ };
+
+ let originalGon;
+
afterEach(() => {
wrapper.destroy();
mock.restore();
+ window.gon = originalGon;
});
const findGlBadge = () => wrapper.findComponent(GlBadge);
+ describe.each`
+ root | description
+ ${'/'} | ${'not used (uses its own (sub)domain)'}
+ ${'/gitlab'} | ${'custom path'}
+ ${'/service/gitlab'} | ${'custom path with 2 depth'}
+ `('path for version_check.json', ({ root, description }) => {
+ describe(`when relative url is ${description}: ${root}`, () => {
+ beforeEach(async () => {
+ originalGon = window.gon;
+ window.gon = { ...dummyGon };
+ window.gon.relative_url_root = root;
+ createComponent(defaultResponse);
+ await waitForPromises(); // Ensure we wrap up the axios call
+ });
+
+ it('reflects the relative url setting', () => {
+ expect(mock.history.get.length).toBe(1);
+
+ const pathRegex = new RegExp(`^${root}`);
+ expect(mock.history.get[0].url).toMatch(pathRegex);
+ });
+ });
+ });
+
describe('template', () => {
describe.each`
description | mockResponse | renders
diff --git a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
index c0a6588833e..2dcd91f737f 100644
--- a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
+++ b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
@@ -59,7 +59,7 @@ describe('GlModalVuex', () => {
default: `<div>${TEST_SLOT}</div>`,
},
});
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
expect(glModal.props('modalId')).toBe(TEST_MODAL_ID);
expect(glModal.text()).toContain(TEST_SLOT);
@@ -76,7 +76,7 @@ describe('GlModalVuex', () => {
okVariant,
},
});
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
expect(glModal.attributes('title')).toEqual(title);
expect(glModal.attributes('oktitle')).toEqual(title);
@@ -90,7 +90,7 @@ describe('GlModalVuex', () => {
listeners: { ok },
});
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
glModal.vm.$emit('ok');
expect(ok).toHaveBeenCalledTimes(1);
@@ -101,7 +101,7 @@ describe('GlModalVuex', () => {
factory();
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
glModal.vm.$emit('shown');
expect(actions.show).toHaveBeenCalledTimes(1);
@@ -112,7 +112,7 @@ describe('GlModalVuex', () => {
factory();
- const glModal = wrapper.find(GlModal);
+ const glModal = wrapper.findComponent(GlModal);
glModal.vm.$emit('hidden');
expect(actions.hide).toHaveBeenCalledTimes(1);
diff --git a/spec/frontend/vue_shared/components/help_popover_spec.js b/spec/frontend/vue_shared/components/help_popover_spec.js
index 64dce194327..6fd5ae0e946 100644
--- a/spec/frontend/vue_shared/components/help_popover_spec.js
+++ b/spec/frontend/vue_shared/components/help_popover_spec.js
@@ -7,8 +7,8 @@ describe('HelpPopover', () => {
const title = 'popover <strong>title</strong>';
const content = 'popover <b>content</b>';
- const findQuestionButton = () => wrapper.find(GlButton);
- const findPopover = () => wrapper.find(GlPopover);
+ const findQuestionButton = () => wrapper.findComponent(GlButton);
+ const findPopover = () => wrapper.findComponent(GlPopover);
const createComponent = ({ props, ...opts } = {}) => {
wrapper = mount(HelpPopover, {
diff --git a/spec/frontend/vue_shared/components/integration_help_text_spec.js b/spec/frontend/vue_shared/components/integration_help_text_spec.js
index c0e8b719007..c63e46313b3 100644
--- a/spec/frontend/vue_shared/components/integration_help_text_spec.js
+++ b/spec/frontend/vue_shared/components/integration_help_text_spec.js
@@ -30,9 +30,9 @@ describe('IntegrationHelpText component', () => {
it('should use the gl components', () => {
wrapper = createComponent();
- expect(wrapper.find(GlSprintf).exists()).toBe(true);
- expect(wrapper.find(GlIcon).exists()).toBe(true);
- expect(wrapper.find(GlLink).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSprintf).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLink).exists()).toBe(true);
});
it('should render the help text', () => {
@@ -44,9 +44,9 @@ describe('IntegrationHelpText component', () => {
it('should not use the gl-link and gl-icon components', () => {
wrapper = createComponent({ message: 'Click nowhere!' });
- expect(wrapper.find(GlSprintf).exists()).toBe(true);
- expect(wrapper.find(GlIcon).exists()).toBe(false);
- expect(wrapper.find(GlLink).exists()).toBe(false);
+ expect(wrapper.findComponent(GlSprintf).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(false);
+ expect(wrapper.findComponent(GlLink).exists()).toBe(false);
});
it('should not render the link when start and end is not provided', () => {
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index 85a135d2b89..50864a4bf25 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -76,7 +76,7 @@ describe('Markdown field component', () => {
const getMarkdownButton = () => subject.find('.js-md');
const getListBulletedButton = () => subject.findAll('.js-md[title="Add a bullet list"]');
const getVideo = () => subject.find('video');
- const getAttachButton = () => subject.find('.button-attach-file');
+ const getAttachButton = () => subject.findByTestId('button-attach-file');
const clickAttachButton = () => getAttachButton().trigger('click');
const findDropzone = () => subject.find('.div-dropzone');
const findMarkdownHeader = () => subject.findComponent(MarkdownFieldHeader);
@@ -232,13 +232,10 @@ describe('Markdown field component', () => {
});
});
- it('should render attach a file button', () => {
- expect(getAttachButton().text()).toBe('Attach a file');
- });
-
it('should trigger dropzone when attach button is clicked', () => {
expect(dropzoneSpy).not.toHaveBeenCalled();
+ getAttachButton().trigger('click');
clickAttachButton();
expect(dropzoneSpy).toHaveBeenCalled();
diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js
index 67222cab247..9831908f806 100644
--- a/spec/frontend/vue_shared/components/markdown/header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/header_spec.js
@@ -21,7 +21,7 @@ describe('Markdown field header component', () => {
const findWriteTab = () => wrapper.findByTestId('write-tab');
const findPreviewTab = () => wrapper.findByTestId('preview-tab');
const findToolbar = () => wrapper.findByTestId('md-header-toolbar');
- const findToolbarButtons = () => wrapper.findAll(ToolbarButton);
+ const findToolbarButtons = () => wrapper.findAllComponents(ToolbarButton);
const findToolbarButtonByProp = (prop, value) =>
findToolbarButtons()
.filter((button) => button.props(prop) === value)
@@ -44,16 +44,16 @@ describe('Markdown field header component', () => {
describe('markdown header buttons', () => {
it('renders the buttons with the correct title', () => {
const buttons = [
+ 'Insert suggestion',
'Add bold text (⌘B)',
'Add italic text (⌘I)',
'Add strikethrough text (⌘⇧X)',
'Insert a quote',
- 'Insert suggestion',
'Insert code',
'Add a link (⌘K)',
'Add a bullet list',
'Add a numbered list',
- 'Add a task list',
+ 'Add a checklist',
'Add a collapsible section',
'Add a table',
'Go full screen',
@@ -65,6 +65,13 @@ describe('Markdown field header component', () => {
});
});
+ it('renders "Attach a file or image" button using gl-button', () => {
+ const button = wrapper.findByTestId('button-attach-file');
+
+ expect(button.element.tagName).toBe('GL-BUTTON-STUB');
+ expect(button.attributes('title')).toBe('Attach a file or image');
+ });
+
describe('when the user is on a non-Mac', () => {
beforeEach(() => {
delete window.gl.client.isMac;
@@ -118,8 +125,8 @@ describe('Markdown field header component', () => {
),
]);
- expect(wrapper.emitted('preview-markdown')).toBeFalsy();
- expect(wrapper.emitted('write-markdown')).toBeFalsy();
+ expect(wrapper.emitted('preview-markdown')).toBeUndefined();
+ expect(wrapper.emitted('write-markdown')).toBeUndefined();
});
it('blurs preview link after click', () => {
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
index 9944267cf24..9db1b779a04 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_header_spec.js
@@ -38,13 +38,13 @@ describe('Suggestion Diff component', () => {
wrapper.destroy();
});
- const findApplyButton = () => wrapper.find(ApplySuggestion);
+ const findApplyButton = () => wrapper.findComponent(ApplySuggestion);
const findApplyBatchButton = () => wrapper.find('.js-apply-batch-btn');
const findAddToBatchButton = () => wrapper.find('.js-add-to-batch-btn');
const findRemoveFromBatchButton = () => wrapper.find('.js-remove-from-batch-btn');
const findHeader = () => wrapper.find('.js-suggestion-diff-header');
const findHelpButton = () => wrapper.find('.js-help-btn');
- const findLoading = () => wrapper.find(GlLoadingIcon);
+ const findLoading = () => wrapper.findComponent(GlLoadingIcon);
it('renders a suggestion header', () => {
createComponent();
diff --git a/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
index af27e953776..d84483c1663 100644
--- a/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
@@ -71,7 +71,7 @@ describe('Suggestion Diff component', () => {
});
it('renders a correct amount of suggestion diff rows', () => {
- expect(wrapper.findAll(SuggestionDiffRow)).toHaveLength(3);
+ expect(wrapper.findAllComponents(SuggestionDiffRow)).toHaveLength(3);
});
it.each`
@@ -81,14 +81,14 @@ describe('Suggestion Diff component', () => {
${'addToBatch'} | ${[]} | ${[suggestionId]}
${'removeFromBatch'} | ${[]} | ${[suggestionId]}
`('emits $event event on sugestion diff header $event', ({ event, childArgs, args }) => {
- wrapper.find(SuggestionDiffHeader).vm.$emit(event, ...childArgs);
+ wrapper.findComponent(SuggestionDiffHeader).vm.$emit(event, ...childArgs);
expect(wrapper.emitted(event)).toBeDefined();
expect(wrapper.emitted(event)).toEqual([args]);
});
it('passes suggestion batch props to suggestion diff header', () => {
- expect(wrapper.find(SuggestionDiffHeader).props()).toMatchObject({
+ expect(wrapper.findComponent(SuggestionDiffHeader).props()).toMatchObject({
batchSuggestionsCount: 1,
isBatched: true,
isApplyingBatch: MOCK_DATA.suggestion.is_applying_batch,
diff --git a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
index 19e4f2d8c92..82210e79799 100644
--- a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
@@ -26,7 +26,7 @@ describe('toolbar_button', () => {
});
const getButtonShortcutsAttr = () => {
- return wrapper.find(GlButton).attributes('data-md-shortcuts');
+ return wrapper.findComponent(GlButton).attributes('data-md-shortcuts');
};
describe('keyboard shortcuts', () => {
diff --git a/spec/frontend/vue_shared/components/memory_graph_spec.js b/spec/frontend/vue_shared/components/memory_graph_spec.js
index 53b96bd1b98..ae8d5ff78ba 100644
--- a/spec/frontend/vue_shared/components/memory_graph_spec.js
+++ b/spec/frontend/vue_shared/components/memory_graph_spec.js
@@ -47,7 +47,7 @@ describe('MemoryGraph', () => {
it('should draw container with chart', () => {
expect(wrapper.element).toMatchSnapshot();
expect(wrapper.find('.memory-graph-container').exists()).toBe(true);
- expect(wrapper.find(GlSparklineChart).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSparklineChart).exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js b/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
index 2cefa77b72d..1789610dba9 100644
--- a/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
+++ b/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
@@ -114,7 +114,7 @@ describe('Metric images tab', () => {
await waitForPromises();
- expect(findModal().attributes('visible')).toBeFalsy();
+ expect(findModal().attributes('visible')).toBeUndefined();
});
it('should add files and url when selected', async () => {
diff --git a/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js b/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js
index c11b20a692e..2c14d65186b 100644
--- a/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js
+++ b/spec/frontend/vue_shared/components/namespace_select/namespace_select_spec.js
@@ -1,5 +1,12 @@
import { nextTick } from 'vue';
-import { GlDropdown, GlDropdownItem, GlDropdownSectionHeader, GlSearchBoxByType } from '@gitlab/ui';
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownSectionHeader,
+ GlSearchBoxByType,
+ GlIntersectionObserver,
+ GlLoadingIcon,
+} from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NamespaceSelect, {
i18n,
@@ -7,7 +14,7 @@ import NamespaceSelect, {
} from '~/vue_shared/components/namespace_select/namespace_select.vue';
import { userNamespaces, groupNamespaces } from './mock_data';
-const FLAT_NAMESPACES = [...groupNamespaces, ...userNamespaces];
+const FLAT_NAMESPACES = [...userNamespaces, ...groupNamespaces];
const EMPTY_NAMESPACE_TITLE = 'Empty namespace TEST';
const EMPTY_NAMESPACE_ITEM = { id: EMPTY_NAMESPACE_ID, humanName: EMPTY_NAMESPACE_TITLE };
@@ -31,6 +38,8 @@ describe('Namespace Select', () => {
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownText = () => findDropdown().props('text');
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findGroupDropdownItems = () =>
+ wrapper.findByTestId('namespace-list-groups').findAllComponents(GlDropdownItem);
const findDropdownItemsTexts = () => findDropdownItems().wrappers.map((x) => x.text());
const findSectionHeaders = () => wrapper.findAllComponents(GlDropdownSectionHeader);
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
@@ -59,7 +68,7 @@ describe('Namespace Select', () => {
it('splits group and user namespaces', () => {
const headers = findSectionHeaders();
- expect(wrappersText(headers)).toEqual([i18n.GROUPS, i18n.USERS]);
+ expect(wrappersText(headers)).toEqual([i18n.USERS, i18n.GROUPS]);
});
it('does not render wrapper as full width', () => {
@@ -89,18 +98,20 @@ describe('Namespace Select', () => {
describe('with search', () => {
it.each`
- term | includeEmptyNamespace | expectedItems
- ${''} | ${false} | ${[...groupNamespaces, ...userNamespaces]}
- ${'sub'} | ${false} | ${[groupNamespaces[1]]}
- ${'User'} | ${false} | ${[...userNamespaces]}
- ${'User'} | ${true} | ${[...userNamespaces]}
- ${'namespace'} | ${true} | ${[EMPTY_NAMESPACE_ITEM, ...userNamespaces]}
+ term | includeEmptyNamespace | shouldFilterNamespaces | expectedItems
+ ${''} | ${false} | ${true} | ${[...userNamespaces, ...groupNamespaces]}
+ ${'sub'} | ${false} | ${true} | ${[groupNamespaces[1]]}
+ ${'User'} | ${false} | ${true} | ${[...userNamespaces]}
+ ${'User'} | ${true} | ${true} | ${[...userNamespaces]}
+ ${'namespace'} | ${true} | ${true} | ${[EMPTY_NAMESPACE_ITEM, ...userNamespaces]}
+ ${'sub'} | ${false} | ${false} | ${[...userNamespaces, ...groupNamespaces]}
`(
- 'with term=$term and includeEmptyNamespace=$includeEmptyNamespace, should show $expectedItems.length',
- async ({ term, includeEmptyNamespace, expectedItems }) => {
+ 'with term=$term, includeEmptyNamespace=$includeEmptyNamespace, and shouldFilterNamespaces=$shouldFilterNamespaces should show $expectedItems.length',
+ async ({ term, includeEmptyNamespace, shouldFilterNamespaces, expectedItems }) => {
wrapper = createComponent({
includeEmptyNamespace,
emptyNamespaceTitle: EMPTY_NAMESPACE_TITLE,
+ shouldFilterNamespaces,
});
search(term);
@@ -114,6 +125,18 @@ describe('Namespace Select', () => {
);
});
+ describe('when search is typed in', () => {
+ it('emits `search` event', async () => {
+ wrapper = createComponent();
+
+ wrapper.findComponent(GlSearchBoxByType).vm.$emit('input', 'foo');
+
+ await nextTick();
+
+ expect(wrapper.emitted('search')).toEqual([['foo']]);
+ });
+ });
+
describe('with a selected namespace', () => {
const selectedGroupIndex = 1;
const selectedItem = groupNamespaces[selectedGroupIndex];
@@ -121,7 +144,8 @@ describe('Namespace Select', () => {
beforeEach(() => {
wrapper = createComponent();
- findDropdownItems().at(selectedGroupIndex).vm.$emit('click');
+ wrapper.findComponent(GlSearchBoxByType).vm.$emit('input', 'foo');
+ findGroupDropdownItems().at(selectedGroupIndex).vm.$emit('click');
});
it('sets the dropdown text', () => {
@@ -132,6 +156,10 @@ describe('Namespace Select', () => {
const args = [selectedItem];
expect(wrapper.emitted('select')).toEqual([args]);
});
+
+ it('clears search', () => {
+ expect(wrapper.findComponent(GlSearchBoxByType).props('value')).toBe('');
+ });
});
describe('with an empty namespace option', () => {
@@ -166,4 +194,33 @@ describe('Namespace Select', () => {
expect(findDropdownItemsTexts().includes(EMPTY_NAMESPACE_TITLE)).toBe(shouldShow);
});
});
+
+ describe('when `hasNextPageOfGroups` prop is `true`', () => {
+ it('renders `GlIntersectionObserver` and emits `load-more-groups` event when bottom is reached', () => {
+ wrapper = createComponent({ hasNextPageOfGroups: true });
+
+ const intersectionObserver = wrapper.findComponent(GlIntersectionObserver);
+
+ intersectionObserver.vm.$emit('appear');
+
+ expect(intersectionObserver.exists()).toBe(true);
+ expect(wrapper.emitted('load-more-groups')).toEqual([[]]);
+ });
+
+ describe('when `isLoadingMoreGroups` prop is `true`', () => {
+ it('renders a loading icon', () => {
+ wrapper = createComponent({ hasNextPageOfGroups: true, isLoadingMoreGroups: true });
+
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
+ });
+ });
+ });
+
+ describe('when `isSearchLoading` prop is `true`', () => {
+ it('sets `isLoading` prop to `true`', () => {
+ wrapper = createComponent({ isSearchLoading: true });
+
+ expect(wrapper.findComponent(GlSearchBoxByType).props('isLoading')).toBe(true);
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/navigation_tabs_spec.js b/spec/frontend/vue_shared/components/navigation_tabs_spec.js
index 30a89fed12f..b1bec28bffb 100644
--- a/spec/frontend/vue_shared/components/navigation_tabs_spec.js
+++ b/spec/frontend/vue_shared/components/navigation_tabs_spec.js
@@ -44,7 +44,7 @@ describe('navigation tabs component', () => {
});
it('should render tabs', () => {
- expect(wrapper.findAll(GlTab)).toHaveLength(data.length);
+ expect(wrapper.findAllComponents(GlTab)).toHaveLength(data.length);
});
it('should render active tab', () => {
diff --git a/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js b/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
index 99b65ca6937..17a62ae8a33 100644
--- a/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
+++ b/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
@@ -6,10 +6,11 @@ import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue'
describe('Issue Warning Component', () => {
let wrapper;
- const findIcon = (w = wrapper) => w.find(GlIcon);
- const findLockedBlock = (w = wrapper) => w.find({ ref: 'locked' });
- const findConfidentialBlock = (w = wrapper) => w.find({ ref: 'confidential' });
- const findLockedAndConfidentialBlock = (w = wrapper) => w.find({ ref: 'lockedAndConfidential' });
+ const findIcon = (w = wrapper) => w.findComponent(GlIcon);
+ const findLockedBlock = (w = wrapper) => w.findComponent({ ref: 'locked' });
+ const findConfidentialBlock = (w = wrapper) => w.findComponent({ ref: 'confidential' });
+ const findLockedAndConfidentialBlock = (w = wrapper) =>
+ w.findComponent({ ref: 'lockedAndConfidential' });
const createComponent = (props) =>
shallowMount(NoteableWarning, {
@@ -73,7 +74,7 @@ describe('Issue Warning Component', () => {
});
it('renders warning icon', () => {
- expect(wrapper.find(GlIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(true);
});
it('does not render information about locked noteable', () => {
@@ -99,7 +100,7 @@ describe('Issue Warning Component', () => {
});
it('does not render warning icon', () => {
- expect(wrapper.find(GlIcon).exists()).toBe(false);
+ expect(wrapper.findComponent(GlIcon).exists()).toBe(false);
});
it('does not render information about locked noteable', () => {
diff --git a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
index f951cfd5cd9..b86c8946e96 100644
--- a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
+++ b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
@@ -14,7 +14,7 @@ const getters = {
describe('Issue placeholder note component', () => {
let wrapper;
- const findNote = () => wrapper.find({ ref: 'note' });
+ const findNote = () => wrapper.findComponent({ ref: 'note' });
const createComponent = (isIndividual = false, propsData = {}) => {
wrapper = shallowMount(IssuePlaceholderNote, {
diff --git a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
index 51a936c0509..c0c3c4a9729 100644
--- a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
+++ b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
@@ -92,15 +92,15 @@ describe('AlertManagementEmptyState', () => {
const EmptyState = () => wrapper.find('.empty-state');
const ItemsTable = () => wrapper.find('.gl-table');
- const ErrorAlert = () => wrapper.find(GlAlert);
- const Pagination = () => wrapper.find(GlPagination);
- const Tabs = () => wrapper.find(GlTabs);
+ const ErrorAlert = () => wrapper.findComponent(GlAlert);
+ const Pagination = () => wrapper.findComponent(GlPagination);
+ const Tabs = () => wrapper.findComponent(GlTabs);
const ActionButton = () => wrapper.find('.header-actions > button');
- const Filters = () => wrapper.find(FilteredSearchBar);
- const findPagination = () => wrapper.find(GlPagination);
- const findStatusFilterTabs = () => wrapper.findAll(GlTab);
- const findStatusTabs = () => wrapper.find(GlTabs);
- const findStatusFilterBadge = () => wrapper.findAll(GlBadge);
+ const Filters = () => wrapper.findComponent(FilteredSearchBar);
+ const findPagination = () => wrapper.findComponent(GlPagination);
+ const findStatusFilterTabs = () => wrapper.findAllComponents(GlTab);
+ const findStatusTabs = () => wrapper.findComponent(GlTabs);
+ const findStatusFilterBadge = () => wrapper.findAllComponents(GlBadge);
describe('Snowplow tracking', () => {
beforeEach(() => {
@@ -213,7 +213,7 @@ describe('AlertManagementEmptyState', () => {
});
it('should render pagination', () => {
- expect(wrapper.find(GlPagination).exists()).toBe(true);
+ expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
describe('prevPage', () => {
diff --git a/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js b/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js
index 08119dee8af..b3be2f8a775 100644
--- a/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js
+++ b/spec/frontend/vue_shared/components/pagination_bar/pagination_bar_spec.js
@@ -64,7 +64,7 @@ describe('Pagination bar', () => {
},
});
- expect(wrapper.find(GlDropdown).find('button').text()).toMatchInterpolatedText(
+ expect(wrapper.findComponent(GlDropdown).find('button').text()).toMatchInterpolatedText(
`${CURRENT_PAGE_SIZE} items per page`,
);
});
diff --git a/spec/frontend/vue_shared/components/pagination_links_spec.js b/spec/frontend/vue_shared/components/pagination_links_spec.js
index 83f1e2844f9..d444ad7a733 100644
--- a/spec/frontend/vue_shared/components/pagination_links_spec.js
+++ b/spec/frontend/vue_shared/components/pagination_links_spec.js
@@ -41,7 +41,7 @@ describe('Pagination links component', () => {
beforeEach(() => {
createComponent();
- glPagination = wrapper.find(GlPagination);
+ glPagination = wrapper.findComponent(GlPagination);
});
afterEach(() => {
diff --git a/spec/frontend/vue_shared/components/project_avatar_spec.js b/spec/frontend/vue_shared/components/project_avatar_spec.js
index d55f3127a74..af828fbca51 100644
--- a/spec/frontend/vue_shared/components/project_avatar_spec.js
+++ b/spec/frontend/vue_shared/components/project_avatar_spec.js
@@ -42,6 +42,42 @@ describe('ProjectAvatar', () => {
});
});
+ describe('with `projectId` prop', () => {
+ const validatorFunc = ProjectAvatar.props.projectId.validator;
+
+ it('prop validators return true for valid types', () => {
+ expect(validatorFunc(1)).toBe(true);
+ expect(validatorFunc('gid://gitlab/Project/1')).toBe(true);
+ });
+
+ it('prop validators return false for invalid types', () => {
+ expect(validatorFunc('1')).toBe(false);
+ });
+
+ it('renders GlAvatar with `entityId` 0 when `projectId` is not informed', () => {
+ createComponent({ props: { projectId: undefined } });
+
+ const avatar = findGlAvatar();
+ expect(avatar.props('entityId')).toBe(0);
+ });
+
+ it('renders GlAvatar with specified `entityId` when `projectId` is a Number', () => {
+ const mockProjectId = 1;
+ createComponent({ props: { projectId: mockProjectId } });
+
+ const avatar = findGlAvatar();
+ expect(avatar.props('entityId')).toBe(mockProjectId);
+ });
+
+ it('renders GlAvatar with specified `entityId` when `projectId` is a gid String', () => {
+ const mockProjectId = 'gid://gitlab/Project/1';
+ createComponent({ props: { projectId: mockProjectId } });
+
+ const avatar = findGlAvatar();
+ expect(avatar.props('entityId')).toBe(1);
+ });
+ });
+
describe('with `projectAvatarUrl` prop', () => {
it('renders GlAvatar with specified `src` prop', () => {
const mockProjectAvatarUrl = 'https://gitlab.com';
diff --git a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js
index 397ab2254b9..4e0c318c84e 100644
--- a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js
+++ b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js
@@ -56,6 +56,7 @@ describe('ProjectListItem component', () => {
expect(avatar.exists()).toBe(true);
expect(avatar.props()).toMatchObject({
+ projectId: project.id,
projectAvatarUrl: '',
projectName: project.name_with_namespace,
});
diff --git a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
index 379e60c1b2d..a0832dd7030 100644
--- a/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
+++ b/spec/frontend/vue_shared/components/project_selector/project_selector_spec.js
@@ -15,7 +15,7 @@ describe('ProjectSelector component', () => {
let selected = [];
selected = selected.concat(allProjects.slice(0, 3)).concat(allProjects.slice(5, 8));
- const findSearchInput = () => wrapper.find(GlSearchBoxByType).find('input');
+ const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType).find('input');
const findLegendText = () => wrapper.find('[data-testid="legend-text"]').text();
const search = (query) => {
const searchInput = findSearchInput();
@@ -65,14 +65,14 @@ describe('ProjectSelector component', () => {
it(`triggers a "bottomReached" event when user has scrolled to the bottom of the list`, () => {
jest.spyOn(vm, '$emit').mockImplementation(() => {});
- wrapper.find(GlInfiniteScroll).vm.$emit('bottomReached');
+ wrapper.findComponent(GlInfiniteScroll).vm.$emit('bottomReached');
expect(vm.$emit).toHaveBeenCalledWith('bottomReached');
});
it(`triggers a "projectClicked" event when a project is clicked`, () => {
jest.spyOn(vm, '$emit').mockImplementation(() => {});
- wrapper.find(ProjectListItem).vm.$emit('click', head(searchResults));
+ wrapper.findComponent(ProjectListItem).vm.$emit('click', head(searchResults));
expect(vm.$emit).toHaveBeenCalledWith('projectClicked', head(searchResults));
});
diff --git a/spec/frontend/vue_shared/components/registry/code_instruction_spec.js b/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
index 3a2ea263a05..8f19f0ea14d 100644
--- a/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
+++ b/spec/frontend/vue_shared/components/registry/code_instruction_spec.js
@@ -22,7 +22,7 @@ describe('Package code instruction', () => {
});
}
- const findCopyButton = () => wrapper.find(ClipboardButton);
+ const findCopyButton = () => wrapper.findComponent(ClipboardButton);
const findInputElement = () => wrapper.find('[data-testid="instruction-input"]');
const findMultilineInstruction = () => wrapper.find('[data-testid="multiline-instruction"]');
diff --git a/spec/frontend/vue_shared/components/registry/details_row_spec.js b/spec/frontend/vue_shared/components/registry/details_row_spec.js
index 3134e0d3e21..ebc9816f983 100644
--- a/spec/frontend/vue_shared/components/registry/details_row_spec.js
+++ b/spec/frontend/vue_shared/components/registry/details_row_spec.js
@@ -5,7 +5,7 @@ import component from '~/vue_shared/components/registry/details_row.vue';
describe('DetailsRow', () => {
let wrapper;
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
const mountComponent = (props) => {
diff --git a/spec/frontend/vue_shared/components/registry/history_item_spec.js b/spec/frontend/vue_shared/components/registry/history_item_spec.js
index f146f87342f..947520567e6 100644
--- a/spec/frontend/vue_shared/components/registry/history_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/history_item_spec.js
@@ -27,8 +27,8 @@ describe('History Item', () => {
wrapper = null;
});
- const findTimelineEntry = () => wrapper.find(TimelineEntryItem);
- const findGlIcon = () => wrapper.find(GlIcon);
+ const findTimelineEntry = () => wrapper.findComponent(TimelineEntryItem);
+ const findGlIcon = () => wrapper.findComponent(GlIcon);
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
const findBodySlot = () => wrapper.find('[data-testid="body-slot"]');
diff --git a/spec/frontend/vue_shared/components/registry/list_item_spec.js b/spec/frontend/vue_shared/components/registry/list_item_spec.js
index 6e9abb2bfb3..b941eb77c32 100644
--- a/spec/frontend/vue_shared/components/registry/list_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/list_item_spec.js
@@ -13,7 +13,7 @@ describe('list item', () => {
const findRightSecondarySlot = () => wrapper.find('[data-testid="right-secondary"]');
const findRightActionSlot = () => wrapper.find('[data-testid="right-action"]');
const findDetailsSlot = (name) => wrapper.find(`[data-testid="${name}"]`);
- const findToggleDetailsButton = () => wrapper.find(GlButton);
+ const findToggleDetailsButton = () => wrapper.findComponent(GlButton);
const mountComponent = (propsData, slots) => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/vue_shared/components/registry/metadata_item_spec.js b/spec/frontend/vue_shared/components/registry/metadata_item_spec.js
index e4abdc15fd5..a04e1e237d4 100644
--- a/spec/frontend/vue_shared/components/registry/metadata_item_spec.js
+++ b/spec/frontend/vue_shared/components/registry/metadata_item_spec.js
@@ -24,10 +24,10 @@ describe('Metadata Item', () => {
wrapper = null;
});
- const findIcon = () => wrapper.find(GlIcon);
- const findLink = (w = wrapper) => w.find(GlLink);
+ const findIcon = () => wrapper.findComponent(GlIcon);
+ const findLink = (w = wrapper) => w.findComponent(GlLink);
const findText = () => wrapper.find('[data-testid="metadata-item-text"]');
- const findTooltipOnTruncate = (w = wrapper) => w.find(TooltipOnTruncate);
+ const findTooltipOnTruncate = (w = wrapper) => w.findComponent(TooltipOnTruncate);
const findTextTooltip = () => wrapper.find('[data-testid="text-tooltip-container"]');
describe.each(['xs', 's', 'm', 'l', 'xl'])('size class', (size) => {
diff --git a/spec/frontend/vue_shared/components/registry/registry_search_spec.js b/spec/frontend/vue_shared/components/registry/registry_search_spec.js
index 20716e79a04..70f4693ae81 100644
--- a/spec/frontend/vue_shared/components/registry/registry_search_spec.js
+++ b/spec/frontend/vue_shared/components/registry/registry_search_spec.js
@@ -6,9 +6,9 @@ import component from '~/vue_shared/components/registry/registry_search.vue';
describe('Registry Search', () => {
let wrapper;
- const findPackageListSorting = () => wrapper.find(GlSorting);
- const findSortingItems = () => wrapper.findAll(GlSortingItem);
- const findFilteredSearch = () => wrapper.find(GlFilteredSearch);
+ const findPackageListSorting = () => wrapper.findComponent(GlSorting);
+ const findSortingItems = () => wrapper.findAllComponents(GlSortingItem);
+ const findFilteredSearch = () => wrapper.findComponent(GlFilteredSearch);
const defaultProps = {
filters: [],
diff --git a/spec/frontend/vue_shared/components/registry/title_area_spec.js b/spec/frontend/vue_shared/components/registry/title_area_spec.js
index b62676b35be..efb57ddd310 100644
--- a/spec/frontend/vue_shared/components/registry/title_area_spec.js
+++ b/spec/frontend/vue_shared/components/registry/title_area_spec.js
@@ -199,7 +199,7 @@ describe('title area', () => {
const message = findInfoMessages().at(0);
- expect(message.find(GlLink).attributes('href')).toBe('bar');
+ expect(message.findComponent(GlLink).attributes('href')).toBe('bar');
expect(message.text()).toBe('foo link');
});
diff --git a/spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js b/spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js
new file mode 100644
index 00000000000..5d96fe27676
--- /dev/null
+++ b/spec/frontend/vue_shared/components/rich_timestamp_tooltip_spec.js
@@ -0,0 +1,41 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+
+import { formatDate } from '~/lib/utils/datetime_utility';
+import RichTimestampTooltip from '~/vue_shared/components/rich_timestamp_tooltip.vue';
+
+describe('RichTimestampTooltip', () => {
+ const currentDate = new Date();
+ const mockRawTimestamp = currentDate.toISOString();
+ const mockTimestamp = formatDate(currentDate);
+ let wrapper;
+
+ const createComponent = ({
+ target = 'some-element',
+ rawTimestamp = mockRawTimestamp,
+ timestampTypeText = 'Created',
+ } = {}) => {
+ wrapper = shallowMountExtended(RichTimestampTooltip, {
+ propsData: {
+ target,
+ rawTimestamp,
+ timestampTypeText,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the tooltip text header', () => {
+ expect(wrapper.findByTestId('header-text').text()).toBe('Created just now');
+ });
+
+ it('renders the tooltip text body', () => {
+ expect(wrapper.findByTestId('body-text').text()).toBe(mockTimestamp);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
index a38dcd626f4..7c5fc63856a 100644
--- a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
+++ b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
@@ -166,7 +166,7 @@ describe('RunnerInstructionsModal component', () => {
});
it('sets the focus on the default selected platform', () => {
- const findOsxPlatformButton = () => wrapper.find({ ref: 'osx' });
+ const findOsxPlatformButton = () => wrapper.findComponent({ ref: 'osx' });
findOsxPlatformButton().element.focus = jest.fn();
@@ -234,14 +234,14 @@ describe('RunnerInstructionsModal component', () => {
MockResizeObserver.mockResize('xs');
await nextTick();
- expect(findPlatformButtonGroup().attributes('vertical')).toBeTruthy();
+ expect(findPlatformButtonGroup().attributes('vertical')).toEqual('true');
});
it('to a non-xs viewport', async () => {
MockResizeObserver.mockResize('sm');
await nextTick();
- expect(findPlatformButtonGroup().props('vertical')).toBeFalsy();
+ expect(findPlatformButtonGroup().props('vertical')).toBeUndefined();
});
});
});
diff --git a/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js b/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js
index 71ebe561def..c5672bc28cc 100644
--- a/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js
+++ b/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js
@@ -50,7 +50,7 @@ describe('Merge request artifact Download', () => {
return createMockApollo(requestHandlers);
};
- const findDownloadDropdown = () => wrapper.find(SecurityReportDownloadDropdown);
+ const findDownloadDropdown = () => wrapper.findComponent(SecurityReportDownloadDropdown);
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js b/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js
index ae86106d86e..08d3d5b19d4 100644
--- a/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js
+++ b/spec/frontend/vue_shared/components/security_reports/help_icon_spec.js
@@ -17,9 +17,9 @@ describe('HelpIcon component', () => {
});
};
- const findLink = () => wrapper.find(GlLink);
- const findPopover = () => wrapper.find(GlPopover);
- const findPopoverTarget = () => wrapper.find({ ref: 'discoverProjectSecurity' });
+ const findLink = () => wrapper.findComponent(GlLink);
+ const findPopover = () => wrapper.findComponent(GlPopover);
+ const findPopoverTarget = () => wrapper.findComponent({ ref: 'discoverProjectSecurity' });
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js b/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
index f213e37cbc1..9b1316677d7 100644
--- a/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/issuable_move_dropdown_spec.js
@@ -173,15 +173,15 @@ describe('IssuableMoveDropdown', () => {
});
describe('template', () => {
- const findDropdownEl = () => wrapper.find(GlDropdown);
+ const findDropdownEl = () => wrapper.findComponent(GlDropdown);
it('renders collapsed state element with icon', () => {
const collapsedEl = wrapper.find('[data-testid="move-collapsed"]');
expect(collapsedEl.exists()).toBe(true);
expect(collapsedEl.attributes('title')).toBe(mockProps.dropdownButtonTitle);
- expect(collapsedEl.find(GlIcon).exists()).toBe(true);
- expect(collapsedEl.find(GlIcon).props('name')).toBe('arrow-right');
+ expect(collapsedEl.findComponent(GlIcon).exists()).toBe(true);
+ expect(collapsedEl.findComponent(GlIcon).props('name')).toBe('arrow-right');
});
describe('gl-dropdown component', () => {
@@ -191,7 +191,7 @@ describe('IssuableMoveDropdown', () => {
});
it('renders gl-dropdown-form component', () => {
- expect(findDropdownEl().find(GlDropdownForm).exists()).toBe(true);
+ expect(findDropdownEl().findComponent(GlDropdownForm).exists()).toBe(true);
});
it('renders header element', () => {
@@ -199,11 +199,11 @@ describe('IssuableMoveDropdown', () => {
expect(headerEl.exists()).toBe(true);
expect(headerEl.find('span').text()).toBe(mockProps.dropdownHeaderTitle);
- expect(headerEl.find(GlButton).props('icon')).toBe('close');
+ expect(headerEl.findComponent(GlButton).props('icon')).toBe('close');
});
it('renders gl-search-box-by-type component', () => {
- const searchEl = findDropdownEl().find(GlSearchBoxByType);
+ const searchEl = findDropdownEl().findComponent(GlSearchBoxByType);
expect(searchEl.exists()).toBe(true);
expect(searchEl.attributes()).toMatchObject({
@@ -221,7 +221,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- expect(findDropdownEl().find(GlLoadingIcon).exists()).toBe(true);
+ expect(findDropdownEl().findComponent(GlLoadingIcon).exists()).toBe(true);
});
it('renders gl-dropdown-item components for available projects', async () => {
@@ -234,7 +234,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- const dropdownItems = wrapper.findAll(GlDropdownItem);
+ const dropdownItems = wrapper.findAllComponents(GlDropdownItem);
expect(dropdownItems).toHaveLength(mockProjects.length);
expect(dropdownItems.at(0).props()).toMatchObject({
@@ -285,7 +285,7 @@ describe('IssuableMoveDropdown', () => {
});
it('renders gl-button within footer', async () => {
- const moveButtonEl = wrapper.find('[data-testid="footer"]').find(GlButton);
+ const moveButtonEl = wrapper.find('[data-testid="footer"]').findComponent(GlButton);
expect(moveButtonEl.text()).toBe('Move');
expect(moveButtonEl.attributes('disabled')).toBe('true');
@@ -299,7 +299,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
expect(
- wrapper.find('[data-testid="footer"]').find(GlButton).attributes('disabled'),
+ wrapper.find('[data-testid="footer"]').findComponent(GlButton).attributes('disabled'),
).not.toBeDefined();
});
});
@@ -308,7 +308,7 @@ describe('IssuableMoveDropdown', () => {
it('collapsed state element emits `toggle-collapse` event on component when clicked', () => {
wrapper.find('[data-testid="move-collapsed"]').trigger('click');
- expect(wrapper.emitted('toggle-collapse')).toBeTruthy();
+ expect(wrapper.emitted('toggle-collapse')).toHaveLength(1);
});
it('gl-dropdown component calls `fetchProjects` on `shown` event', () => {
@@ -337,11 +337,11 @@ describe('IssuableMoveDropdown', () => {
it('gl-dropdown component emits `dropdown-close` event on component from `hide` event', async () => {
findDropdownEl().vm.$emit('hide');
- expect(wrapper.emitted('dropdown-close')).toBeTruthy();
+ expect(wrapper.emitted('dropdown-close')).toHaveLength(1);
});
it('close icon in dropdown header closes the dropdown when clicked', () => {
- wrapper.find('[data-testid="header"]').find(GlButton).vm.$emit('click', mockEvent);
+ wrapper.find('[data-testid="header"]').findComponent(GlButton).vm.$emit('click', mockEvent);
expect(wrapper.vm.$refs.dropdown.hide).toHaveBeenCalled();
});
@@ -355,7 +355,7 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- wrapper.findAll(GlDropdownItem).at(0).vm.$emit('click', mockEvent);
+ wrapper.findAllComponents(GlDropdownItem).at(0).vm.$emit('click', mockEvent);
expect(wrapper.vm.selectedProject).toBe(mockProjects[0]);
});
@@ -369,10 +369,10 @@ describe('IssuableMoveDropdown', () => {
await nextTick();
- wrapper.find('[data-testid="footer"]').find(GlButton).vm.$emit('click');
+ wrapper.find('[data-testid="footer"]').findComponent(GlButton).vm.$emit('click');
expect(wrapper.vm.$refs.dropdown.hide).toHaveBeenCalled();
- expect(wrapper.emitted('move-issuable')).toBeTruthy();
+ expect(wrapper.emitted('move-issuable')).toHaveLength(1);
expect(wrapper.emitted('move-issuable')[0]).toEqual([mockProjects[0]]);
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js
index c05513a6d5f..c0e5408e1bd 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_button_spec.js
@@ -33,9 +33,9 @@ describe('DropdownButton', () => {
wrapper.destroy();
});
- const findDropdownButton = () => wrapper.find(GlButton);
+ const findDropdownButton = () => wrapper.findComponent(GlButton);
const findDropdownText = () => wrapper.find('.dropdown-toggle-text');
- const findDropdownIcon = () => wrapper.find(GlIcon);
+ const findDropdownIcon = () => wrapper.findComponent(GlIcon);
describe('methods', () => {
describe('handleButtonClick', () => {
@@ -61,7 +61,7 @@ describe('DropdownButton', () => {
describe('template', () => {
it('renders component container element', () => {
- expect(wrapper.find(GlButton).element).toBe(wrapper.element);
+ expect(wrapper.findComponent(GlButton).element).toBe(wrapper.element);
});
it('renders default button text element', () => {
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
index 0673ffee22b..799e2c1d08e 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view_spec.js
@@ -127,7 +127,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders dropdown back button element', () => {
- const backBtnEl = wrapper.find('.dropdown-title').findAll(GlButton).at(0);
+ const backBtnEl = wrapper.find('.dropdown-title').findAllComponents(GlButton).at(0);
expect(backBtnEl.exists()).toBe(true);
expect(backBtnEl.attributes('aria-label')).toBe('Go back');
@@ -142,7 +142,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders dropdown close button element', () => {
- const closeBtnEl = wrapper.find('.dropdown-title').findAll(GlButton).at(1);
+ const closeBtnEl = wrapper.find('.dropdown-title').findAllComponents(GlButton).at(1);
expect(closeBtnEl.exists()).toBe(true);
expect(closeBtnEl.attributes('aria-label')).toBe('Close');
@@ -150,7 +150,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders label title input element', () => {
- const titleInputEl = wrapper.find('.dropdown-input').find(GlFormInput);
+ const titleInputEl = wrapper.find('.dropdown-input').findComponent(GlFormInput);
expect(titleInputEl.exists()).toBe(true);
expect(titleInputEl.attributes('placeholder')).toBe('Name new label');
@@ -158,7 +158,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders color block element for all suggested colors', () => {
- const colorBlocksEl = wrapper.find('.dropdown-content').findAll(GlLink);
+ const colorBlocksEl = wrapper.find('.dropdown-content').findAllComponents(GlLink);
colorBlocksEl.wrappers.forEach((colorBlock, index) => {
expect(colorBlock.attributes('style')).toContain('background-color');
@@ -175,7 +175,7 @@ describe('DropdownContentsCreateView', () => {
await nextTick();
const colorPreviewEl = wrapper.find('.color-input-container > .dropdown-label-color-preview');
- const colorInputEl = wrapper.find('.color-input-container').find(GlFormInput);
+ const colorInputEl = wrapper.find('.color-input-container').findComponent(GlFormInput);
expect(colorPreviewEl.exists()).toBe(true);
expect(colorPreviewEl.attributes('style')).toContain('background-color');
@@ -185,7 +185,7 @@ describe('DropdownContentsCreateView', () => {
});
it('renders create button element', () => {
- const createBtnEl = wrapper.find('.dropdown-actions').findAll(GlButton).at(0);
+ const createBtnEl = wrapper.find('.dropdown-actions').findAllComponents(GlButton).at(0);
expect(createBtnEl.exists()).toBe(true);
expect(createBtnEl.text()).toContain('Create');
@@ -195,14 +195,14 @@ describe('DropdownContentsCreateView', () => {
wrapper.vm.$store.dispatch('requestCreateLabel');
await nextTick();
- const loadingIconEl = wrapper.find('.dropdown-actions').find(GlLoadingIcon);
+ const loadingIconEl = wrapper.find('.dropdown-actions').findComponent(GlLoadingIcon);
expect(loadingIconEl.exists()).toBe(true);
expect(loadingIconEl.isVisible()).toBe(true);
});
it('renders cancel button element', () => {
- const cancelBtnEl = wrapper.find('.dropdown-actions').findAll(GlButton).at(1);
+ const cancelBtnEl = wrapper.find('.dropdown-actions').findAllComponents(GlButton).at(1);
expect(cancelBtnEl.exists()).toBe(true);
expect(cancelBtnEl.text()).toContain('Cancel');
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
index 00c8e3a814a..cc9b9f393ce 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -58,7 +58,7 @@ describe('DropdownContentsLabelsView', () => {
const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
const findDropdownTitle = () => wrapper.find('[data-testid="dropdown-title"]');
const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
describe('computed', () => {
describe('visibleLabels', () => {
@@ -285,7 +285,7 @@ describe('DropdownContentsLabelsView', () => {
describe('template', () => {
it('renders gl-intersection-observer as component root', () => {
- expect(wrapper.find(GlIntersectionObserver).exists()).toBe(true);
+ expect(wrapper.findComponent(GlIntersectionObserver).exists()).toBe(true);
});
it('renders gl-loading-icon component when `labelsFetchInProgress` prop is true', async () => {
@@ -316,20 +316,20 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders dropdown close button element', () => {
- const closeButtonEl = findDropdownTitle().find(GlButton);
+ const closeButtonEl = findDropdownTitle().findComponent(GlButton);
expect(closeButtonEl.exists()).toBe(true);
expect(closeButtonEl.props('icon')).toBe('close');
});
it('renders label search input element', () => {
- const searchInputEl = wrapper.find(GlSearchBoxByType);
+ const searchInputEl = wrapper.findComponent(GlSearchBoxByType);
expect(searchInputEl.exists()).toBe(true);
});
it('renders label elements for all labels', () => {
- expect(wrapper.findAll(LabelItem)).toHaveLength(mockLabels.length);
+ expect(wrapper.findAllComponents(LabelItem)).toHaveLength(mockLabels.length);
});
it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', async () => {
@@ -340,7 +340,7 @@ describe('DropdownContentsLabelsView', () => {
});
await nextTick();
- const labelItemEl = findDropdownContent().find(LabelItem);
+ const labelItemEl = findDropdownContent().findComponent(LabelItem);
expect(labelItemEl.attributes('highlight')).toBe('true');
});
@@ -373,7 +373,7 @@ describe('DropdownContentsLabelsView', () => {
});
it('renders footer list items', () => {
- const footerLinks = findDropdownFooter().findAll(GlLink);
+ const footerLinks = findDropdownFooter().findAllComponents(GlLink);
const createLabelLink = footerLinks.at(0);
const manageLabelsLink = footerLinks.at(1);
@@ -387,7 +387,7 @@ describe('DropdownContentsLabelsView', () => {
wrapper.vm.$store.state.allowLabelCreate = false;
await nextTick();
- const createLabelLink = findDropdownFooter().findAll(GlLink).at(0);
+ const createLabelLink = findDropdownFooter().findAllComponents(GlLink).at(0);
expect(createLabelLink.text()).not.toBe('Create label');
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js
index 84e9f3f41c3..54804f85f81 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/dropdown_title_spec.js
@@ -41,7 +41,7 @@ describe('DropdownTitle', () => {
});
it('renders edit link', () => {
- const editBtnEl = wrapper.find(GlButton);
+ const editBtnEl = wrapper.findComponent(GlButton);
expect(editBtnEl.exists()).toBe(true);
expect(editBtnEl.text()).toBe('Edit');
@@ -53,7 +53,7 @@ describe('DropdownTitle', () => {
});
await nextTick();
- expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).isVisible()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
index bedb6204088..bb0f1777de6 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js
@@ -32,7 +32,7 @@ describe('LabelItem', () => {
describe('template', () => {
it('renders gl-link component', () => {
- expect(wrapper.find(GlLink).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLink).exists()).toBe(true);
});
it('renders component root with class `is-focused` when `highlight` prop is true', () => {
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js
index c150410ff8e..4c7ac6e9a6f 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_vue/labels_select_root_spec.js
@@ -138,13 +138,13 @@ describe('LabelsSelectRoot', () => {
it('renders `dropdown-value-collapsed` component when `allowLabelCreate` prop is `true`', async () => {
createComponent();
await nextTick();
- expect(wrapper.find(DropdownValueCollapsed).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownValueCollapsed).exists()).toBe(true);
});
it('renders `dropdown-title` component', async () => {
createComponent();
await nextTick();
- expect(wrapper.find(DropdownTitle).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownTitle).exists()).toBe(true);
});
it('renders `dropdown-value` component', async () => {
@@ -153,7 +153,7 @@ describe('LabelsSelectRoot', () => {
});
await nextTick();
- const valueComp = wrapper.find(DropdownValue);
+ const valueComp = wrapper.findComponent(DropdownValue);
expect(valueComp.exists()).toBe(true);
expect(valueComp.text()).toBe('None');
@@ -163,14 +163,14 @@ describe('LabelsSelectRoot', () => {
createComponent();
wrapper.vm.$store.dispatch('toggleDropdownButton');
await nextTick();
- expect(wrapper.find(DropdownButton).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownButton).exists()).toBe(true);
});
it('renders `dropdown-contents` component when `showDropdownButton` & `showDropdownContents` prop is `true`', async () => {
createComponent();
wrapper.vm.$store.dispatch('toggleDropdownContents');
await nextTick();
- expect(wrapper.find(DropdownContents).exists()).toBe(true);
+ expect(wrapper.findComponent(DropdownContents).exists()).toBe(true);
});
describe('sets content direction based on viewport', () => {
@@ -187,7 +187,7 @@ describe('LabelsSelectRoot', () => {
wrapper.vm.setContentIsOnViewport(wrapper.vm.$store.state);
await nextTick();
- expect(wrapper.find(DropdownContents).props('renderOnTop')).toBe(true);
+ expect(wrapper.findComponent(DropdownContents).props('renderOnTop')).toBe(true);
});
it('does not set direction when inside of viewport', async () => {
@@ -195,7 +195,7 @@ describe('LabelsSelectRoot', () => {
wrapper.vm.setContentIsOnViewport(wrapper.vm.$store.state);
await nextTick();
- expect(wrapper.find(DropdownContents).props('renderOnTop')).toBe(false);
+ expect(wrapper.findComponent(DropdownContents).props('renderOnTop')).toBe(false);
});
},
);
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
index 1b27a294b90..cad401e0013 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
@@ -131,6 +131,7 @@ describe('LabelsSelectRoot', () => {
expect(findDropdownValue().exists()).toBe(true);
expect(findDropdownValue().props('selectedLabels')).toEqual([
{
+ __typename: 'Label',
color: '#330066',
description: null,
id: 'gid://gitlab/ProjectLabel/1',
diff --git a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
index de3e1ccfb03..01958a144ed 100644
--- a/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/todo_button_spec.js
@@ -30,19 +30,19 @@ describe('Todo Button', () => {
it('renders GlButton', () => {
createComponent();
- expect(wrapper.find(GlButton).exists()).toBe(true);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(true);
});
it('emits click event when clicked', () => {
createComponent({}, mount);
- wrapper.find(GlButton).trigger('click');
+ wrapper.findComponent(GlButton).trigger('click');
- expect(wrapper.emitted().click).toBeTruthy();
+ expect(wrapper.emitted().click).toHaveLength(1);
});
it('calls dispatchDocumentEvent to update global To-Do counter correctly', () => {
createComponent({}, mount);
- wrapper.find(GlButton).trigger('click');
+ wrapper.findComponent(GlButton).trigger('click');
const dispatchedEvent = dispatchEventSpy.mock.calls[0][0];
expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
@@ -57,12 +57,12 @@ describe('Todo Button', () => {
`('sets correct label when isTodo is $isTodo', ({ label, isTodo }) => {
createComponent({ isTodo });
- expect(wrapper.find(GlButton).text()).toBe(label);
+ expect(wrapper.findComponent(GlButton).text()).toBe(label);
});
it('binds additional props to GlButton', () => {
createComponent({ loading: true });
- expect(wrapper.find(GlButton).props('loading')).toBe(true);
+ expect(wrapper.findComponent(GlButton).props('loading')).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/components/source_editor_spec.js b/spec/frontend/vue_shared/components/source_editor_spec.js
index dca4d60e23c..ca5b990bc29 100644
--- a/spec/frontend/vue_shared/components/source_editor_spec.js
+++ b/spec/frontend/vue_shared/components/source_editor_spec.js
@@ -3,6 +3,7 @@ import { nextTick } from 'vue';
import { EDITOR_READY_EVENT } from '~/editor/constants';
import Editor from '~/editor/source_editor';
import SourceEditor from '~/vue_shared/components/source_editor.vue';
+import * as helpers from 'jest/editor/helpers';
jest.mock('~/editor/source_editor');
@@ -13,6 +14,7 @@ describe('Source Editor component', () => {
const value = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
const fileName = 'lorem.txt';
const fileGlobalId = 'snippet_777';
+ const useSpy = jest.fn();
const createInstanceMock = jest.fn().mockImplementation(() => {
mockInstance = {
onDidChangeModelContent: jest.fn(),
@@ -20,6 +22,7 @@ describe('Source Editor component', () => {
getValue: jest.fn(),
setValue: jest.fn(),
dispose: jest.fn(),
+ use: useSpy,
};
return mockInstance;
});
@@ -77,16 +80,33 @@ describe('Source Editor component', () => {
});
it('initialises Source Editor instance', () => {
- const el = wrapper.find({ ref: 'editor' }).element;
+ const el = wrapper.findComponent({ ref: 'editor' }).element;
expect(createInstanceMock).toHaveBeenCalledWith({
el,
blobPath: fileName,
blobGlobalId: fileGlobalId,
blobContent: value,
- extensions: null,
});
});
+ it.each`
+ description | extensions | toBeCalled
+ ${'no extension when `undefined` is'} | ${undefined} | ${false}
+ ${'no extension when {} is'} | ${{}} | ${false}
+ ${'no extension when [] is'} | ${[]} | ${false}
+ ${'single extension'} | ${{ definition: helpers.SEClassExtension }} | ${true}
+ ${'single extension with options'} | ${{ definition: helpers.SEWithSetupExt, setupOptions: { foo: 'bar' } }} | ${true}
+ ${'multiple extensions'} | ${[{ definition: helpers.SEClassExtension }, { definition: helpers.SEWithSetupExt }]} | ${true}
+ ${'multiple extensions with options'} | ${[{ definition: helpers.SEClassExtension }, { definition: helpers.SEWithSetupExt, setupOptions: { foo: 'bar' } }]} | ${true}
+ `('installs $description passed as a prop', ({ extensions, toBeCalled }) => {
+ createComponent({ extensions });
+ if (toBeCalled) {
+ expect(useSpy).toHaveBeenCalledWith(extensions);
+ } else {
+ expect(useSpy).not.toHaveBeenCalled();
+ }
+ });
+
it('reacts to the changes in fileName', () => {
const newFileName = 'ipsum.txt';
@@ -112,7 +132,7 @@ describe('Source Editor component', () => {
});
it('emits EDITOR_READY_EVENT event when the Source Editor is ready', async () => {
- const el = wrapper.find({ ref: 'editor' }).element;
+ const el = wrapper.findComponent({ ref: 'editor' }).element;
expect(wrapper.emitted()[EDITOR_READY_EVENT]).toBeUndefined();
await el.dispatchEvent(new Event(EDITOR_READY_EVENT));
diff --git a/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js b/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
index eb2eec92534..fd3ff9ce892 100644
--- a/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
@@ -1,4 +1,3 @@
-import { GlLink } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ChunkLine from '~/vue_shared/components/source_viewer/components/chunk_line.vue';
import {
@@ -11,16 +10,26 @@ const DEFAULT_PROPS = {
number: 2,
content: '// Line content',
language: 'javascript',
+ blamePath: 'blame/file.js',
};
describe('Chunk Line component', () => {
let wrapper;
+ const fileLineBlame = true;
const createComponent = (props = {}) => {
- wrapper = shallowMountExtended(ChunkLine, { propsData: { ...DEFAULT_PROPS, ...props } });
+ wrapper = shallowMountExtended(ChunkLine, {
+ propsData: { ...DEFAULT_PROPS, ...props },
+ provide: {
+ glFeatures: {
+ fileLineBlame,
+ },
+ },
+ });
};
- const findLink = () => wrapper.findComponent(GlLink);
+ const findLineLink = () => wrapper.find('.file-line-num');
+ const findBlameLink = () => wrapper.find('.file-line-blame');
const findContent = () => wrapper.findByTestId('content');
const findWrappedBidiChars = () => wrapper.findAllByTestId('bidi-wrapper');
@@ -47,14 +56,22 @@ describe('Chunk Line component', () => {
});
});
+ it('renders a blame link', () => {
+ expect(findBlameLink().attributes()).toMatchObject({
+ href: `${DEFAULT_PROPS.blamePath}#L${DEFAULT_PROPS.number}`,
+ });
+
+ expect(findBlameLink().text()).toBe('');
+ });
+
it('renders a line number', () => {
- expect(findLink().attributes()).toMatchObject({
+ expect(findLineLink().attributes()).toMatchObject({
'data-line-number': `${DEFAULT_PROPS.number}`,
- to: `#L${DEFAULT_PROPS.number}`,
+ href: `#L${DEFAULT_PROPS.number}`,
id: `L${DEFAULT_PROPS.number}`,
});
- expect(findLink().text()).toBe(DEFAULT_PROPS.number.toString());
+ expect(findLineLink().text()).toBe(DEFAULT_PROPS.number.toString());
});
it('renders content', () => {
diff --git a/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js b/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
index 42c4f2eacb8..8dc3348acfa 100644
--- a/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
@@ -10,6 +10,7 @@ const DEFAULT_PROPS = {
startingFrom: 140,
totalLines: 50,
language: 'javascript',
+ blamePath: 'blame/file.js',
};
describe('Chunk component', () => {
@@ -76,6 +77,7 @@ describe('Chunk component', () => {
number: DEFAULT_PROPS.startingFrom + 1,
content: splitContent[0],
language: DEFAULT_PROPS.language,
+ blamePath: DEFAULT_PROPS.blamePath,
});
});
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js
index 3036ce43888..375b1307616 100644
--- a/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/link_dependencies_spec.js
@@ -1,8 +1,10 @@
import packageJsonLinker from '~/vue_shared/components/source_viewer/plugins/utils/package_json_linker';
+import gemspecLinker from '~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker';
import linkDependencies from '~/vue_shared/components/source_viewer/plugins/link_dependencies';
-import { PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT } from './mock_data';
+import { PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT, GEMSPEC_FILE_TYPE } from './mock_data';
jest.mock('~/vue_shared/components/source_viewer/plugins/utils/package_json_linker');
+jest.mock('~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker');
describe('Highlight.js plugin for linking dependencies', () => {
const hljsResultMock = { value: 'test' };
@@ -11,4 +13,9 @@ describe('Highlight.js plugin for linking dependencies', () => {
linkDependencies(hljsResultMock, PACKAGE_JSON_FILE_TYPE, PACKAGE_JSON_CONTENT);
expect(packageJsonLinker).toHaveBeenCalled();
});
+
+ it('calls gemspecLinker for gemspec file types', () => {
+ linkDependencies(hljsResultMock, GEMSPEC_FILE_TYPE);
+ expect(gemspecLinker).toHaveBeenCalled();
+ });
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js b/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js
index 75659770e2c..aa874c9c081 100644
--- a/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/mock_data.js
@@ -1,2 +1,4 @@
export const PACKAGE_JSON_FILE_TYPE = 'package_json';
export const PACKAGE_JSON_CONTENT = '{ "dependencies": { "@babel/core": "^7.18.5" } }';
+
+export const GEMSPEC_FILE_TYPE = 'gemspec';
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js
index ee200747af9..8079d5ad99a 100644
--- a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/dependency_linker_util_spec.js
@@ -14,10 +14,11 @@ describe('createLink', () => {
it('escapes the user-controlled content', () => {
const unescapedXSS = '<script>XSS</script>';
- const escapedXSS = '&amp;lt;script&amp;gt;XSS&amp;lt;/script&amp;gt;';
+ const escapedPackageName = '&lt;script&gt;XSS&lt;/script&gt;';
+ const escapedHref = '&amp;lt;script&amp;gt;XSS&amp;lt;/script&amp;gt;';
const href = `http://test.com/${unescapedXSS}`;
const innerText = `testing${unescapedXSS}`;
- const result = `<a href="http://test.com/${escapedXSS}" rel="nofollow noreferrer noopener">testing${escapedXSS}</a>`;
+ const result = `<a href="http://test.com/${escapedHref}" rel="nofollow noreferrer noopener">testing${escapedPackageName}</a>`;
expect(createLink(href, innerText)).toBe(result);
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js
new file mode 100644
index 00000000000..3f74bfa117f
--- /dev/null
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/utils/gemspec_linker_spec.js
@@ -0,0 +1,14 @@
+import gemspecLinker from '~/vue_shared/components/source_viewer/plugins/utils/gemspec_linker';
+
+describe('Highlight.js plugin for linking gemspec dependencies', () => {
+ it('mutates the input value by wrapping dependency names in anchors', () => {
+ const inputValue =
+ 's.add_dependency(<span class="hljs-string">&#x27;rugged&#x27;</span>, <span class="hljs-string">&#x27;~&gt; 0.24.0&#x27;</span>)';
+ const outputValue =
+ 's.add_dependency(<span class="hljs-string linked">&#x27;<a href="https://rubygems.org/gems/rugged" rel="nofollow noreferrer noopener">rugged</a>&#x27;</span>, <span class="hljs-string">&#x27;~&gt; 0.24.0&#x27;</span>)';
+ const hljsResultMock = { value: inputValue };
+
+ const output = gemspecLinker(hljsResultMock);
+ expect(output).toBe(outputValue);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
index 2c03b7aa7d3..4fbc907a813 100644
--- a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
@@ -40,8 +40,9 @@ describe('Source Viewer component', () => {
const chunk2 = generateContent('// Some source code 2', 70);
const content = chunk1 + chunk2;
const path = 'some/path.js';
+ const blamePath = 'some/blame/path.js';
const fileType = 'javascript';
- const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path, fileType };
+ const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path, blamePath, fileType };
const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
const createComponent = async (blob = {}) => {
diff --git a/spec/frontend/vue_shared/components/split_button_spec.js b/spec/frontend/vue_shared/components/split_button_spec.js
index 4965969bc3e..6b869db4058 100644
--- a/spec/frontend/vue_shared/components/split_button_spec.js
+++ b/spec/frontend/vue_shared/components/split_button_spec.js
@@ -26,8 +26,9 @@ describe('SplitButton', () => {
});
};
- const findDropdown = () => wrapper.find(GlDropdown);
- const findDropdownItem = (index = 0) => findDropdown().findAll(GlDropdownItem).at(index);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItem = (index = 0) =>
+ findDropdown().findAllComponents(GlDropdownItem).at(index);
const selectItem = async (index) => {
findDropdownItem(index).vm.$emit('click');
diff --git a/spec/frontend/vue_shared/components/table_pagination_spec.js b/spec/frontend/vue_shared/components/table_pagination_spec.js
index ed23a47c328..99de26ce2ae 100644
--- a/spec/frontend/vue_shared/components/table_pagination_spec.js
+++ b/spec/frontend/vue_shared/components/table_pagination_spec.js
@@ -50,7 +50,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(wrapper.find(GlPagination).exists()).toBe(true);
+ expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
it('renders if there is a prev page', () => {
@@ -66,7 +66,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(wrapper.find(GlPagination).exists()).toBe(true);
+ expect(wrapper.findComponent(GlPagination).exists()).toBe(true);
});
});
@@ -83,7 +83,7 @@ describe('Pagination component', () => {
},
change: spy,
});
- wrapper.find(GlPagination).vm.$emit('input', 3);
+ wrapper.findComponent(GlPagination).vm.$emit('input', 3);
expect(spy).toHaveBeenCalledWith(3);
});
});
diff --git a/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js b/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
index 9e7e5c1263f..ca1f7996ad6 100644
--- a/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
+++ b/spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
@@ -68,7 +68,7 @@ describe('TooltipOnTruncate component', () => {
},
);
- wrapper = parent.find(WrappedTooltipOnTruncate);
+ wrapper = parent.findComponent(WrappedTooltipOnTruncate);
};
const getTooltipValue = () => getBinding(wrapper.element, 'gl-tooltip')?.value;
diff --git a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
index 21e9b401215..a063a5591e3 100644
--- a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
+++ b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js
@@ -14,7 +14,7 @@ describe('Upload dropzone component', () => {
const findDropzoneCard = () => wrapper.find('.upload-dropzone-card');
const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]');
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const findUploadText = () => wrapper.find('[data-testid="upload-text"]').text();
const findFileInput = () => wrapper.find('input[type="file"]');
diff --git a/spec/frontend/vue_shared/components/user_access_role_badge_spec.js b/spec/frontend/vue_shared/components/user_access_role_badge_spec.js
index 7f25f7c08e7..cea6fcac8c8 100644
--- a/spec/frontend/vue_shared/components/user_access_role_badge_spec.js
+++ b/spec/frontend/vue_shared/components/user_access_role_badge_spec.js
@@ -18,7 +18,7 @@ describe('UserAccessRoleBadge', () => {
},
});
- const badge = wrapper.find(GlBadge);
+ const badge = wrapper.findComponent(GlBadge);
expect(badge.exists()).toBe(true);
expect(badge.html()).toContain('test slot content');
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
index 5e05b54cb8c..f87737ca86a 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
@@ -18,6 +18,8 @@ const PROVIDED_PROPS = {
describe('User Avatar Image Component', () => {
let wrapper;
+ const findAvatar = () => wrapper.findComponent(GlAvatar);
+
afterEach(() => {
wrapper.destroy();
});
@@ -28,21 +30,14 @@ describe('User Avatar Image Component', () => {
propsData: {
...PROVIDED_PROPS,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should render `GlAvatar` and provide correct properties to it', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.attributes('data-src')).toBe(
+ expect(findAvatar().attributes('data-src')).toBe(
`${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
);
- expect(avatar.props()).toMatchObject({
+ expect(findAvatar().props()).toMatchObject({
src: `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
alt: PROVIDED_PROPS.imgAlt,
size: PROVIDED_PROPS.size,
@@ -63,23 +58,28 @@ describe('User Avatar Image Component', () => {
...PROVIDED_PROPS,
lazy: true,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should add lazy attributes', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.classes()).toContain('lazy');
- expect(avatar.attributes()).toMatchObject({
+ expect(findAvatar().classes()).toContain('lazy');
+ expect(findAvatar().attributes()).toMatchObject({
src: placeholderImage,
'data-src': `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
});
});
+
+ it('should use maximum number when size is provided as an object', () => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ size: { default: 16, md: 64, lg: 24 },
+ lazy: true,
+ },
+ });
+
+ expect(findAvatar().attributes('data-src')).toBe(`${PROVIDED_PROPS.imgSrc}?width=${64}`);
+ });
});
describe('Initialization without src', () => {
@@ -89,18 +89,11 @@ describe('User Avatar Image Component', () => {
...PROVIDED_PROPS,
imgSrc: null,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should have default avatar image', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
+ expect(findAvatar().props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
index 75d2a936b34..6ad2ef226c2 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
@@ -15,47 +15,37 @@ const PROVIDED_PROPS = {
describe('User Avatar Image Component', () => {
let wrapper;
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...PROVIDED_PROPS,
+ const createWrapper = (props = {}, { glAvatarForAllUserAvatars } = {}) => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ ...props,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
- });
+ },
});
+ };
- it('should render `UserAvatarImageNew` component', () => {
- expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(true);
- expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(false);
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...PROVIDED_PROPS,
- },
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: false,
- },
- },
+ describe.each([
+ [false, true, true],
+ [true, false, true],
+ [true, true, true],
+ [false, false, false],
+ ])(
+ 'when glAvatarForAllUserAvatars=%s and enforceGlAvatar=%s',
+ (glAvatarForAllUserAvatars, enforceGlAvatar, isUsingNewVersion) => {
+ it(`will render ${isUsingNewVersion ? 'new' : 'old'} version`, () => {
+ createWrapper({ enforceGlAvatar }, { glAvatarForAllUserAvatars });
+ expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(isUsingNewVersion);
+ expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(!isUsingNewVersion);
});
- });
-
- it('should render `UserAvatarImageOld` component', () => {
- expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(false);
- expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(true);
- });
- });
+ },
+ );
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
index 5ba80b31b99..f485a14cfea 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
@@ -54,6 +54,7 @@ describe('User Avatar Link Component', () => {
size: defaultProps.imgSize,
tooltipPlacement: defaultProps.tooltipPlacement,
tooltipText: '',
+ enforceGlAvatar: false,
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
index 2d513c46e77..cf7a1025dba 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
@@ -54,6 +54,7 @@ describe('User Avatar Link Component', () => {
size: defaultProps.imgSize,
tooltipPlacement: defaultProps.tooltipPlacement,
tooltipText: '',
+ enforceGlAvatar: false,
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
index b36b83d1fea..fd3f59008ec 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
@@ -15,47 +15,37 @@ const PROVIDED_PROPS = {
describe('User Avatar Link Component', () => {
let wrapper;
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...PROVIDED_PROPS,
+ const createWrapper = (props = {}, { glAvatarForAllUserAvatars } = {}) => {
+ wrapper = shallowMount(UserAvatarLink, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ ...props,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
- });
+ },
});
+ };
- it('should render `UserAvatarLinkNew` component', () => {
- expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(true);
- expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(false);
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...PROVIDED_PROPS,
- },
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: false,
- },
- },
+ describe.each([
+ [false, true, true],
+ [true, false, true],
+ [true, true, true],
+ [false, false, false],
+ ])(
+ 'when glAvatarForAllUserAvatars=%s and enforceGlAvatar=%s',
+ (glAvatarForAllUserAvatars, enforceGlAvatar, isUsingNewVersion) => {
+ it(`will render ${isUsingNewVersion ? 'new' : 'old'} version`, () => {
+ createWrapper({ enforceGlAvatar }, { glAvatarForAllUserAvatars });
+ expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(isUsingNewVersion);
+ expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(!isUsingNewVersion);
});
- });
-
- it('should render `UserAvatarLinkOld` component', () => {
- expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(false);
- expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(true);
- });
- });
+ },
+ );
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
index 20ff0848cff..b9accbf0373 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
@@ -38,7 +38,7 @@ describe('UserAvatarList', () => {
};
const clickButton = () => {
- const button = wrapper.find(GlButton);
+ const button = wrapper.findComponent(GlButton);
button.vm.$emit('click');
};
@@ -79,7 +79,7 @@ describe('UserAvatarList', () => {
const items = createList(20);
factory({ propsData: { items } });
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
const linkProps = links.wrappers.map((x) => x.props());
expect(linkProps).toEqual(
@@ -105,7 +105,7 @@ describe('UserAvatarList', () => {
it('renders all avatars if length is <= breakpoint', () => {
factory();
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(props.items.length);
});
@@ -113,7 +113,7 @@ describe('UserAvatarList', () => {
it('does not show button', () => {
factory();
- expect(wrapper.find(GlButton).exists()).toBe(false);
+ expect(wrapper.findComponent(GlButton).exists()).toBe(false);
});
});
@@ -126,7 +126,7 @@ describe('UserAvatarList', () => {
it('renders avatars up to breakpoint', () => {
factory();
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(TEST_BREAKPOINT);
});
@@ -138,7 +138,7 @@ describe('UserAvatarList', () => {
});
it('renders all avatars', () => {
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(props.items.length);
});
@@ -147,7 +147,7 @@ describe('UserAvatarList', () => {
clickButton();
await nextTick();
- const links = wrapper.findAll(UserAvatarLink);
+ const links = wrapper.findAllComponents(UserAvatarLink);
expect(links.length).toEqual(TEST_BREAKPOINT);
});
diff --git a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
index 9550368eefc..b7ce3e47cef 100644
--- a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
+++ b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
@@ -6,6 +6,7 @@ import UserPopover from '~/vue_shared/components/user_popover/user_popover.vue';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import { followUser, unfollowUser } from '~/api/user_api';
+import { mockTracking } from 'helpers/tracking_helper';
jest.mock('~/flash');
jest.mock('~/api/user_api', () => ({
@@ -51,6 +52,18 @@ describe('User Popover Component', () => {
const findUserLocalTime = () => wrapper.findByTestId('user-popover-local-time');
const findToggleFollowButton = () => wrapper.findByTestId('toggle-follow-button');
+ const itTracksToggleFollowButtonClick = (expectedLabel) => {
+ it('tracks click', async () => {
+ const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ await findToggleFollowButton().trigger('click');
+
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_button', {
+ label: expectedLabel,
+ });
+ });
+ };
+
const createWrapper = (props = {}) => {
wrapper = mountExtended(UserPopover, {
propsData: {
@@ -75,7 +88,7 @@ describe('User Popover Component', () => {
},
});
- expect(wrapper.find(GlSkeletonLoader).exists()).toBe(true);
+ expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(true);
});
});
@@ -89,7 +102,7 @@ describe('User Popover Component', () => {
it('shows icon for location', () => {
createWrapper();
- const iconEl = wrapper.find(GlIcon);
+ const iconEl = wrapper.findComponent(GlIcon);
expect(iconEl.props('name')).toEqual('location');
});
@@ -102,8 +115,8 @@ describe('User Popover Component', () => {
});
describe('job data', () => {
- const findWorkInformation = () => wrapper.find({ ref: 'workInformation' });
- const findBio = () => wrapper.find({ ref: 'bio' });
+ const findWorkInformation = () => wrapper.findComponent({ ref: 'workInformation' });
+ const findBio = () => wrapper.findComponent({ ref: 'bio' });
const bio = 'My super interesting bio';
it('should show only bio if work information is not available', () => {
@@ -159,7 +172,7 @@ describe('User Popover Component', () => {
createWrapper({ user });
expect(
- wrapper.findAll(GlIcon).filter((icon) => icon.props('name') === 'profile').length,
+ wrapper.findAllComponents(GlIcon).filter((icon) => icon.props('name') === 'profile').length,
).toEqual(1);
});
@@ -172,7 +185,7 @@ describe('User Popover Component', () => {
createWrapper({ user });
expect(
- wrapper.findAll(GlIcon).filter((icon) => icon.props('name') === 'work').length,
+ wrapper.findAllComponents(GlIcon).filter((icon) => icon.props('name') === 'work').length,
).toEqual(1);
});
});
@@ -338,9 +351,11 @@ describe('User Popover Component', () => {
await axios.waitForAll();
expect(wrapper.emitted().follow.length).toBe(1);
- expect(wrapper.emitted().unfollow).toBeFalsy();
+ expect(wrapper.emitted().unfollow).toBeUndefined();
});
+ itTracksToggleFollowButtonClick('follow_from_user_popover');
+
describe('when an error occurs', () => {
beforeEach(() => {
followUser.mockRejectedValue({});
@@ -361,8 +376,8 @@ describe('User Popover Component', () => {
it('emits no events', async () => {
await axios.waitForAll();
- expect(wrapper.emitted().follow).toBe(undefined);
- expect(wrapper.emitted().unfollow).toBe(undefined);
+ expect(wrapper.emitted().follow).toBeUndefined();
+ expect(wrapper.emitted().unfollow).toBeUndefined();
});
});
});
@@ -388,6 +403,8 @@ describe('User Popover Component', () => {
expect(wrapper.emitted().unfollow.length).toBe(1);
});
+ itTracksToggleFollowButtonClick('unfollow_from_user_popover');
+
describe('when an error occurs', () => {
beforeEach(async () => {
unfollowUser.mockRejectedValue({});
@@ -406,8 +423,8 @@ describe('User Popover Component', () => {
});
it('emits no events', () => {
- expect(wrapper.emitted().follow).toBe(undefined);
- expect(wrapper.emitted().unfollow).toBe(undefined);
+ expect(wrapper.emitted().follow).toBeUndefined();
+ expect(wrapper.emitted().unfollow).toBeUndefined();
});
});
});
diff --git a/spec/frontend/vue_shared/components/user_select_spec.js b/spec/frontend/vue_shared/components/user_select_spec.js
index ec9128d5e38..4188adc72a1 100644
--- a/spec/frontend/vue_shared/components/user_select_spec.js
+++ b/spec/frontend/vue_shared/components/user_select_spec.js
@@ -9,6 +9,7 @@ import searchUsersQuery from '~/graphql_shared/queries/users_search.query.graphq
import searchUsersQueryOnMR from '~/graphql_shared/queries/users_search_with_mr_permissions.graphql';
import { IssuableType } from '~/issues/constants';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
import getIssueParticipantsQuery from '~/vue_shared/components/sidebar/queries/get_issue_participants.query.graphql';
import UserSelect from '~/vue_shared/components/user_select/user_select.vue';
import {
@@ -16,6 +17,8 @@ import {
searchResponseOnMR,
projectMembersResponse,
participantsQueryResponse,
+ mockUser1,
+ mockUser2,
} from 'jest/sidebar/mock_data';
const assignee = {
@@ -45,9 +48,14 @@ describe('User select dropdown', () => {
const findSearchField = () => wrapper.findComponent(GlSearchBoxByType);
const findParticipantsLoading = () => wrapper.find('[data-testid="loading-participants"]');
const findSelectedParticipants = () => wrapper.findAll('[data-testid="selected-participant"]');
+ const findSelectedParticipantByIndex = (index) =>
+ findSelectedParticipants().at(index).findComponent(SidebarParticipant);
const findUnselectedParticipants = () =>
wrapper.findAll('[data-testid="unselected-participant"]');
+ const findUnselectedParticipantByIndex = (index) =>
+ findUnselectedParticipants().at(index).findComponent(SidebarParticipant);
const findCurrentUser = () => wrapper.findAll('[data-testid="current-user"]');
+ const findIssuableAuthor = () => wrapper.findAll('[data-testid="issuable-author"]');
const findUnassignLink = () => wrapper.find('[data-testid="unassign"]');
const findEmptySearchResults = () => wrapper.find('[data-testid="empty-results"]');
@@ -136,6 +144,93 @@ describe('User select dropdown', () => {
expect(findCurrentUser().exists()).toBe(true);
});
+ it('does not render current user if user is not logged in', async () => {
+ createComponent({
+ props: {
+ currentUser: {},
+ },
+ });
+ await waitForPromises();
+
+ expect(findCurrentUser().exists()).toBe(false);
+ });
+
+ it('does not render issuable author if author is not passed as a prop', async () => {
+ createComponent();
+ await waitForPromises();
+
+ expect(findIssuableAuthor().exists()).toBe(false);
+ });
+
+ describe('when issuable author is passed as a prop', () => {
+ it('moves issuable author on top of assigned list, if author is assigned', async () => {
+ createComponent({
+ props: {
+ value: [assignee, mockUser2],
+ issuableAuthor: mockUser2,
+ },
+ });
+ await waitForPromises();
+
+ expect(findSelectedParticipantByIndex(0).props('user')).toEqual(mockUser2);
+ });
+
+ it('moves issuable author on top of assigned list after current user, if author and current user are assigned', async () => {
+ const currentUser = mockUser1;
+ const issuableAuthor = mockUser2;
+
+ createComponent({
+ props: {
+ value: [assignee, issuableAuthor, currentUser],
+ issuableAuthor,
+ currentUser,
+ },
+ });
+ await waitForPromises();
+
+ expect(findSelectedParticipantByIndex(0).props('user')).toEqual(currentUser);
+ expect(findSelectedParticipantByIndex(1).props('user')).toEqual(issuableAuthor);
+ });
+
+ it('moves issuable author on top of unassigned list, if author is unassigned project member', async () => {
+ createComponent({
+ props: {
+ issuableAuthor: mockUser2,
+ },
+ });
+ await waitForPromises();
+
+ expect(findUnselectedParticipantByIndex(0).props('user')).toEqual(mockUser2);
+ });
+
+ it('moves issuable author on top of unassigned list after current user, if author and current user are unassigned project members', async () => {
+ const currentUser = mockUser2;
+ const issuableAuthor = mockUser1;
+
+ createComponent({
+ props: {
+ issuableAuthor,
+ currentUser,
+ },
+ });
+ await waitForPromises();
+
+ expect(findUnselectedParticipantByIndex(0).props('user')).toEqual(currentUser);
+ expect(findUnselectedParticipantByIndex(1).props('user')).toMatchObject(issuableAuthor);
+ });
+
+ it('displays author in a designated position if author is not assigned and not a project member', async () => {
+ createComponent({
+ props: {
+ issuableAuthor: assignee,
+ },
+ });
+ await waitForPromises();
+
+ expect(findIssuableAuthor().exists()).toBe(true);
+ });
+ });
+
it('displays correct amount of selected users', async () => {
createComponent({
props: {
diff --git a/spec/frontend/vue_shared/components/web_ide_link_spec.js b/spec/frontend/vue_shared/components/web_ide_link_spec.js
index 040461f6be4..a0b868d1d52 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -3,7 +3,7 @@ import { nextTick } from 'vue';
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
-import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
+import WebIdeLink, { i18n } from '~/vue_shared/components/web_ide_link.vue';
import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue';
import { stubComponent } from 'helpers/stub_component';
@@ -37,8 +37,8 @@ const ACTION_EDIT_CONFIRM_FORK = {
const ACTION_WEB_IDE = {
href: TEST_WEB_IDE_URL,
key: 'webide',
- secondaryText: 'Quickly and easily edit multiple files in your project.',
- tooltip: '',
+ secondaryText: i18n.webIdeText,
+ tooltip: i18n.webIdeTooltip,
text: 'Web IDE',
attrs: {
'data-qa-selector': 'web_ide_button',
@@ -108,8 +108,8 @@ describe('Web IDE link component', () => {
wrapper.destroy();
});
- const findActionsButton = () => wrapper.find(ActionsButton);
- const findLocalStorageSync = () => wrapper.find(LocalStorageSync);
+ const findActionsButton = () => wrapper.findComponent(ActionsButton);
+ const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
const findModal = () => wrapper.findComponent(GlModal);
const findForkConfirmModal = () => wrapper.findComponent(ConfirmForkModal);
diff --git a/spec/frontend/vue_shared/issuable/create/components/issuable_create_root_spec.js b/spec/frontend/vue_shared/issuable/create/components/issuable_create_root_spec.js
index 81362edaf37..7b0f0f7e344 100644
--- a/spec/frontend/vue_shared/issuable/create/components/issuable_create_root_spec.js
+++ b/spec/frontend/vue_shared/issuable/create/components/issuable_create_root_spec.js
@@ -51,11 +51,11 @@ describe('IssuableCreateRoot', () => {
});
it('renders issuable-form component', () => {
- expect(wrapper.find(IssuableForm).exists()).toBe(true);
+ expect(wrapper.findComponent(IssuableForm).exists()).toBe(true);
});
it('renders contents for slot "actions" within issuable-form component', () => {
- const buttonEl = wrapper.find(IssuableForm).find('button.js-issuable-save');
+ const buttonEl = wrapper.findComponent(IssuableForm).find('button.js-issuable-save');
expect(buttonEl.exists()).toBe(true);
expect(buttonEl.text()).toBe('Submit issuable');
diff --git a/spec/frontend/vue_shared/issuable/create/components/issuable_form_spec.js b/spec/frontend/vue_shared/issuable/create/components/issuable_form_spec.js
index cbfd05e7903..f98e7a678f4 100644
--- a/spec/frontend/vue_shared/issuable/create/components/issuable_form_spec.js
+++ b/spec/frontend/vue_shared/issuable/create/components/issuable_form_spec.js
@@ -65,9 +65,9 @@ describe('IssuableForm', () => {
expect(titleFieldEl.exists()).toBe(true);
expect(titleFieldEl.find('label').text()).toBe('Title');
- expect(titleFieldEl.find(GlFormInput).exists()).toBe(true);
- expect(titleFieldEl.find(GlFormInput).attributes('placeholder')).toBe('Title');
- expect(titleFieldEl.find(GlFormInput).attributes('autofocus')).toBe('true');
+ expect(titleFieldEl.findComponent(GlFormInput).exists()).toBe(true);
+ expect(titleFieldEl.findComponent(GlFormInput).attributes('placeholder')).toBe('Title');
+ expect(titleFieldEl.findComponent(GlFormInput).attributes('autofocus')).toBe('true');
});
it('renders issuable description input field', () => {
@@ -75,8 +75,8 @@ describe('IssuableForm', () => {
expect(descriptionFieldEl.exists()).toBe(true);
expect(descriptionFieldEl.find('label').text()).toBe('Description');
- expect(descriptionFieldEl.find(MarkdownField).exists()).toBe(true);
- expect(descriptionFieldEl.find(MarkdownField).props()).toMatchObject({
+ expect(descriptionFieldEl.findComponent(MarkdownField).exists()).toBe(true);
+ expect(descriptionFieldEl.findComponent(MarkdownField).props()).toMatchObject({
markdownPreviewPath: wrapper.vm.descriptionPreviewPath,
markdownDocsPath: wrapper.vm.descriptionHelpPath,
addSpacingClasses: false,
@@ -94,8 +94,8 @@ describe('IssuableForm', () => {
expect(labelsSelectEl.exists()).toBe(true);
expect(labelsSelectEl.find('label').text()).toBe('Labels');
- expect(labelsSelectEl.find(LabelsSelect).exists()).toBe(true);
- expect(labelsSelectEl.find(LabelsSelect).props()).toMatchObject({
+ expect(labelsSelectEl.findComponent(LabelsSelect).exists()).toBe(true);
+ expect(labelsSelectEl.findComponent(LabelsSelect).props()).toMatchObject({
allowLabelEdit: true,
allowLabelCreate: true,
allowMultiselect: true,
diff --git a/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js b/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js
index 80f14dffd08..f55d3156581 100644
--- a/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js
+++ b/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js
@@ -3,6 +3,7 @@ import { nextTick } from 'vue';
import { useFakeDate } from 'helpers/fake_date';
import { shallowMountExtended as shallowMount } from 'helpers/vue_test_utils_helper';
import IssuableItem from '~/vue_shared/issuable/list/components/issuable_item.vue';
+import WorkItemTypeIcon from '~/work_items/components/work_item_type_icon.vue';
import IssuableAssignees from '~/issuable/components/issue_assignees.vue';
import { mockIssuable, mockRegularLabel } from '../mock_data';
@@ -13,6 +14,7 @@ const createComponent = ({
issuable = mockIssuable,
showCheckbox = true,
slots = {},
+ showWorkItemTypeIcon = false,
} = {}) =>
shallowMount(IssuableItem, {
propsData: {
@@ -21,6 +23,7 @@ const createComponent = ({
issuable,
showDiscussions: true,
showCheckbox,
+ showWorkItemTypeIcon,
},
slots,
stubs: {
@@ -40,6 +43,7 @@ describe('IssuableItem', () => {
let wrapper;
const findTimestampWrapper = () => wrapper.find('[data-testid="issuable-timestamp"]');
+ const findWorkItemTypeIcon = () => wrapper.findComponent(WorkItemTypeIcon);
beforeEach(() => {
gon.gitlab_url = MOCK_GITLAB_URL;
@@ -273,9 +277,9 @@ describe('IssuableItem', () => {
const titleEl = wrapper.find('[data-testid="issuable-title"]');
expect(titleEl.exists()).toBe(true);
- expect(titleEl.find(GlLink).attributes('href')).toBe(expectedHref);
- expect(titleEl.find(GlLink).attributes('target')).toBe(expectedTarget);
- expect(titleEl.find(GlLink).text()).toBe(mockIssuable.title);
+ expect(titleEl.findComponent(GlLink).attributes('href')).toBe(expectedHref);
+ expect(titleEl.findComponent(GlLink).attributes('target')).toBe(expectedTarget);
+ expect(titleEl.findComponent(GlLink).text()).toBe(mockIssuable.title);
},
);
@@ -286,8 +290,8 @@ describe('IssuableItem', () => {
await nextTick();
- expect(wrapper.find(GlFormCheckbox).exists()).toBe(true);
- expect(wrapper.find(GlFormCheckbox).attributes('checked')).not.toBeDefined();
+ expect(wrapper.findComponent(GlFormCheckbox).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFormCheckbox).attributes('checked')).not.toBeDefined();
wrapper.setProps({
checked: true,
@@ -295,7 +299,7 @@ describe('IssuableItem', () => {
await nextTick();
- expect(wrapper.find(GlFormCheckbox).attributes('checked')).toBe('true');
+ expect(wrapper.findComponent(GlFormCheckbox).attributes('checked')).toBe('true');
});
it('renders issuable title with `target` set as "_blank" when issuable.webUrl is external', async () => {
@@ -308,9 +312,9 @@ describe('IssuableItem', () => {
await nextTick();
- expect(wrapper.find('[data-testid="issuable-title"]').find(GlLink).attributes('target')).toBe(
- '_blank',
- );
+ expect(
+ wrapper.find('[data-testid="issuable-title"]').findComponent(GlLink).attributes('target'),
+ ).toBe('_blank');
});
it('renders issuable confidential icon when issuable is confidential', async () => {
@@ -323,7 +327,7 @@ describe('IssuableItem', () => {
await nextTick();
- const confidentialEl = wrapper.find('[data-testid="issuable-title"]').find(GlIcon);
+ const confidentialEl = wrapper.find('[data-testid="issuable-title"]').findComponent(GlIcon);
expect(confidentialEl.exists()).toBe(true);
expect(confidentialEl.props('name')).toBe('eye-slash');
@@ -349,11 +353,23 @@ describe('IssuableItem', () => {
wrapper = createComponent();
const taskStatus = wrapper.find('[data-testid="task-status"]');
- const expected = `${mockIssuable.taskCompletionStatus.completedCount} of ${mockIssuable.taskCompletionStatus.count} tasks completed`;
+ const expected = `${mockIssuable.taskCompletionStatus.completedCount} of ${mockIssuable.taskCompletionStatus.count} checklist items completed`;
expect(taskStatus.text()).toBe(expected);
});
+ it('does not renders work item type icon by default', () => {
+ wrapper = createComponent();
+
+ expect(findWorkItemTypeIcon().exists()).toBe(false);
+ });
+
+ it('renders work item type icon when props passed', () => {
+ wrapper = createComponent({ showWorkItemTypeIcon: true });
+
+ expect(findWorkItemTypeIcon().props('workItemType')).toBe(mockIssuable.type);
+ });
+
it('renders issuable reference', () => {
wrapper = createComponent();
@@ -440,7 +456,7 @@ describe('IssuableItem', () => {
it('renders gl-label component for each label present within `issuable` prop', () => {
wrapper = createComponent();
- const labelsEl = wrapper.findAll(GlLabel);
+ const labelsEl = wrapper.findAllComponents(GlLabel);
expect(labelsEl.exists()).toBe(true);
expect(labelsEl).toHaveLength(mockLabels.length);
@@ -476,18 +492,18 @@ describe('IssuableItem', () => {
const discussionsEl = wrapper.find('[data-testid="issuable-discussions"]');
expect(discussionsEl.exists()).toBe(true);
- expect(discussionsEl.find(GlLink).attributes()).toMatchObject({
+ expect(discussionsEl.findComponent(GlLink).attributes()).toMatchObject({
title: 'Comments',
href: `${mockIssuable.webUrl}#notes`,
});
- expect(discussionsEl.find(GlIcon).props('name')).toBe('comments');
- expect(discussionsEl.find(GlLink).text()).toContain('2');
+ expect(discussionsEl.findComponent(GlIcon).props('name')).toBe('comments');
+ expect(discussionsEl.findComponent(GlLink).text()).toContain('2');
});
it('renders issuable-assignees component', () => {
wrapper = createComponent();
- const assigneesEl = wrapper.find(IssuableAssignees);
+ const assigneesEl = wrapper.findComponent(IssuableAssignees);
expect(assigneesEl.exists()).toBe(true);
expect(assigneesEl.props()).toMatchObject({
diff --git a/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js b/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js
index 50e79dbe589..0c53f599d55 100644
--- a/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js
+++ b/spec/frontend/vue_shared/issuable/list/components/issuable_list_root_spec.js
@@ -359,7 +359,7 @@ describe('IssuableListRoot', () => {
findIssuableTabs().vm.$emit('click');
- expect(wrapper.emitted('click-tab')).toBeTruthy();
+ expect(wrapper.emitted('click-tab')).toHaveLength(1);
});
it('sets all issuables as checked when filtered-search-bar component emits `checked-input` event', () => {
@@ -369,7 +369,7 @@ describe('IssuableListRoot', () => {
searchEl.vm.$emit('checked-input', true);
- expect(searchEl.emitted('checked-input')).toBeTruthy();
+ expect(searchEl.emitted('checked-input')).toHaveLength(1);
expect(searchEl.emitted('checked-input').length).toBe(1);
expect(wrapper.vm.checkedIssuables[mockIssuables[0].iid]).toEqual({
@@ -384,9 +384,9 @@ describe('IssuableListRoot', () => {
const searchEl = findFilteredSearchBar();
searchEl.vm.$emit('onFilter');
- expect(wrapper.emitted('filter')).toBeTruthy();
+ expect(wrapper.emitted('filter')).toHaveLength(1);
searchEl.vm.$emit('onSort');
- expect(wrapper.emitted('sort')).toBeTruthy();
+ expect(wrapper.emitted('sort')).toHaveLength(1);
});
it('sets an issuable as checked when issuable-item component emits `checked-input` event', () => {
@@ -396,7 +396,7 @@ describe('IssuableListRoot', () => {
issuableItem.vm.$emit('checked-input', true);
- expect(issuableItem.emitted('checked-input')).toBeTruthy();
+ expect(issuableItem.emitted('checked-input')).toHaveLength(1);
expect(issuableItem.emitted('checked-input').length).toBe(1);
expect(wrapper.vm.checkedIssuables[mockIssuables[0].iid]).toEqual({
@@ -425,7 +425,7 @@ describe('IssuableListRoot', () => {
wrapper = createComponent({ data, props: { showPaginationControls: true } });
findGlPagination().vm.$emit('input');
- expect(wrapper.emitted('page-change')).toBeTruthy();
+ expect(wrapper.emitted('page-change')).toHaveLength(1);
});
it.each`
diff --git a/spec/frontend/vue_shared/issuable/list/mock_data.js b/spec/frontend/vue_shared/issuable/list/mock_data.js
index 8640f4a2cd5..b67bd0f42fe 100644
--- a/spec/frontend/vue_shared/issuable/list/mock_data.js
+++ b/spec/frontend/vue_shared/issuable/list/mock_data.js
@@ -57,6 +57,7 @@ export const mockIssuable = {
count: 2,
completedCount: 1,
},
+ type: 'issue',
};
export const mockIssuables = [
diff --git a/spec/frontend/vue_shared/issuable/show/components/issuable_body_spec.js b/spec/frontend/vue_shared/issuable/show/components/issuable_body_spec.js
index 7c582360637..39a76a51191 100644
--- a/spec/frontend/vue_shared/issuable/show/components/issuable_body_spec.js
+++ b/spec/frontend/vue_shared/issuable/show/components/issuable_body_spec.js
@@ -154,7 +154,7 @@ describe('IssuableBody', () => {
describe('template', () => {
it('renders issuable-title component', () => {
- const titleEl = wrapper.find(IssuableTitle);
+ const titleEl = wrapper.findComponent(IssuableTitle);
expect(titleEl.exists()).toBe(true);
expect(titleEl.props()).toMatchObject({
@@ -165,7 +165,7 @@ describe('IssuableBody', () => {
});
it('renders issuable-description component', () => {
- const descriptionEl = wrapper.find(IssuableDescription);
+ const descriptionEl = wrapper.findComponent(IssuableDescription);
expect(descriptionEl.exists()).toBe(true);
expect(descriptionEl.props('issuable')).toEqual(issuableBodyProps.issuable);
@@ -184,7 +184,7 @@ describe('IssuableBody', () => {
await nextTick();
- const editFormEl = wrapper.find(IssuableEditForm);
+ const editFormEl = wrapper.findComponent(IssuableEditForm);
expect(editFormEl.exists()).toBe(true);
expect(editFormEl.props()).toMatchObject({
issuable: issuableBodyProps.issuable,
@@ -198,7 +198,7 @@ describe('IssuableBody', () => {
describe('events', () => {
it('component emits `edit-issuable` event bubbled via issuable-title', () => {
- const issuableTitle = wrapper.find(IssuableTitle);
+ const issuableTitle = wrapper.findComponent(IssuableTitle);
issuableTitle.vm.$emit('edit-issuable');
@@ -223,7 +223,7 @@ describe('IssuableBody', () => {
await nextTick();
- const issuableEditForm = wrapper.find(IssuableEditForm);
+ const issuableEditForm = wrapper.findComponent(IssuableEditForm);
issuableEditForm.vm.$emit(eventName, eventObj, issuableMeta);
diff --git a/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js b/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js
index d3e484cf913..d843da4da5b 100644
--- a/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js
+++ b/spec/frontend/vue_shared/issuable/show/components/issuable_edit_form_spec.js
@@ -124,7 +124,7 @@ describe('IssuableEditForm', () => {
const titleInputEl = wrapper.find('[data-testid="title"]');
expect(titleInputEl.exists()).toBe(true);
- expect(titleInputEl.find(GlFormInput).attributes()).toMatchObject({
+ expect(titleInputEl.findComponent(GlFormInput).attributes()).toMatchObject({
'aria-label': 'Title',
placeholder: 'Title',
});
@@ -134,7 +134,7 @@ describe('IssuableEditForm', () => {
const descriptionEl = wrapper.find('[data-testid="description"]');
expect(descriptionEl.exists()).toBe(true);
- expect(descriptionEl.find(MarkdownField).props()).toMatchObject({
+ expect(descriptionEl.findComponent(MarkdownField).props()).toMatchObject({
markdownPreviewPath: issuableEditFormProps.descriptionPreviewPath,
markdownDocsPath: issuableEditFormProps.descriptionHelpPath,
enableAutocomplete: issuableEditFormProps.enableAutocomplete,
@@ -161,7 +161,7 @@ describe('IssuableEditForm', () => {
};
it('component emits `keydown-title` event with event object and issuableMeta params via gl-form-input', async () => {
- const titleInputEl = wrapper.find(GlFormInput);
+ const titleInputEl = wrapper.findComponent(GlFormInput);
titleInputEl.vm.$emit('keydown', eventObj, 'title');
diff --git a/spec/frontend/vue_shared/issuable/show/components/issuable_header_spec.js b/spec/frontend/vue_shared/issuable/show/components/issuable_header_spec.js
index e00bb184535..6a8b9ef77a9 100644
--- a/spec/frontend/vue_shared/issuable/show/components/issuable_header_spec.js
+++ b/spec/frontend/vue_shared/issuable/show/components/issuable_header_spec.js
@@ -86,7 +86,7 @@ describe('IssuableHeader', () => {
const blockedEl = wrapper.findByTestId('blocked');
expect(blockedEl.exists()).toBe(true);
- expect(blockedEl.find(GlIcon).props('name')).toBe('lock');
+ expect(blockedEl.findComponent(GlIcon).props('name')).toBe('lock');
});
it('renders confidential icon when issuable is confidential', async () => {
@@ -97,7 +97,7 @@ describe('IssuableHeader', () => {
const confidentialEl = wrapper.findByTestId('confidential');
expect(confidentialEl.exists()).toBe(true);
- expect(confidentialEl.find(GlIcon).props('name')).toBe('eye-slash');
+ expect(confidentialEl.findComponent(GlIcon).props('name')).toBe('eye-slash');
});
it('renders issuable author avatar', () => {
@@ -113,19 +113,19 @@ describe('IssuableHeader', () => {
const avatarEl = wrapper.findByTestId('avatar');
expect(avatarEl.exists()).toBe(true);
expect(avatarEl.attributes()).toMatchObject(avatarElAttrs);
- expect(avatarEl.find(GlAvatarLabeled).attributes()).toMatchObject({
+ expect(avatarEl.findComponent(GlAvatarLabeled).attributes()).toMatchObject({
size: '24',
src: avatarUrl,
label: name,
});
- expect(avatarEl.find(GlAvatarLabeled).find(GlIcon).exists()).toBe(false);
+ expect(avatarEl.findComponent(GlAvatarLabeled).findComponent(GlIcon).exists()).toBe(false);
});
it('renders task status text when `taskCompletionStatus` prop is defined', () => {
createComponent();
expect(findTaskStatusEl().exists()).toBe(true);
- expect(findTaskStatusEl().text()).toContain('0 of 5 tasks completed');
+ expect(findTaskStatusEl().text()).toContain('0 of 5 checklist items completed');
});
it('does not render task status text when tasks count is 0', () => {
@@ -172,7 +172,7 @@ describe('IssuableHeader', () => {
);
const avatarEl = wrapper.findComponent(GlAvatarLabeled);
- const icon = avatarEl.find(GlIcon);
+ const icon = avatarEl.findComponent(GlIcon);
expect(icon.exists()).toBe(true);
expect(icon.props('name')).toBe('external-link');
diff --git a/spec/frontend/vue_shared/issuable/show/components/issuable_show_root_spec.js b/spec/frontend/vue_shared/issuable/show/components/issuable_show_root_spec.js
index f56064ed8e1..edfd55c8bb4 100644
--- a/spec/frontend/vue_shared/issuable/show/components/issuable_show_root_spec.js
+++ b/spec/frontend/vue_shared/issuable/show/components/issuable_show_root_spec.js
@@ -63,7 +63,7 @@ describe('IssuableShowRoot', () => {
});
it('renders issuable-header component', () => {
- const issuableHeader = wrapper.find(IssuableHeader);
+ const issuableHeader = wrapper.findComponent(IssuableHeader);
expect(issuableHeader.exists()).toBe(true);
expect(issuableHeader.props()).toMatchObject({
@@ -84,7 +84,7 @@ describe('IssuableShowRoot', () => {
});
it('renders issuable-body component', () => {
- const issuableBody = wrapper.find(IssuableBody);
+ const issuableBody = wrapper.findComponent(IssuableBody);
expect(issuableBody.exists()).toBe(true);
expect(issuableBody.props()).toMatchObject({
@@ -99,38 +99,38 @@ describe('IssuableShowRoot', () => {
});
it('renders issuable-sidebar component', () => {
- const issuableSidebar = wrapper.find(IssuableSidebar);
+ const issuableSidebar = wrapper.findComponent(IssuableSidebar);
expect(issuableSidebar.exists()).toBe(true);
});
describe('events', () => {
it('component emits `edit-issuable` event bubbled via issuable-body', () => {
- const issuableBody = wrapper.find(IssuableBody);
+ const issuableBody = wrapper.findComponent(IssuableBody);
issuableBody.vm.$emit('edit-issuable');
- expect(wrapper.emitted('edit-issuable')).toBeTruthy();
+ expect(wrapper.emitted('edit-issuable')).toHaveLength(1);
});
it('component emits `task-list-update-success` event bubbled via issuable-body', () => {
- const issuableBody = wrapper.find(IssuableBody);
+ const issuableBody = wrapper.findComponent(IssuableBody);
const eventParam = {
foo: 'bar',
};
issuableBody.vm.$emit('task-list-update-success', eventParam);
- expect(wrapper.emitted('task-list-update-success')).toBeTruthy();
+ expect(wrapper.emitted('task-list-update-success')).toHaveLength(1);
expect(wrapper.emitted('task-list-update-success')[0]).toEqual([eventParam]);
});
it('component emits `task-list-update-failure` event bubbled via issuable-body', () => {
- const issuableBody = wrapper.find(IssuableBody);
+ const issuableBody = wrapper.findComponent(IssuableBody);
issuableBody.vm.$emit('task-list-update-failure');
- expect(wrapper.emitted('task-list-update-failure')).toBeTruthy();
+ expect(wrapper.emitted('task-list-update-failure')).toHaveLength(1);
});
it.each(['keydown-title', 'keydown-description'])(
@@ -145,11 +145,11 @@ describe('IssuableShowRoot', () => {
issuableDescription: 'foobar',
};
- const issuableBody = wrapper.find(IssuableBody);
+ const issuableBody = wrapper.findComponent(IssuableBody);
issuableBody.vm.$emit(eventName, eventObj, issuableMeta);
- expect(wrapper.emitted(eventName)).toBeTruthy();
+ expect(wrapper.emitted()).toHaveProperty(eventName);
expect(wrapper.emitted(eventName)[0]).toMatchObject([eventObj, issuableMeta]);
},
);
diff --git a/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js b/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js
index 4b75da0b126..5f2b13a79c9 100644
--- a/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js
+++ b/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js
@@ -12,8 +12,8 @@ describe('SecurityReportDownloadDropdown component', () => {
});
};
- const findDropdown = () => wrapper.find(GlDropdown);
- const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
afterEach(() => {
wrapper.destroy();
diff --git a/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js b/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js
index 68a97103d3a..a9651cf8bac 100644
--- a/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js
+++ b/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js
@@ -70,8 +70,8 @@ describe('Security reports app', () => {
return createMockApollo(requestHandlers);
};
- const findDownloadDropdown = () => wrapper.find(SecurityReportDownloadDropdown);
- const findHelpIconComponent = () => wrapper.find(HelpIcon);
+ const findDownloadDropdown = () => wrapper.findComponent(SecurityReportDownloadDropdown);
+ const findHelpIconComponent = () => wrapper.findComponent(HelpIcon);
afterEach(() => {
wrapper.destroy();