summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--config/feature_flags/development/sandboxed_mermaid.yml2
-rw-r--r--db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb19
-rw-r--r--db/schema_migrations/202201241514561
-rw-r--r--db/structure.sql3
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md2
-rw-r--r--doc/api/commits.md4
-rw-r--r--doc/api/merge_request_approvals.md8
-rw-r--r--doc/api/merge_requests.md2
-rw-r--r--doc/api/notes.md2
-rw-r--r--doc/api/projects.md2
-rw-r--r--doc/api/users.md2
-rw-r--r--doc/api/visual_review_discussions.md2
-rw-r--r--doc/architecture/blueprints/consolidating_groups_and_projects/index.md2
-rw-r--r--doc/architecture/blueprints/database_testing/index.md4
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md2
-rw-r--r--doc/ci/index.md2
-rw-r--r--doc/ci/migration/jenkins.md2
-rw-r--r--doc/ci/pipelines/index.md8
-rw-r--r--doc/ci/pipelines/parent_child_pipelines.md2
-rw-r--r--doc/ci/troubleshooting.md6
-rw-r--r--doc/ci/unit_test_reports.md4
-rw-r--r--doc/development/cached_queries.md2
-rw-r--r--doc/development/code_review.md6
-rw-r--r--doc/development/database_review.md2
-rw-r--r--doc/development/dependencies.md2
-rw-r--r--doc/development/diffs.md4
-rw-r--r--doc/development/export_csv.md2
-rw-r--r--doc/development/feature_flags/index.md2
-rw-r--r--doc/development/features_inside_dot_gitlab.md2
-rw-r--r--doc/development/index.md2
-rw-r--r--doc/development/integrations/secure.md2
-rw-r--r--doc/development/issuable-like-models.md2
-rw-r--r--doc/development/issue_types.md2
-rw-r--r--doc/development/service_ping/metrics_dictionary.md2
-rw-r--r--doc/development/snowplow/index.md13
-rw-r--r--doc/integration/elasticsearch.md2
-rw-r--r--doc/integration/jenkins_deprecated.md2
-rw-r--r--doc/topics/git/merge_conflicts.md2
-rw-r--r--doc/user/admin_area/analytics/usage_trends.md2
-rw-r--r--doc/user/application_security/secret_detection/index.md4
-rw-r--r--doc/user/clusters/agent/index.md15
-rw-r--r--doc/user/clusters/agent/repository.md3
-rw-r--r--doc/user/index.md8
-rw-r--r--doc/user/infrastructure/iac/index.md4
-rw-r--r--doc/user/infrastructure/iac/mr_integration.md10
-rw-r--r--doc/user/project/settings/index.md4
-rw-r--r--doc/user/search/index.md6
-rw-r--r--lib/gitlab/database/gitlab_loose_foreign_keys.yml3
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb2
-rw-r--r--spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js8
-rw-r--r--spec/frontend/artifacts_settings/components/keep_latest_artifact_checkbox_spec.js7
-rw-r--r--spec/frontend/boards/board_list_helper.js9
-rw-r--r--spec/frontend/clusters_list/components/install_agent_modal_spec.js6
-rw-r--r--spec/frontend/design_management/pages/index_spec.js12
-rw-r--r--spec/frontend/diffs/components/collapsed_files_warning_spec.js4
-rw-r--r--spec/frontend/diffs/components/compare_versions_spec.js18
-rw-r--r--spec/frontend/diffs/components/diff_file_header_spec.js23
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js30
-rw-r--r--spec/frontend/diffs/components/diff_gutter_avatars_spec.js22
-rw-r--r--spec/frontend/diffs/components/tree_list_spec.js34
-rw-r--r--spec/frontend/environments/canary_update_modal_spec.js11
-rw-r--r--spec/frontend/environments/deploy_board_component_spec.js10
-rw-r--r--spec/frontend/environments/environment_actions_spec.js4
-rw-r--r--spec/frontend/environments/environment_table_spec.js3
-rw-r--r--spec/frontend/environments/environments_app_spec.js8
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js123
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_actions_spec.js24
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js37
-rw-r--r--spec/frontend/error_tracking_settings/components/app_spec.js7
-rw-r--r--spec/frontend/error_tracking_settings/components/project_dropdown_spec.js14
-rw-r--r--spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js7
-rw-r--r--spec/frontend/feature_flags/components/edit_feature_flag_spec.js14
-rw-r--r--spec/frontend/feature_flags/components/empty_state_spec.js3
-rw-r--r--spec/frontend/feature_flags/components/environments_dropdown_spec.js15
-rw-r--r--spec/frontend/feature_flags/components/feature_flags_spec.js4
-rw-r--r--spec/frontend/feature_flags/components/feature_flags_table_spec.js8
-rw-r--r--spec/frontend/feature_flags/components/form_spec.js21
-rw-r--r--spec/frontend/feature_flags/components/new_environments_dropdown_spec.js12
-rw-r--r--spec/frontend/feature_flags/components/new_feature_flag_spec.js13
-rw-r--r--spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js3
-rw-r--r--spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js6
-rw-r--r--spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js3
-rw-r--r--spec/frontend/feature_flags/components/strategy_spec.js134
-rw-r--r--spec/frontend/feature_highlight/feature_highlight_popover_spec.js3
-rw-r--r--spec/frontend/frequent_items/components/app_spec.js8
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_list_spec.js28
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_search_input_spec.js4
-rw-r--r--spec/frontend/grafana_integration/components/grafana_integration_spec.js22
-rw-r--r--spec/frontend/group_settings/components/shared_runners_form_spec.js3
-rw-r--r--spec/frontend/groups/components/invite_members_banner_spec.js3
-rw-r--r--spec/frontend/header_search/components/app_spec.js14
-rw-r--r--spec/frontend/header_search/components/header_search_autocomplete_items_spec.js4
-rw-r--r--spec/frontend/ide/components/branches/search_list_spec.js9
-rw-r--r--spec/frontend/ide/components/commit_sidebar/form_spec.js42
-rw-r--r--spec/frontend/ide/components/error_message_spec.js33
-rw-r--r--spec/frontend/ide/components/file_templates/dropdown_spec.js31
-rw-r--r--spec/frontend/ide/components/ide_file_row_spec.js27
-rw-r--r--spec/frontend/ide/components/ide_review_spec.js10
-rw-r--r--spec/frontend/ide/components/ide_side_bar_spec.js14
-rw-r--r--spec/frontend/ide/components/jobs/stage_spec.js15
-rw-r--r--spec/frontend/ide/components/merge_requests/list_spec.js70
-rw-r--r--spec/frontend/ide/components/panes/right_spec.js23
-rw-r--r--spec/frontend/ide/components/preview/clientside_spec.js27
-rw-r--r--spec/frontend/ide/components/preview/navigator_spec.js120
-rw-r--r--spec/frontend/ide/components/repo_tabs_spec.js17
-rw-r--r--spec/frontend/ide/components/resizable_panel_spec.js9
-rw-r--r--spec/frontend/ide/components/terminal/session_spec.js20
-rw-r--r--spec/frontend/ide/components/terminal/terminal_controls_spec.js15
-rw-r--r--spec/frontend/incidents/components/incidents_list_spec.js11
-rw-r--r--spec/frontend/integrations/edit/components/active_checkbox_spec.js3
-rw-r--r--spec/frontend/integrations/edit/components/confirmation_modal_spec.js3
-rw-r--r--spec/frontend/integrations/edit/components/jira_issues_fields_spec.js3
-rw-r--r--spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js19
-rw-r--r--spec/frontend/invite_members/components/import_a_project_modal_spec.js5
-rw-r--r--spec/frontend/invite_members/components/invite_members_modal_spec.js7
-rw-r--r--spec/frontend/issuable/components/related_issuable_item_spec.js9
-rw-r--r--spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js47
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_root_spec.js30
-rw-r--r--spec/frontend/issues/list/components/new_issue_dropdown_spec.js7
-rw-r--r--spec/frontend/issues/new/components/title_suggestions_spec.js57
-rw-r--r--spec/frontend/issues/show/components/app_spec.js165
-rw-r--r--spec/frontend/issues/show/components/fields/type_spec.js9
-rw-r--r--spec/frontend/issues/show/components/form_spec.js3
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js4
-rw-r--r--spec/frontend/jira_connect/branches/components/new_branch_form_spec.js8
-rw-r--r--spec/frontend/jira_connect/branches/components/project_dropdown_spec.js10
-rw-r--r--spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js8
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js3
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js7
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/app_spec.js9
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js3
-rw-r--r--spec/frontend/jobs/bridge/app_spec.js10
-rw-r--r--spec/frontend/jobs/components/job_app_spec.js14
-rw-r--r--spec/frontend/jobs/components/job_container_item_spec.js3
-rw-r--r--spec/frontend/jobs/components/job_log_controllers_spec.js9
-rw-r--r--spec/frontend/jobs/components/log/collapsible_section_spec.js8
-rw-r--r--spec/frontend/jobs/components/log/line_header_spec.js8
-rw-r--r--spec/frontend/jobs/components/sidebar_spec.js3
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js9
-rw-r--r--spec/frontend/jobs/mixins/delayed_job_mixin_spec.js11
-rw-r--r--spec/frontend/logs/components/environment_logs_spec.js22
-rw-r--r--spec/frontend/logs/components/log_control_buttons_spec.js31
-rw-r--r--spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js6
-rw-r--r--spec/frontend/monitoring/components/charts/stacked_column_spec.js25
-rw-r--r--spec/frontend/monitoring/components/charts/time_series_spec.js142
-rw-r--r--spec/frontend/monitoring/components/create_dashboard_modal_spec.js10
-rw-r--r--spec/frontend/monitoring/components/dashboard_actions_menu_spec.js100
-rw-r--r--spec/frontend/monitoring/components/dashboard_header_spec.js143
-rw-r--r--spec/frontend/monitoring/components/dashboard_panel_builder_spec.js67
-rw-r--r--spec/frontend/monitoring/components/dashboard_panel_spec.js137
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js341
-rw-r--r--spec/frontend/monitoring/components/dashboard_url_time_spec.js101
-rw-r--r--spec/frontend/monitoring/components/embeds/embed_group_spec.js10
-rw-r--r--spec/frontend/monitoring/components/graph_group_spec.js35
-rw-r--r--spec/frontend/monitoring/components/links_section_spec.js20
-rw-r--r--spec/frontend/monitoring/components/refresh_button_spec.js13
-rw-r--r--spec/frontend/monitoring/components/variables/dropdown_field_spec.js8
-rw-r--r--spec/frontend/monitoring/components/variables/text_field_spec.js22
-rw-r--r--spec/frontend/monitoring/components/variables_section_spec.js39
-rw-r--r--spec/frontend/mr_popover/mr_popover_spec.js29
-rw-r--r--spec/frontend/nav/components/responsive_app_spec.js5
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js12
-rw-r--r--spec/frontend/notes/components/diff_discussion_header_spec.js63
-rw-r--r--spec/frontend/notes/components/discussion_counter_spec.js20
-rw-r--r--spec/frontend/notes/components/discussion_filter_spec.js50
-rw-r--r--spec/frontend/notes/components/discussion_notes_spec.js29
-rw-r--r--spec/frontend/notes/components/discussion_resolve_button_spec.js17
-rw-r--r--spec/frontend/notes/components/noteable_note_spec.js24
-rw-r--r--spec/frontend/notes/components/timeline_toggle_spec.js10
-rw-r--r--spec/frontend/notes/mixins/discussion_navigation_spec.js19
-rw-r--r--spec/frontend/notifications/components/custom_notifications_modal_spec.js7
-rw-r--r--spec/frontend/operation_settings/components/metrics_settings_spec.js21
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js5
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js5
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js10
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js10
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/app_spec.js7
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js18
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js3
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js7
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/details_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/list_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js7
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js10
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js15
-rw-r--r--spec/frontend/pages/admin/projects/components/namespace_select_spec.js7
-rw-r--r--spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js7
-rw-r--r--spec/frontend/pages/projects/forks/new/components/fork_form_spec.js11
-rw-r--r--spec/frontend/pages/projects/graphs/code_coverage_spec.js5
-rw-r--r--spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js13
-rw-r--r--spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js7
-rw-r--r--spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js33
-rw-r--r--spec/frontend/pages/shared/wikis/components/wiki_form_spec.js6
-rw-r--r--spec/frontend/performance_bar/components/add_request_spec.js25
-rw-r--r--spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js7
-rw-r--r--spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js7
-rw-r--r--spec/frontend/pipeline_editor/components/header/validation_segment_spec.js7
-rw-r--r--spec/frontend/pipeline_new/components/pipeline_new_form_spec.js13
-rw-r--r--spec/frontend/pipelines/components/dag/dag_annotations_spec.js19
-rw-r--r--spec/frontend/pipelines/components/dag/dag_spec.js9
-rw-r--r--spec/frontend/pipelines/components/jobs/jobs_app_spec.js7
-rw-r--r--spec/frontend/pipelines/components/pipelines_filtered_search_spec.js37
-rw-r--r--spec/frontend/pipelines/graph/action_component_spec.js20
-rw-r--r--spec/frontend/pipelines/graph/job_item_spec.js18
-rw-r--r--spec/frontend/pipelines/graph/linked_pipelines_column_spec.js9
-rw-r--r--spec/frontend/pipelines/pipeline_triggerer_spec.js8
-rw-r--r--spec/frontend/pipelines/pipelines_actions_spec.js5
-rw-r--r--spec/frontend/popovers/components/popovers_spec.js15
-rw-r--r--spec/frontend/profile/account/components/update_username_spec.js11
-rw-r--r--spec/frontend/projects/commit/components/branches_dropdown_spec.js4
-rw-r--r--spec/frontend/projects/commit/components/form_modal_spec.js7
-rw-r--r--spec/frontend/projects/commits/components/author_select_spec.js55
-rw-r--r--spec/frontend/projects/compare/components/app_spec.js7
-rw-r--r--spec/frontend/projects/compare/components/repo_dropdown_spec.js7
-rw-r--r--spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js3
-rw-r--r--spec/frontend/projects/compare/components/revision_dropdown_spec.js3
-rw-r--r--spec/frontend/projects/new/components/new_project_url_select_spec.js4
-rw-r--r--spec/frontend/projects/pipelines/charts/components/app_spec.js7
-rw-r--r--spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js7
-rw-r--r--spec/frontend/projects/settings/components/shared_runners_toggle_spec.js3
-rw-r--r--spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js2
-rw-r--r--spec/frontend/ref/components/ref_selector_spec.js34
-rw-r--r--spec/frontend/related_issues/components/related_issuable_input_spec.js3
-rw-r--r--spec/frontend/releases/components/app_edit_new_spec.js3
-rw-r--r--spec/frontend/releases/components/app_index_apollo_client_spec.js10
-rw-r--r--spec/frontend/releases/components/evidence_block_spec.js8
-rw-r--r--spec/frontend/releases/components/release_block_footer_spec.js5
-rw-r--r--spec/frontend/releases/components/release_block_milestone_info_spec.js30
-rw-r--r--spec/frontend/releases/components/release_block_spec.js5
-rw-r--r--spec/frontend/releases/components/tag_field_new_spec.js4
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js9
-rw-r--r--spec/frontend/repository/components/blob_controls_spec.js9
-rw-r--r--spec/frontend/repository/components/breadcrumbs_spec.js9
-rw-r--r--spec/frontend/repository/components/upload_blob_modal_spec.js5
-rw-r--r--spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js7
-rw-r--r--spec/frontend/runner/components/registration/registration_dropdown_spec.js39
-rw-r--r--spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js7
-rw-r--r--spec/frontend/runner/group_runners/group_runners_app_spec.js1
-rw-r--r--spec/frontend/serverless/survey_banner_spec.js10
-rw-r--r--spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js19
-rw-r--r--spec/frontend/sidebar/assignees_realtime_spec.js7
-rw-r--r--spec/frontend/sidebar/assignees_spec.js8
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js9
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js11
-rw-r--r--spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js5
-rw-r--r--spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js9
-rw-r--r--spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js17
-rw-r--r--spec/frontend/sidebar/components/time_tracking/report_spec.js7
-rw-r--r--spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js15
-rw-r--r--spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js4
-rw-r--r--spec/frontend/sidebar/lock/edit_form_buttons_spec.js25
-rw-r--r--spec/frontend/sidebar/lock/issuable_lock_form_spec.js22
-rw-r--r--spec/frontend/sidebar/sidebar_assignees_spec.js8
-rw-r--r--spec/frontend/sidebar/todo_spec.js8
-rw-r--r--spec/frontend/snippets/components/edit_spec.js9
-rw-r--r--spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js3
-rw-r--r--spec/frontend/snippets/components/snippet_header_spec.js25
-rw-r--r--spec/frontend/static_site_editor/components/edit_meta_controls_spec.js5
-rw-r--r--spec/frontend/static_site_editor/components/edit_meta_modal_spec.js15
-rw-r--r--spec/frontend/static_site_editor/pages/home_spec.js23
-rw-r--r--spec/frontend/terraform/components/states_table_actions_spec.js11
-rw-r--r--spec/frontend/terraform/components/states_table_spec.js5
-rw-r--r--spec/frontend/terraform/components/terraform_list_spec.js7
-rw-r--r--spec/frontend/token_access/token_access_spec.js6
-rw-r--r--spec/frontend/tooltips/components/tooltips_spec.js35
-rw-r--r--spec/frontend/user_lists/components/add_user_modal_spec.js5
-rw-r--r--spec/frontend/user_lists/components/edit_user_list_spec.js12
-rw-r--r--spec/frontend/user_lists/components/new_user_list_spec.js8
-rw-r--r--spec/frontend/user_lists/components/user_list_spec.js22
-rw-r--r--spec/frontend/user_lists/components/user_lists_table_spec.js28
-rw-r--r--spec/frontend/whats_new/components/app_spec.js6
-rw-r--r--spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb1
-rw-r--r--spec/models/ci/trigger_spec.rb7
280 files changed, 2212 insertions, 2477 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d3ecbdcc1f6..8e758c669db 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -273,7 +273,7 @@ class ApplicationController < ActionController::Base
end
def default_headers
- headers['X-Frame-Options'] = 'DENY'
+ headers['X-Frame-Options'] = 'SAMEORIGIN'
headers['X-XSS-Protection'] = '1; mode=block'
headers['X-UA-Compatible'] = 'IE=edge'
headers['X-Content-Type-Options'] = 'nosniff'
diff --git a/config/feature_flags/development/sandboxed_mermaid.yml b/config/feature_flags/development/sandboxed_mermaid.yml
index a008a9fad38..434cd4055d8 100644
--- a/config/feature_flags/development/sandboxed_mermaid.yml
+++ b/config/feature_flags/development/sandboxed_mermaid.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349755
milestone: '14.7'
type: development
group: group::analyzer frontend
-default_enabled: false
+default_enabled: true
diff --git a/db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb b/db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb
new file mode 100644
index 00000000000..684d363eb96
--- /dev/null
+++ b/db/post_migrate/20220124151456_remove_projects_ci_triggers_project_id_fk.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveProjectsCiTriggersProjectIdFk < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ return unless foreign_key_exists?(:ci_triggers, :projects, name: "fk_e3e63f966e")
+
+ with_lock_retries do
+ execute('LOCK projects, ci_triggers IN ACCESS EXCLUSIVE MODE') if transaction_open?
+
+ remove_foreign_key_if_exists(:ci_triggers, :projects, name: "fk_e3e63f966e")
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(:ci_triggers, :projects, name: "fk_e3e63f966e", column: :project_id, target_column: :id, on_delete: :cascade)
+ end
+end
diff --git a/db/schema_migrations/20220124151456 b/db/schema_migrations/20220124151456
new file mode 100644
index 00000000000..10a7b978e2f
--- /dev/null
+++ b/db/schema_migrations/20220124151456
@@ -0,0 +1 @@
+5ec73b28adb027a4462ec9b268ef9c505e281f1afedce3c592d431cd90808dac \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index a4ad87093a8..0c1cf010705 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -29906,9 +29906,6 @@ ALTER TABLE ONLY ci_builds_metadata
ALTER TABLE ONLY gitlab_subscriptions
ADD CONSTRAINT fk_e2595d00a1 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_triggers
- ADD CONSTRAINT fk_e3e63f966e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY merge_requests
ADD CONSTRAINT fk_e719a85f8a FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE SET NULL;
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index 33a81c12811..0dd931eb506 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -818,7 +818,7 @@ conflicting_permanent_redirects = RedirectRoute.matching_path_and_descendants(pa
conflicting_permanent_redirects.destroy_all
```
-## Merge Requests
+## Merge requests
### Close a merge request properly (if merged but still marked as open)
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 6347af451a2..133f9495d03 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -740,9 +740,9 @@ Example response:
}
```
-## List Merge Requests associated with a commit
+## List merge requests associated with a commit
-Get a list of Merge Requests related to the specified commit.
+Get a list of merge requests related to the specified commit.
```plaintext
GET /projects/:id/repository/commits/:sha/merge_requests
diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md
index b6021d494fd..ec3f2f61bde 100644
--- a/doc/api/merge_request_approvals.md
+++ b/doc/api/merge_request_approvals.md
@@ -527,9 +527,9 @@ DELETE /projects/:id/approval_rules/:approval_rule_id
| `id` | integer or string | yes | The ID or [URL-encoded path of a project](index.md#namespaced-path-encoding) |
| `approval_rule_id` | integer | yes | The ID of a approval rule
-## Merge Request-level MR approvals
+## Merge request-level MR approvals
-Configuration for approvals on a specific Merge Request. Must be authenticated for all endpoints.
+Configuration for approvals on a specific merge request. Must be authenticated for all endpoints.
### Get Configuration
@@ -957,7 +957,7 @@ These are system generated rules.
| `merge_request_iid` | integer | yes | The IID of the merge request |
| `approval_rule_id` | integer | yes | The ID of an approval rule |
-## Approve Merge Request
+## Approve merge request
> Moved to GitLab Premium in 13.9.
@@ -1020,7 +1020,7 @@ does not match, the response code is `409`.
}
```
-## Unapprove Merge Request
+## Unapprove merge request
> Moved to GitLab Premium in 13.9.
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 82db3b0a2fd..5189811b539 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -2686,7 +2686,7 @@ Example response:
## Approvals
-For approvals, see [Merge Request Approvals](merge_request_approvals.md)
+For approvals, see [Merge request approvals](merge_request_approvals.md)
## List merge request state events
diff --git a/doc/api/notes.md b/doc/api/notes.md
index 879ffaca191..445940e02fc 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -320,7 +320,7 @@ Parameters:
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/snippets/52/notes/1659"
```
-## Merge Requests
+## Merge requests
### List all merge request notes
diff --git a/doc/api/projects.md b/doc/api/projects.md
index b445d144315..c3f9e2aa38b 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1449,7 +1449,7 @@ Supported attributes:
| `wiki_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `wiki_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable wiki for this project. Use `wiki_access_level` instead. |
| `issues_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for Issues. Description is parsed with GitLab Flavored Markdown. See [Templates for issues and merge requests](#templates-for-issues-and-merge-requests). |
-| `merge_requests_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for Merge Requests. Description is parsed with GitLab Flavored Markdown. See [Templates for issues and merge requests](#templates-for-issues-and-merge-requests). |
+| `merge_requests_template` **(PREMIUM)** | string | **{dotted-circle}** No | Default description for merge requests. Description is parsed with GitLab Flavored Markdown. See [Templates for issues and merge requests](#templates-for-issues-and-merge-requests). |
| `keep_latest_artifact` | boolean | **{dotted-circle}** No | Disable or enable the ability to keep the latest artifact for this project. |
| `mr_default_target_self` | boolean | **{dotted-circle}** No | For forked projects, target merge requests to this project. If `false`, the target will be the upstream project. |
diff --git a/doc/api/users.md b/doc/api/users.md
index f78de621de2..0dd1d416502 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -1838,7 +1838,7 @@ The activities that update the timestamp are:
- Git HTTP/SSH activities (such as clone, push)
- User logging in to GitLab
-- User visiting pages related to Dashboards, Projects, Issues, and Merge Requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54947) in GitLab 11.8)
+- User visiting pages related to dashboards, projects, issues, and merge requests ([introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/54947) in GitLab 11.8)
- User using the API
- User using the GraphQL API
diff --git a/doc/api/visual_review_discussions.md b/doc/api/visual_review_discussions.md
index 8457f63fd38..5b7aec3785b 100644
--- a/doc/api/visual_review_discussions.md
+++ b/doc/api/visual_review_discussions.md
@@ -10,7 +10,7 @@ type: reference, api
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18710) in GitLab 12.5.
> - [Moved](https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model/) to GitLab Premium in 13.9.
-Visual Review discussions are notes on Merge Requests sent as
+Visual Review discussions are notes on merge requests sent as
feedback from [Visual Reviews](../ci/review_apps/index.md#visual-reviews).
## Create new merge request thread
diff --git a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
index 345160dc77f..6040ac1e50f 100644
--- a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
+++ b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
@@ -131,7 +131,7 @@ epic.
The initial iteration will provide a framework to house features under `Namespaces`. Stage groups will eventually need to migrate their own features and functionality over to `Namespaces`. This may impact these features in unexpected ways. Therefore, to minimize UX debt and maintain product consistency, stage groups will have to consider a number of factors when migrating their features over to `Namespaces`:
-1. **Conceptual model**: What are the current and future state conceptual models of these features ([see object modeling for designers](https://hpadkisson.medium.com/object-modeling-for-designers-an-introduction-7871bdcf8baf))? These should be documented in Pajamas (example: [Merge Requests](https://design.gitlab.com/objects/merge-request)).
+1. **Conceptual model**: What are the current and future state conceptual models of these features ([see object modeling for designers](https://hpadkisson.medium.com/object-modeling-for-designers-an-introduction-7871bdcf8baf))? These should be documented in Pajamas (example: [merge requests](https://design.gitlab.com/objects/merge-request)).
1. **Merge conflicts**: What inconsistencies are there across project, group, and admin levels? How might these be addressed? For an example of how we rationalized this for labels, please see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/338820).
1. **Inheritance & information flow**: How is information inherited across our container hierarchy currently? How might this be impacted if complying with the new [inheritance behavior](https://gitlab.com/gitlab-org/gitlab/-/issues/343316) framework?
1. **Settings**: Where can settings for this feature be found currently? How will these be impacted by `Namespaces`?
diff --git a/doc/architecture/blueprints/database_testing/index.md b/doc/architecture/blueprints/database_testing/index.md
index 4676caab85d..8c0cb550d61 100644
--- a/doc/architecture/blueprints/database_testing/index.md
+++ b/doc/architecture/blueprints/database_testing/index.md
@@ -100,7 +100,7 @@ The short-term goal is detailed in [this epic](https://gitlab.com/groups/gitlab-
### Mid-term - Improved feedback, query testing and background migration testing
-Mid-term, we plan to expand the level of detail the testing pipeline reports back to the Merge Request and expand its scope to cover query testing, too. By doing so, we use our experience from database code reviews and using thin-clone technology and bring this back closer to the GitLab workflow. Instead of reaching out to different tools (`postgres.ai`, `joe`, Slack, plan visualizations, and so on) we bring this back to GitLab and working directly on the Merge Request.
+Mid-term, we plan to expand the level of detail the testing pipeline reports back to the merge requet and expand its scope to cover query testing, too. By doing so, we use our experience from database code reviews and using thin-clone technology and bring this back closer to the GitLab workflow. Instead of reaching out to different tools (`postgres.ai`, `joe`, Slack, plan visualizations, and so on) we bring this back to GitLab and working directly on the merge request.
Secondly, we plan to cover background migrations testing, too. These are typically data migrations that are scheduled to run over a long period of time. The success of both the scheduling phase and the job execution phase typically depends a lot on data distribution - which only surfaces when running these migrations on actual production data. In order to become confident about a background migration, we plan to provide the following feedback:
@@ -109,7 +109,7 @@ Secondly, we plan to cover background migrations testing, too. These are typical
### Long-term - incorporate into GitLab product
-There are opportunities to discuss for extracting features from this into GitLab itself. For example, annotating the Merge Request with query examples and attaching feedback gathered from the testing run can become a first-class citizen instead of using Merge Request description and comments for it. We plan to evaluate those ideas as we see those being used in earlier phases and bring our experience back into the product.
+There are opportunities to discuss for extracting features from this into GitLab itself. For example, annotating the merge request with query examples and attaching feedback gathered from the testing run can become a first-class citizen instead of using merge request description and comments for it. We plan to evaluate those ideas as we see those being used in earlier phases and bring our experience back into the product.
## An alternative discussed: Anonymization
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index be33e62b75c..6dbec0dfc8b 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -378,7 +378,7 @@ Now, we would need to deploy our app by running `envoy run deploy`, but it won't
Now it's time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `main` branch.
To keep things simple, we commit directly to `main`, without using [feature-branches](../../../topics/gitlab_flow.md#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial.
-In a real world project, teams may use [Issue Tracker](../../../user/project/issues/index.md) and [Merge Requests](../../../user/project/merge_requests/index.md) to move their code across branches:
+In a real world project, teams may use [Issue Tracker](../../../user/project/issues/index.md) and [merge requests](../../../user/project/merge_requests/index.md) to move their code across branches:
```shell
git add Envoy.blade.php
diff --git a/doc/ci/index.md b/doc/ci/index.md
index c557e9e6f57..27122a99d29 100644
--- a/doc/ci/index.md
+++ b/doc/ci/index.md
@@ -64,7 +64,7 @@ GitLab CI/CD supports numerous configuration options:
| [Git submodules for CI/CD](git_submodules.md) | Configure jobs for using Git submodules. |
| [SSH keys for CI/CD](ssh_keys/index.md) | Using SSH keys in your CI pipelines. |
| [Pipeline triggers](triggers/index.md) | Trigger pipelines through the API. |
-| [Pipelines for Merge Requests](pipelines/merge_request_pipelines.md) | Design a pipeline structure for running a pipeline in merge requests. |
+| [Pipelines for merge requests](pipelines/merge_request_pipelines.md) | Design a pipeline structure for running a pipeline in merge requests. |
| [Integrate with Kubernetes clusters](../user/infrastructure/clusters/index.md) | Connect your project to Google Kubernetes Engine (GKE) or an existing Kubernetes cluster. |
| [Optimize GitLab and GitLab Runner for large repositories](large_repositories/index.md) | Recommended strategies for handling large repositories. |
| [`.gitlab-ci.yml` full reference](yaml/index.md) | All the attributes you can use with GitLab CI/CD. |
diff --git a/doc/ci/migration/jenkins.md b/doc/ci/migration/jenkins.md
index ef6f28e36e5..bfa2eb54806 100644
--- a/doc/ci/migration/jenkins.md
+++ b/doc/ci/migration/jenkins.md
@@ -196,7 +196,7 @@ can leverage. You can see the complete list of packaging features in the
Where you may have used plugins to get things like code quality, unit tests, security scanning, and so on working in Jenkins,
GitLab takes advantage of our connected ecosystem to automatically pull these kinds of results into
-your Merge Requests, pipeline details pages, and other locations. You may find that you actually don't
+your merge requests, pipeline details pages, and other locations. You may find that you actually don't
need to configure anything to have these appear.
If they aren't working as expected, or if you'd like to see what's available, our [CI feature index](../index.md#gitlab-cicd-features) has the full list
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index b873b2ae30f..5405c8317cb 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -50,14 +50,14 @@ Pipelines can be configured in many different ways:
followed by the next stage.
- [Directed Acyclic Graph Pipeline (DAG) pipelines](../directed_acyclic_graph/index.md) are based on relationships
between jobs and can run more quickly than basic pipelines.
-- [Pipelines for Merge Requests](../pipelines/merge_request_pipelines.md) run for merge
+- [Pipelines for merge requests](../pipelines/merge_request_pipelines.md) run for merge
requests only (rather than for every commit).
-- [Pipelines for Merged Results](../pipelines/pipelines_for_merged_results.md)
+- [Pipelines for merged results](../pipelines/pipelines_for_merged_results.md)
are merge request pipelines that act as though the changes from the source branch have
already been merged into the target branch.
-- [Merge Trains](../pipelines/merge_trains.md)
+- [Merge trains](../pipelines/merge_trains.md)
use pipelines for merged results to queue merges one after the other.
-- [Parent-Child pipelines](parent_child_pipelines.md) break down complex pipelines
+- [Parent-child pipelines](parent_child_pipelines.md) break down complex pipelines
into one parent pipeline that can trigger multiple child sub-pipelines, which all
run in the same project and with the same SHA. This pipeline architecture is commonly used for mono-repos.
- [Multi-project pipelines](multi_project_pipelines.md) combine pipelines for different projects together.
diff --git a/doc/ci/pipelines/parent_child_pipelines.md b/doc/ci/pipelines/parent_child_pipelines.md
index 5e4b707a38c..a3ded24e8c9 100644
--- a/doc/ci/pipelines/parent_child_pipelines.md
+++ b/doc/ci/pipelines/parent_child_pipelines.md
@@ -100,7 +100,7 @@ microservice_a:
## Merge request child pipelines
-To trigger a child pipeline as a [Merge Request Pipeline](merge_request_pipelines.md) we need to:
+To trigger a child pipeline as a [merge request pipeline](merge_request_pipelines.md) we need to:
- Set the trigger job to run on merge requests:
diff --git a/doc/ci/troubleshooting.md b/doc/ci/troubleshooting.md
index 4d550f6da13..7465f079ce7 100644
--- a/doc/ci/troubleshooting.md
+++ b/doc/ci/troubleshooting.md
@@ -69,11 +69,11 @@ if you are using that type:
and run separate pipelines in the same project. You can also
[dynamically generate the child pipeline's configuration](pipelines/parent_child_pipelines.md#dynamic-child-pipelines)
at runtime.
-- [Pipelines for Merge Requests](pipelines/merge_request_pipelines.md): Run a pipeline
+- [Pipelines for merge requests](pipelines/merge_request_pipelines.md): Run a pipeline
in the context of a merge request.
- - [Pipelines for Merge Results](pipelines/pipelines_for_merged_results.md):
+ - [Pipelines for merge results](pipelines/pipelines_for_merged_results.md):
Pipelines for merge requests that run on the combined source and target branch
- - [Merge Trains](pipelines/merge_trains.md):
+ - [Merge trains](pipelines/merge_trains.md):
Multiple pipelines for merged results that queue and run automatically before
changes are merged.
diff --git a/doc/ci/unit_test_reports.md b/doc/ci/unit_test_reports.md
index 55fd8c1eb49..c2b285bb017 100644
--- a/doc/ci/unit_test_reports.md
+++ b/doc/ci/unit_test_reports.md
@@ -21,7 +21,7 @@ report on the merge request so that it's easier and faster to identify the
failure without having to check the entire log. Unit test reports currently
only support test reports in the JUnit report format.
-If you don't use Merge Requests but still want to see the unit test report
+If you don't use merge requests but still want to see the unit test report
output without searching through job logs, the full
[Unit test reports](#viewing-unit-test-reports-on-gitlab) are available
in the pipeline detail view.
@@ -67,7 +67,7 @@ execution time and the error output.
### Number of recent failures
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241759) in Merge Requests in GitLab 13.7.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241759) in merge requests in GitLab 13.7.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268249) in GitLab 13.8.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235525) in Test Reports in GitLab 13.9.
diff --git a/doc/development/cached_queries.md b/doc/development/cached_queries.md
index 4f82d721164..492c8d13600 100644
--- a/doc/development/cached_queries.md
+++ b/doc/development/cached_queries.md
@@ -163,5 +163,5 @@ factors help improve the overall execution time:
## For more information
- [Metrics that would help us detect the potential N+1 Cached SQL calls](https://gitlab.com/gitlab-org/gitlab/-/issues/259007)
-- [Merge Request performance guidelines for cached queries](merge_request_performance_guidelines.md#cached-queries)
+- [Merge request performance guidelines for cached queries](merge_request_performance_guidelines.md#cached-queries)
- [Improvements for biggest offenders](https://gitlab.com/groups/gitlab-org/-/epics/4508)
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index 473fa14ce20..51460dea86d 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -285,7 +285,7 @@ Maintainers should check before merging if the merge request is approved by the
required approvers. If still awaiting further approvals from others, remove yourself as a reviewer then `@` mention the author and explain why in a comment. Stay as reviewer if you're merging the code.
Maintainers must check before merging if the merge request is introducing new
-vulnerabilities, by inspecting the list in the Merge Request
+vulnerabilities, by inspecting the list in the merge request
[Security Widget](../user/application_security/index.md).
When in doubt, a [Security Engineer](https://about.gitlab.com/company/team/) can be involved. The list of detected
vulnerabilities must be either empty or containing:
@@ -296,8 +296,8 @@ vulnerabilities must be either empty or containing:
Maintainers should **never** dismiss vulnerabilities to "empty" the list,
without duly verifying them.
-Note that certain Merge Requests may target a stable branch. These are rare
-events. These types of Merge Requests cannot be merged by the Maintainer.
+Note that certain merge requests may target a stable branch. These are rare
+events. These types of merge requests cannot be merged by the Maintainer.
Instead, these should be sent to the [Release Manager](https://about.gitlab.com/community/release-managers/).
After merging, a maintainer should stay as the reviewer listed on the merge request.
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index f968865114b..8e217725a17 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -66,7 +66,7 @@ Refer to [Preparation when adding or modifying queries](#preparation-when-adding
### Roles and process
-A Merge Request **author**'s role is to:
+A merge request **author**'s role is to:
- Decide whether a database review is needed.
- If database review is needed, add the ~database label.
diff --git a/doc/development/dependencies.md b/doc/development/dependencies.md
index c81c6408211..329539f0cc2 100644
--- a/doc/development/dependencies.md
+++ b/doc/development/dependencies.md
@@ -51,6 +51,6 @@ This has certain benefits as outlined in our <a href="https://docs.gitlab.com/ee
You might find that we do not currently update DEPENDENCY automatically, but we are planning to do so in [the near future](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/21).
-Thank you for understanding, I will close this Merge Request.
+Thank you for understanding, I will close this merge request.
/close
```
diff --git a/doc/development/diffs.md b/doc/development/diffs.md
index aaa3340af33..d61de740f15 100644
--- a/doc/development/diffs.md
+++ b/doc/development/diffs.md
@@ -35,7 +35,7 @@ have changed since then, it should still serve as a good introduction.
### Merge request diffs
-When refreshing a Merge Request (pushing to a source branch, force-pushing to target branch, or if the target branch now contains any commits from the MR)
+When refreshing a merge request (pushing to a source branch, force-pushing to target branch, or if the target branch now contains any commits from the MR)
we fetch the comparison information using `Gitlab::Git::Compare`, which fetches `base` and `head` data using Gitaly and diff between them through
`Gitlab::Git::Diff.between`.
The diffs fetching process _limits_ single file diff sizes and the overall size of the whole diff through a series of constant values. Raw diff files are
@@ -45,7 +45,7 @@ Even though diffs larger than 10% of the value of `ApplicationSettings#diff_max_
we still keep them on PostgreSQL. However, diff files larger than defined _safety limits_
(see the [Diff limits section](#diff-limits)) are _not_ persisted in the database.
-In order to present diffs information on the Merge Request diffs page, we:
+In order to present diffs information on the merge request diffs page, we:
1. Fetch all diff files from database `merge_request_diff_files`
1. Fetch the _old_ and _new_ file blobs in batch to:
diff --git a/doc/development/export_csv.md b/doc/development/export_csv.md
index e2bbd0491d6..a73b0e74e18 100644
--- a/doc/development/export_csv.md
+++ b/doc/development/export_csv.md
@@ -12,7 +12,7 @@ This document lists the different implementations of CSV export in GitLab codeba
|---|---|---|---|---|
| Streaming | - Query and yield data in batches to a response stream.<br>- Download starts immediately. | - Report available immediately. | - No progress indicator.<br>- Requires a reliable connection. | [Export Audit Event Log](../administration/audit_events.md#export-to-csv) |
| Downloading | - Query and write data in batches to a temporary file.<br>- Loads the file into memory.<br>- Sends the file to the client. | - Report available immediately. | - Large amount of data might cause request timeout.<br>- Memory intensive.<br>- Request expires when user navigates to a different page. | [Export Chain of Custody Report](../user/compliance/compliance_report/#chain-of-custody-report) |
-| As email attachment | - Asynchronously process the query with background job.<br>- Email uses the export as an attachment. | - Asynchronous processing. | - Requires users use a different app (email) to download the CSV.<br>- Email providers may limit attachment size. | - [Export Issues](../user/project/issues/csv_export.md)<br>- [Export Merge Requests](../user/project/merge_requests/csv_export.md) |
+| As email attachment | - Asynchronously process the query with background job.<br>- Email uses the export as an attachment. | - Asynchronous processing. | - Requires users use a different app (email) to download the CSV.<br>- Email providers may limit attachment size. | - [Export issues](../user/project/issues/csv_export.md)<br>- [Export merge requests](../user/project/merge_requests/csv_export.md) |
| As downloadable link in email (*) | - Asynchronously process the query with background job.<br>- Email uses an export link. | - Asynchronous processing.<br>- Bypasses email provider attachment size limit. | - Requires users use a different app (email).<br>- Requires additional storage and cleanup. | [Export User Permissions](https://gitlab.com/gitlab-org/gitlab/-/issues/1772) |
| Polling (non-persistent state) | - Asynchronously processes the query with the background job.<br>- Frontend(FE) polls every few seconds to check if CSV file is ready. | - Asynchronous processing.<br>- Automatically downloads to local machine on completion.<br>- In-app solution. | - Non-persistable request - request expires when user navigates to a different page.<br>- API is processed for each polling request. | [Export Vulnerabilities](../user/application_security/vulnerability_report/#export-vulnerability-details) |
| Polling (persistent state) (*) | - Asynchronously processes the query with background job.<br>- Backend (BE) maintains the export state<br>- FE polls every few seconds to check status.<br>- FE shows 'Download link' when export is ready.<br>- User can download or regenerate a new report. | - Asynchronous processing.<br>- No database calls made during the polling requests (HTTP 304 status is returned until export status changes).<br>- Does not require user to stay on page until export is complete.<br>- In-app solution.<br>- Can be expanded into a generic CSV feature (such as dashboard / CSV API). | - Requires to maintain export states in DB.<br>- Does not automatically download the CSV export to local machine, requires users to click 'Download' button. | [Export Merge Commits Report](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43055) |
diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md
index 820b4bab802..df3b26d59af 100644
--- a/doc/development/feature_flags/index.md
+++ b/doc/development/feature_flags/index.md
@@ -169,7 +169,7 @@ Each feature flag is defined in a separate YAML file consisting of a number of f
| `name` | yes | Name of the feature flag. |
| `type` | yes | Type of feature flag. |
| `default_enabled` | yes | The default state of the feature flag that is strictly validated, with `default_enabled:` passed as an argument. |
-| `introduced_by_url` | no | The URL to the Merge Request that introduced the feature flag. |
+| `introduced_by_url` | no | The URL to the merge request that introduced the feature flag. |
| `rollout_issue_url` | no | The URL to the Issue covering the feature flag rollout. |
| `milestone` | no | Milestone in which the feature was added. |
| `group` | no | The [group](https://about.gitlab.com/handbook/product/categories/#devops-stages) that owns the feature flag. |
diff --git a/doc/development/features_inside_dot_gitlab.md b/doc/development/features_inside_dot_gitlab.md
index 73ba9cbd674..283a0d5d5fb 100644
--- a/doc/development/features_inside_dot_gitlab.md
+++ b/doc/development/features_inside_dot_gitlab.md
@@ -11,7 +11,7 @@ When implementing new features, please refer to these existing features to avoid
- [Custom Dashboards](../operations/metrics/dashboards/index.md#add-a-new-dashboard-to-your-project): `.gitlab/dashboards/`.
- [Issue Templates](../user/project/description_templates.md#create-an-issue-template): `.gitlab/issue_templates/`.
-- [Merge Request Templates](../user/project/description_templates.md#create-a-merge-request-template): `.gitlab/merge_request_templates/`.
+- [Merge request Templates](../user/project/description_templates.md#create-a-merge-request-template): `.gitlab/merge_request_templates/`.
- [GitLab Agent](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/configuration_repository.md#layout): `.gitlab/agents/`.
- [CODEOWNERS](../user/project/code_owners.md#set-up-code-owners): `.gitlab/CODEOWNERS`.
- [Route Maps](../ci/review_apps/#route-maps): `.gitlab/route-map.yml`.
diff --git a/doc/development/index.md b/doc/development/index.md
index 105ad9a8852..0501f70b818 100644
--- a/doc/development/index.md
+++ b/doc/development/index.md
@@ -224,7 +224,7 @@ the [reviewer values](https://about.gitlab.com/handbook/engineering/workflow/rev
- [Sidekiq guidelines](sidekiq/index.md) for working with Sidekiq workers
- [Working with Gitaly](gitaly.md)
- [Elasticsearch integration docs](elasticsearch.md)
-- [Working with Merge Request diffs](diffs.md)
+- [Working with merge request diffs](diffs.md)
- [Approval Rules](approval_rules.md)
- [Repository mirroring](repository_mirroring.md)
- [File uploads](uploads.md)
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 147d379cec7..27a166aebf9 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -10,7 +10,7 @@ Integrating a security scanner into GitLab consists of providing end users
with a [CI job definition](../../ci/yaml/index.md)
they can add to their CI configuration files to scan their GitLab projects.
This CI job should then output its results in a GitLab-specified format. These results are then
-automatically presented in various places in GitLab, such as the Pipeline view, Merge Request
+automatically presented in various places in GitLab, such as the Pipeline view, merge request
widget, and Security Dashboard.
The scanning job is usually based on a [Docker image](https://docs.docker.com/)
diff --git a/doc/development/issuable-like-models.md b/doc/development/issuable-like-models.md
index b3be2b1b2e6..42dfe2e0f2f 100644
--- a/doc/development/issuable-like-models.md
+++ b/doc/development/issuable-like-models.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab Rails codebase contains several models that hold common functionality and behave similarly to
[Issues](../user/project/issues/index.md). Other examples of "issuables"
-are [Merge Requests](../user/project/merge_requests/index.md) and
+are [merge requests](../user/project/merge_requests/index.md) and
[Epics](../user/group/epics/index.md).
This guide accumulates guidelines on working with such Rails models.
diff --git a/doc/development/issue_types.md b/doc/development/issue_types.md
index 31fa50e1d97..e6047c62827 100644
--- a/doc/development/issue_types.md
+++ b/doc/development/issue_types.md
@@ -11,7 +11,7 @@ We are deprecating Issue Types as of GitLab 14.2 in favor of [Work Items and Wor
Sometimes when a new resource type is added it's not clear if it should be only an
"extension" of Issue (Issue Type) or if it should be a new first-class resource type
-(similar to Issue, Epic, Merge Request, Snippet).
+(similar to issue, epic, merge request, snippet).
The idea of Issue Types was first proposed in [this
issue](https://gitlab.com/gitlab-org/gitlab/-/issues/8767) and its usage was
diff --git a/doc/development/service_ping/metrics_dictionary.md b/doc/development/service_ping/metrics_dictionary.md
index 808c5064cf3..1be6f6b9719 100644
--- a/doc/development/service_ping/metrics_dictionary.md
+++ b/doc/development/service_ping/metrics_dictionary.md
@@ -49,7 +49,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `tier` | yes | `array`; may contain one or a combination of `free`, `premium` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. This should be verbose and contain all tiers where a metric is available. |
| `milestone` | no | The milestone when the metric is introduced. |
| `milestone_removed` | no | The milestone when the metric is removed. |
-| `introduced_by_url` | no | The URL to the Merge Request that introduced the metric. |
+| `introduced_by_url` | no | The URL to the merge request that introduced the metric. |
| `repair_issue_url` | no | The URL of the issue that was created to repair a metric with a `broken` status. |
| `options` | no | `object`: options information needed to calculate the metric value. |
| `skip_validation` | no | This should **not** be set. [Used for imported metrics until we review, update and make them valid](https://gitlab.com/groups/gitlab-org/-/epics/5425). |
diff --git a/doc/development/snowplow/index.md b/doc/development/snowplow/index.md
index dbc7a25075f..bf627d977ae 100644
--- a/doc/development/snowplow/index.md
+++ b/doc/development/snowplow/index.md
@@ -166,6 +166,19 @@ LIMIT 100
Snowplow JavaScript adds [web-specific parameters](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol/#Web-specific_parameters) to all web events by default.
+## Snowplow monitoring
+
+For different stages in the processing pipeline, there are several tools that monitor Snowplow events tracking:
+
+- [Product Intelligence Grafana dashboard](https://dashboards.gitlab.net/d/product-intelligence-main/product-intelligence-product-intelligence?orgId=1) monitors backend events sent from GitLab.com instance to collectors fleet. This dashboard provides information about:
+ - The number of events that successfully reach Snowplow collectors.
+ - The number of events that failed to reach Snowplow collectors.
+ - The number of backend events that were sent.
+- [AWS CloudWatch dashboard](https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#dashboards:name=SnowPlow;start=P3D) monitors the state of the events processing pipeline. The pipeline starts from Snowplow collectors, through to enrichers and pseudonymization, and up to persistence on S3 bucket from which events are imported to Snowflake Data Warehouse. To view this dashboard AWS access is required, follow this [instruction](https://gitlab.com/gitlab-org/growth/product-intelligence/snowplow-pseudonymization#monitoring) if you are interested in getting one.
+- [SiSense dashboard](https://app.periscopedata.com/app/gitlab/417669/Snowplow-Summary-Dashboard) provides information about the number of good and bad events imported into the Data Warehouse, in addition to the total number of imported Snowplow events.
+
+For more information, see this [video walk-through](https://www.youtube.com/watch?v=NxPS0aKa_oU).
+
## Related topics
- [Snowplow data structure](https://docs.snowplowanalytics.com/docs/understanding-your-pipeline/canonical-event/)
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 7fbbe4ee04a..b9c2ef56adf 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -517,7 +517,7 @@ When performing a search, the GitLab index uses the following scopes:
| `projects` | Project data (default) |
| `blobs` | Code |
| `issues` | Issue data |
-| `merge_requests` | Merge Request data |
+| `merge_requests` | Merge request data |
| `milestones` | Milestone data |
| `notes` | Note data |
| `snippets` | Snippet data |
diff --git a/doc/integration/jenkins_deprecated.md b/doc/integration/jenkins_deprecated.md
index 8da3118cf2c..57219b18047 100644
--- a/doc/integration/jenkins_deprecated.md
+++ b/doc/integration/jenkins_deprecated.md
@@ -19,7 +19,7 @@ This service was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1600) i
Integration includes:
- Trigger Jenkins build after push to repository
-- Show build status on Merge Request page
+- Show build status on Merge request page
Requirements:
diff --git a/doc/topics/git/merge_conflicts.md b/doc/topics/git/merge_conflicts.md
index bf69190030c..47276ccb0b2 100644
--- a/doc/topics/git/merge_conflicts.md
+++ b/doc/topics/git/merge_conflicts.md
@@ -23,7 +23,7 @@ comments: false
1. Fix conflicts on the `conflicts.rb` file.
1. Stage the file and continue rebasing.
1. Force push the changes.
-1. Finally continue with the Merge Request.
+1. Finally continue with the merge request.
```shell
git checkout -b conflicts_branch
diff --git a/doc/user/admin_area/analytics/usage_trends.md b/doc/user/admin_area/analytics/usage_trends.md
index 7901d30c3ea..a9c5adcf838 100644
--- a/doc/user/admin_area/analytics/usage_trends.md
+++ b/doc/user/admin_area/analytics/usage_trends.md
@@ -33,7 +33,7 @@ At the top of the page, Usage Trends shows total counts for:
- Projects
- Groups
- Issues
-- Merge Requests
+- Merge requests
- Pipelines
These figures can be useful for understanding how much data your instance contains in total.
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index c5761a5743f..fe897243988 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -63,7 +63,7 @@ as shown in the following table:
| [Configure Secret Detection Scanners](#configuration) | **{check-circle}** | **{check-circle}** |
| [Customize Secret Detection Settings](#customizing-settings) | **{check-circle}** | **{check-circle}** |
| View [JSON Report](../sast/index.md#reports-json-format) | **{check-circle}** | **{check-circle}** |
-| Presentation of JSON Report in Merge Request | **{dotted-circle}** | **{check-circle}** |
+| Presentation of JSON Report in merge request | **{dotted-circle}** | **{check-circle}** |
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** | **{check-circle}** |
| [Interaction with Vulnerabilities](../vulnerabilities/index.md) | **{dotted-circle}** | **{check-circle}** |
| [Access to Security Dashboard](../security_dashboard/index.md) | **{dotted-circle}** | **{check-circle}** |
@@ -370,7 +370,7 @@ For information on this, see the [general Application Security troubleshooting s
### Error: `Couldn't run the gitleaks command: exit status 2`
-If a pipeline is triggered from a Merge Request containing 60 commits while the `GIT_DEPTH` variable's
+If a pipeline is triggered from a merge request containing 60 commits while the `GIT_DEPTH` variable's
value is less than that, the Secret Detection job fails as the clone is not deep enough to contain all of the
relevant commits. For information on the current default value, see the
[pipeline configuration documentation](../../../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone).
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index a235c0ef6f8..b8466ddf40f 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -377,3 +377,18 @@ Alternatively, you can mount the certificate file at a different location and in
mountPath: /tmp/myCA.pem
subPath: myCA.pem
```
+
+#### Project not found
+
+```json
+{
+ "level ":"error ",
+ "time ":"2022-01-05T15:18:11.331Z",
+ "msg ":"GetObjectsToSynchronize.Recv failed ",
+ "mod_name ":"gitops ",
+ "error ":"rpc error: code = NotFound desc = project not found ",
+}
+```
+
+This error is shown if the manifest project is not public. To fix it,
+[make sure your manifest project is public](repository.md#synchronize-manifest-projects).
diff --git a/doc/user/clusters/agent/repository.md b/doc/user/clusters/agent/repository.md
index 22964fde395..4a28182f653 100644
--- a/doc/user/clusters/agent/repository.md
+++ b/doc/user/clusters/agent/repository.md
@@ -40,6 +40,9 @@ with Kubernetes resource definitions in YAML or JSON format. The Agent monitors
each project you declare, and when the project changes, GitLab deploys the changes
using the Agent.
+WARNING:
+When using separate GitLab projects for manifest files and configuration repository, the manifests project must be public.
+
To use multiple YAML files, specify a `paths` attribute in the `gitops.manifest_projects` section.
```yaml
diff --git a/doc/user/index.md b/doc/user/index.md
index a3b7cfc4b3c..f4a7cd6a5d9 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -44,7 +44,7 @@ GitLab is a Git-based platform that integrates a great number of essential tools
- Tracking proposals for new implementations, bug reports, and feedback with a
fully featured [Issue tracker](project/issues/index.md).
- Organizing and prioritizing with [issue boards](project/issue_board.md).
-- Reviewing code in [Merge Requests](project/merge_requests/index.md) with live-preview changes per
+- Reviewing code in [merge requests](project/merge_requests/index.md) with live-preview changes per
branch with [Review Apps](../ci/review_apps/index.md).
- Building, testing, and deploying with built-in [Continuous Integration](../ci/index.md).
- Deploying personal and professional static websites with [GitLab Pages](project/pages/index.md).
@@ -56,7 +56,7 @@ GitLab is a Git-based platform that integrates a great number of essential tools
With GitLab Enterprise Edition, you can also:
- Improve collaboration with:
- - [Merge Request Approvals](project/merge_requests/approvals/index.md).
+ - [Merge request approvals](project/merge_requests/approvals/index.md).
- [Multiple Assignees for Issues](project/issues/multiple_assignees_for_issues.md).
- [Multiple issue boards](project/issue_board.md#multiple-issue-boards).
- Create formal relationships between issues with [linked issues](project/issues/related_issues.md).
@@ -152,8 +152,8 @@ it all at once, from one single project.
- [Repositories](project/repository/index.md): Host your codebase in
repositories with version control and as part of a fully integrated platform.
- [Issues](project/issues/index.md): Explore the best of GitLab Issues' features.
-- [Merge Requests](project/merge_requests/index.md): Collaborate on code,
- reviews, live preview changes per branch, and request approvals with Merge Requests.
+- [Merge requests](project/merge_requests/index.md): Collaborate on code,
+ reviews, live preview changes per branch, and request approvals with merge requests.
- [Milestones](project/milestones/index.md): Work on multiple issues and merge
requests towards the same target date with Milestones.
diff --git a/doc/user/infrastructure/iac/index.md b/doc/user/infrastructure/iac/index.md
index ceb6101688b..21769bdd14c 100644
--- a/doc/user/infrastructure/iac/index.md
+++ b/doc/user/infrastructure/iac/index.md
@@ -83,12 +83,12 @@ GitLab can be used as a [Terraform module registry](../../packages/terraform_mod
to create and publish Terraform modules to a private registry specific to your
top-level namespace.
-## Terraform integration in Merge Requests
+## Terraform integration in merge requests
Collaborating around Infrastructure as Code (IaC) changes requires both code changes
and expected infrastructure changes to be checked and approved. GitLab provides a
solution to help collaboration around Terraform code changes and their expected
-effects using the Merge Request pages. This way users don't have to build custom
+effects using the merge request pages. This way users don't have to build custom
tools or rely on 3rd party solutions to streamline their IaC workflows.
Read more on setting up and [using the merge request integrations](mr_integration.md).
diff --git a/doc/user/infrastructure/iac/mr_integration.md b/doc/user/infrastructure/iac/mr_integration.md
index ab59f8ad64b..1b754288032 100644
--- a/doc/user/infrastructure/iac/mr_integration.md
+++ b/doc/user/infrastructure/iac/mr_integration.md
@@ -4,9 +4,9 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Terraform integration in Merge Requests **(FREE)**
+# Terraform integration in merge requests **(FREE)**
-Collaborating around Infrastructure as Code (IaC) changes requires both code changes and expected infrastructure changes to be checked and approved. GitLab provides a solution to help collaboration around Terraform code changes and their expected effects using the Merge Request pages. This way users don't have to build custom tools or rely on 3rd party solutions to streamline their IaC workflows.
+Collaborating around Infrastructure as Code (IaC) changes requires both code changes and expected infrastructure changes to be checked and approved. GitLab provides a solution to help collaboration around Terraform code changes and their expected effects using the merge request pages. This way users don't have to build custom tools or rely on 3rd party solutions to streamline their IaC workflows.
## Output Terraform Plan information into a merge request
@@ -83,7 +83,7 @@ To manually configure a GitLab Terraform Report artifact:
1. Running the pipeline displays the widget in the merge request, like this:
- ![Merge Request Terraform widget](img/terraform_plan_widget_v13_2.png)
+ ![merge request Terraform widget](img/terraform_plan_widget_v13_2.png)
1. Clicking the **View Full Log** button in the widget takes you directly to the
plan output present in the pipeline logs:
@@ -151,8 +151,8 @@ apply:
### Multiple Terraform Plan reports
-Starting with GitLab version 13.2, you can display multiple reports on the Merge Request
-page. The reports also display the `artifacts: name:`. See example below for a suggested setup.
+Starting with GitLab version 13.2, you can display multiple reports on a merge request.
+The reports also display the `artifacts: name:`. See example below for a suggested setup.
```yaml
default:
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 46fef3a305f..34cc49c1e22 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -249,7 +249,7 @@ Use the switches to enable or disable the following features:
|:---------------------------------|:--------------------------|:--------------|
| **Issues** | ✓ | Activates the GitLab issues tracker. |
| **Repository** | ✓ | Enables [repository](../repository/) functionality |
-| **Merge Requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings). |
+| **Merge requests** | ✓ | Enables [merge request](../merge_requests/) functionality; also see [Merge request settings](#merge-request-settings). |
| **Forks** | ✓ | Enables [forking](../repository/forking_workflow.md) functionality. |
| **Git Large File Storage (LFS)** | | Enables the use of [large files](../../../topics/git/lfs/index.md#git-large-file-storage-lfs). |
| **Packages** | | Supports configuration of a [package registry](../../../administration/packages/index.md#gitlab-package-registry-administration) functionality. |
@@ -281,7 +281,7 @@ Some features depend on others:
- If you disable **Repository** functionality, GitLab also disables the following
features for your project:
- - **Merge Requests**
+ - **Merge requests**
- **CI/CD**
- **Container Registry**
- **Git Large File Storage**
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index 0e2be455a0c..2c13d06a91d 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## Search issues and merge requests
-To search through issues and merge requests in multiple projects, on the top bar, select the **Issues** or **Merge Requests** links.
+To search through issues and merge requests in multiple projects, on the top bar, select the **Issues** or **Merge requests** links.
The numbers indicate how many issues, merge requests, and to-do items are assigned to you:
@@ -36,7 +36,7 @@ in the search field in the upper right corner:
> - Filter by child Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab Ultimate 13.0.
> - Filter by Iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6. Moved to GitLab Premium in 13.9.
-Follow these steps to filter the **Issues** and **Merge Requests** list pages in projects and
+Follow these steps to filter the **Issues** and **Merge requests** list pages in projects and
groups:
1. Click in the field **Search or filter results...**.
@@ -95,7 +95,7 @@ You can add this URL to your feed reader.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1.
-You can filter the **Issues** list to individual instances by their ID. For example, enter filter `#10` to return only issue 10. The same applies to the **Merge Requests** list. Enter filter `#30` to return only merge request 30.
+You can filter the **Issues** list to individual instances by their ID. For example, enter filter `#10` to return only issue 10. The same applies to the **Merge requests** list. Enter filter `#30` to return only merge request 30.
![filter issues by specific ID](img/issue_search_by_id.png)
diff --git a/lib/gitlab/database/gitlab_loose_foreign_keys.yml b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
index 5f9d320ab78..13a27c0d1ec 100644
--- a/lib/gitlab/database/gitlab_loose_foreign_keys.yml
+++ b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
@@ -170,3 +170,6 @@ ci_triggers:
- table: users
column: owner_id
on_delete: async_delete
+ - table: projects
+ column: project_id
+ on_delete: async_delete
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
index 0abc21531a6..a0bf816eda3 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
@@ -2,7 +2,7 @@
module QA
RSpec.shared_context 'with gitlab project migration', quarantine: {
- only: { job: 'praefect', subdomain: :staging },
+ only: [{ job: 'praefect' }, { subdomain: :staging }],
type: :investigating,
issue: [
'https://gitlab.com/gitlab-org/gitlab/-/issues/348999',
diff --git a/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js
index 12fc08c303c..acd80ed8db2 100644
--- a/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js
+++ b/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
-import { mount, createLocalVue } from '@vue/test-utils';
+import { mount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql';
import updateHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql';
@@ -49,8 +50,6 @@ import mockIntegrations from './mocks/integrations.json';
jest.mock('~/flash');
-const localVue = createLocalVue();
-
describe('AlertsSettingsWrapper', () => {
let wrapper;
let fakeApollo;
@@ -111,7 +110,7 @@ describe('AlertsSettingsWrapper', () => {
function createComponentWithApollo({
destroyHandler = jest.fn().mockResolvedValue(destroyIntegrationResponse),
} = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
destroyIntegrationHandler = destroyHandler;
const requestHandlers = [
@@ -122,7 +121,6 @@ describe('AlertsSettingsWrapper', () => {
fakeApollo = createMockApollo(requestHandlers);
wrapper = mount(AlertsSettingsWrapper, {
- localVue,
apolloProvider: fakeApollo,
provide: {
alertSettings: {
diff --git a/spec/frontend/artifacts_settings/components/keep_latest_artifact_checkbox_spec.js b/spec/frontend/artifacts_settings/components/keep_latest_artifact_checkbox_spec.js
index bfa8274f0eb..3ba0280deb3 100644
--- a/spec/frontend/artifacts_settings/components/keep_latest_artifact_checkbox_spec.js
+++ b/spec/frontend/artifacts_settings/components/keep_latest_artifact_checkbox_spec.js
@@ -1,5 +1,6 @@
import { GlFormCheckbox, GlLink } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import UpdateKeepLatestArtifactProjectSetting from '~/artifacts_settings/graphql/mutations/update_keep_latest_artifact_project_setting.mutation.graphql';
@@ -7,8 +8,7 @@ import GetKeepLatestArtifactApplicationSetting from '~/artifacts_settings/graphq
import GetKeepLatestArtifactProjectSetting from '~/artifacts_settings/graphql/queries/get_keep_latest_artifact_project_setting.query.graphql';
import KeepLatestArtifactCheckbox from '~/artifacts_settings/keep_latest_artifact_checkbox.vue';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
const keepLatestArtifactProjectMock = {
data: {
@@ -73,7 +73,6 @@ describe('Keep latest artifact checkbox', () => {
stubs: {
GlFormCheckbox,
},
- localVue,
apolloProvider,
});
};
diff --git a/spec/frontend/boards/board_list_helper.js b/spec/frontend/boards/board_list_helper.js
index d0f14bd37c1..04192489817 100644
--- a/spec/frontend/boards/board_list_helper.js
+++ b/spec/frontend/boards/board_list_helper.js
@@ -1,4 +1,5 @@
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex';
@@ -33,9 +34,8 @@ export default function createComponent({
},
issuesCount,
} = {}) {
- const localVue = createLocalVue();
- localVue.use(VueApollo);
- localVue.use(Vuex);
+ Vue.use(VueApollo);
+ Vue.use(Vuex);
const fakeApollo = createMockApollo([
[listQuery, jest.fn().mockResolvedValue(boardListQueryResponse(issuesCount))],
@@ -85,7 +85,6 @@ export default function createComponent({
const component = shallowMount(BoardList, {
apolloProvider: fakeApollo,
- localVue,
store,
propsData: {
disabled: false,
diff --git a/spec/frontend/clusters_list/components/install_agent_modal_spec.js b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
index 5edc504aecb..6ad3d61cec7 100644
--- a/spec/frontend/clusters_list/components/install_agent_modal_spec.js
+++ b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
@@ -1,5 +1,5 @@
import { GlAlert, GlButton, GlFormInputGroup, GlSprintf } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { sprintf } from '~/locale';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -32,8 +32,7 @@ import {
} from '../mocks/apollo';
import ModalStub from '../stubs';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
const projectPath = 'path/to/project';
const kasAddress = 'kas.example.com';
@@ -95,7 +94,6 @@ describe('InstallAgentModal', () => {
GlSprintf,
GlModal: ModalStub,
},
- localVue,
apolloProvider,
provide,
propsData,
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index ce74569f219..5a2f3bdeef8 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -1,6 +1,7 @@
import { GlEmptyState } from '@gitlab/ui';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+
import VueApollo, { ApolloMutation } from 'vue-apollo';
import VueRouter from 'vue-router';
import VueDraggable from 'vuedraggable';
@@ -49,9 +50,8 @@ jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageEl);
const scrollIntoViewMock = jest.fn();
HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
-const localVue = createLocalVue();
const router = createRouter();
-localVue.use(VueRouter);
+Vue.use(VueRouter);
const mockDesigns = [
{
@@ -159,7 +159,6 @@ describe('Design management index page', () => {
};
},
mocks: { $apollo },
- localVue,
router,
stubs: { DesignDestroyer, ApolloMutation, VueDraggable, ...stubs },
attachTo: document.body,
@@ -175,7 +174,7 @@ describe('Design management index page', () => {
function createComponentWithApollo({
moveHandler = jest.fn().mockResolvedValue(moveDesignMutationResponse),
}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
moveDesignHandler = moveHandler;
const requestHandlers = [
@@ -186,7 +185,6 @@ describe('Design management index page', () => {
fakeApollo = createMockApollo(requestHandlers);
wrapper = shallowMount(Index, {
- localVue,
apolloProvider: fakeApollo,
router,
stubs: { VueDraggable },
diff --git a/spec/frontend/diffs/components/collapsed_files_warning_spec.js b/spec/frontend/diffs/components/collapsed_files_warning_spec.js
index 050d32413ad..9726df55c6f 100644
--- a/spec/frontend/diffs/components/collapsed_files_warning_spec.js
+++ b/spec/frontend/diffs/components/collapsed_files_warning_spec.js
@@ -19,7 +19,7 @@ async function files(store, count) {
const copies = Array(count).fill(file);
store.state.diffs.diffFiles.push(...copies);
- return nextTick();
+ await nextTick();
}
describe('CollapsedFilesWarning', () => {
@@ -84,7 +84,7 @@ describe('CollapsedFilesWarning', () => {
getAlertCloseButton().element.click();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find('[data-testid="root"]').exists()).toBe(false);
});
diff --git a/spec/frontend/diffs/components/compare_versions_spec.js b/spec/frontend/diffs/components/compare_versions_spec.js
index 1ef927f5e9e..f11b60a9238 100644
--- a/spec/frontend/diffs/components/compare_versions_spec.js
+++ b/spec/frontend/diffs/components/compare_versions_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import getDiffWithCommit from 'test_fixtures/merge_request_diffs/with_commit.json';
import setWindowLocation from 'helpers/set_window_location_helper';
@@ -232,14 +232,13 @@ describe('CompareVersions', () => {
expect(link.element.getAttribute('href')).toEqual(PREV_COMMIT_URL);
});
- it('triggers the correct Vuex action on click', () => {
+ it('triggers the correct Vuex action on click', async () => {
const link = getPrevCommitNavElement();
link.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({
- direction: 'previous',
- });
+ await nextTick();
+ expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({
+ direction: 'previous',
});
});
@@ -267,13 +266,12 @@ describe('CompareVersions', () => {
expect(link.element.getAttribute('href')).toEqual(NEXT_COMMIT_URL);
});
- it('triggers the correct Vuex action on click', () => {
+ it('triggers the correct Vuex action on click', async () => {
const link = getNextCommitNavElement();
link.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({ direction: 'next' });
- });
+ await nextTick();
+ expect(wrapper.vm.moveToNeighboringCommit).toHaveBeenCalledWith({ direction: 'next' });
});
it('renders a disabled button when there is no next commit', () => {
diff --git a/spec/frontend/diffs/components/diff_file_header_spec.js b/spec/frontend/diffs/components/diff_file_header_spec.js
index 1beaae6e16d..320fb395c3b 100644
--- a/spec/frontend/diffs/components/diff_file_header_spec.js
+++ b/spec/frontend/diffs/components/diff_file_header_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { cloneDeep } from 'lodash';
import Vuex from 'vuex';
@@ -125,30 +125,27 @@ describe('DiffFileHeader component', () => {
expect(findCollapseIcon().props('name')).toBe(icon);
});
- it('when header is clicked emits toggleFile', () => {
+ it('when header is clicked emits toggleFile', async () => {
createComponent();
findHeader().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleFile).toBeDefined();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleFile).toBeDefined();
});
- it('when collapseIcon is clicked emits toggleFile', () => {
+ it('when collapseIcon is clicked emits toggleFile', async () => {
createComponent({ props: { collapsible: true } });
findCollapseIcon().vm.$emit('click', new Event('click'));
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleFile).toBeDefined();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleFile).toBeDefined();
});
- it('when other element in header is clicked does not emits toggleFile', () => {
+ it('when other element in header is clicked does not emits toggleFile', async () => {
createComponent({ props: { collapsible: true } });
findTitleLink().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleFile).not.toBeDefined();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleFile).not.toBeDefined();
});
describe('copy to clipboard', () => {
diff --git a/spec/frontend/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index e185b817fca..a0aa4c784bf 100644
--- a/spec/frontend/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -160,7 +160,7 @@ describe('DiffFile', () => {
last,
}));
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(eventHub.$emit).toHaveBeenCalledTimes(events.length);
events.forEach((event) => {
@@ -184,13 +184,13 @@ describe('DiffFile', () => {
makeFileAutomaticallyCollapsed(store);
- await wrapper.vm.$nextTick(); // Wait for store updates to flow into the component
+ await nextTick(); // Wait for store updates to flow into the component
toggleFile(wrapper);
- await wrapper.vm.$nextTick(); // Wait for the load to resolve
- await wrapper.vm.$nextTick(); // Wait for the idleCallback
- await wrapper.vm.$nextTick(); // Wait for nextTick inside postRender
+ await nextTick(); // Wait for the load to resolve
+ await nextTick(); // Wait for the idleCallback
+ await nextTick(); // Wait for nextTick inside postRender
expect(eventHub.$emit).toHaveBeenCalledTimes(2);
expect(eventHub.$emit).toHaveBeenCalledWith(EVT_PERF_MARK_FIRST_DIFF_FILE_SHOWN);
@@ -214,7 +214,7 @@ describe('DiffFile', () => {
markFileToBeRendered(store);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(DiffContentComponent).exists()).toBe(true);
});
@@ -264,7 +264,7 @@ describe('DiffFile', () => {
it('performs the normal file toggle when the file is collapsed', async () => {
makeFileAutomaticallyCollapsed(store);
- await wrapper.vm.$nextTick();
+ await nextTick();
eventHub.$emit(EVT_EXPAND_ALL_FILES);
@@ -274,7 +274,7 @@ describe('DiffFile', () => {
it('does nothing when the file is not collapsed', async () => {
eventHub.$emit(EVT_EXPAND_ALL_FILES);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.handleToggle).not.toHaveBeenCalled();
});
@@ -286,7 +286,7 @@ describe('DiffFile', () => {
});
it('should not have any content at all', async () => {
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDiffContentArea(wrapper).element.children.length).toBe(0);
});
@@ -392,7 +392,7 @@ describe('DiffFile', () => {
readableText,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
toggleFile(wrapper);
};
@@ -440,7 +440,7 @@ describe('DiffFile', () => {
makeFileAutomaticallyCollapsed(store);
wrapper.vm.requestDiff();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findLoader(wrapper).exists()).toBe(true);
});
@@ -451,7 +451,7 @@ describe('DiffFile', () => {
({ wrapper, store } = createComponent({ file: getUnreadableFile() }));
makeFileAutomaticallyCollapsed(store);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDiffContentArea(wrapper).html()).toContain(
'Files with large changes are collapsed by default.',
@@ -470,7 +470,7 @@ describe('DiffFile', () => {
markFileToBeRendered(store);
changeViewerType(store, mode);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.classes('has-body')).toBe(true);
expect(wrapper.find(DiffContentComponent).exists()).toBe(true);
@@ -496,7 +496,7 @@ describe('DiffFile', () => {
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
const button = wrapper.find('[data-testid="blob-button"]');
@@ -521,7 +521,7 @@ describe('DiffFile', () => {
({ wrapper, store } = createComponent({ file, props: { viewDiffsFileByFile: true } }));
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findLoader(wrapper).exists()).toBe(true);
});
diff --git a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js
index 5884a9ebd3a..c18f0b721da 100644
--- a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js
+++ b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import DiffGutterAvatars from '~/diffs/components/diff_gutter_avatars.vue';
import discussionsMockData from '../mock_data/diff_discussions';
@@ -35,12 +36,11 @@ describe('DiffGutterAvatars', () => {
expect(findCollapseButton().exists()).toBe(true);
});
- it('should emit toggleDiscussions event on button click', () => {
+ it('should emit toggleDiscussions event on button click', async () => {
findCollapseButton().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
});
});
@@ -65,20 +65,18 @@ describe('DiffGutterAvatars', () => {
expect(findMoreCount().text()).toBe('+2');
});
- it('should emit toggleDiscussions event on avatars click', () => {
+ it('should emit toggleDiscussions event on avatars click', async () => {
findUserAvatars().at(0).trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
});
- it('should emit toggleDiscussions event on more count text click', () => {
+ it('should emit toggleDiscussions event on more count text click', async () => {
findMoreCount().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleLineDiscussions).toBeTruthy();
});
});
diff --git a/spec/frontend/diffs/components/tree_list_spec.js b/spec/frontend/diffs/components/tree_list_spec.js
index f03792295df..963805f4792 100644
--- a/spec/frontend/diffs/components/tree_list_spec.js
+++ b/spec/frontend/diffs/components/tree_list_spec.js
@@ -1,5 +1,5 @@
import { shallowMount, mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import TreeList from '~/diffs/components/tree_list.vue';
import createStore from '~/diffs/store/modules';
@@ -91,12 +91,11 @@ describe('Diffs tree list component', () => {
expect(getFileRows().at(1).html()).toContain('app');
});
- it('hides file stats', () => {
+ it('hides file stats', async () => {
wrapper.setProps({ hideFileStats: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('.file-row-stats').exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find('.file-row-stats').exists()).toBe(false);
});
it('calls toggleTreeOpen when clicking folder', () => {
@@ -117,20 +116,18 @@ describe('Diffs tree list component', () => {
});
});
- it('renders as file list when renderTreeList is false', () => {
+ it('renders as file list when renderTreeList is false', async () => {
wrapper.vm.$store.state.diffs.renderTreeList = false;
- return wrapper.vm.$nextTick().then(() => {
- expect(getFileRows()).toHaveLength(1);
- });
+ await nextTick();
+ expect(getFileRows()).toHaveLength(1);
});
- it('renders file paths when renderTreeList is false', () => {
+ it('renders file paths when renderTreeList is false', async () => {
wrapper.vm.$store.state.diffs.renderTreeList = false;
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('.file-row').html()).toContain('index.js');
- });
+ await nextTick();
+ expect(wrapper.find('.file-row').html()).toContain('index.js');
});
});
@@ -142,14 +139,13 @@ describe('Diffs tree list component', () => {
store.state.diffs.viewedDiffFileIds = viewedDiffFileIds;
});
- it('passes the viewedDiffFileIds to the FileTree', () => {
+ it('passes the viewedDiffFileIds to the FileTree', async () => {
createComponent(shallowMount);
- return wrapper.vm.$nextTick().then(() => {
- // Have to use $attrs['viewed-files'] because we are passing down an object
- // and attributes('') stringifies values (e.g. [object])...
- expect(wrapper.find(FileTree).vm.$attrs['viewed-files']).toBe(viewedDiffFileIds);
- });
+ await nextTick();
+ // Have to use $attrs['viewed-files'] because we are passing down an object
+ // and attributes('') stringifies values (e.g. [object])...
+ expect(wrapper.find(FileTree).vm.$attrs['viewed-files']).toBe(viewedDiffFileIds);
});
});
});
diff --git a/spec/frontend/environments/canary_update_modal_spec.js b/spec/frontend/environments/canary_update_modal_spec.js
index c7129ee1320..22d13558a84 100644
--- a/spec/frontend/environments/canary_update_modal_spec.js
+++ b/spec/frontend/environments/canary_update_modal_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue';
import updateCanaryIngress from '~/environments/graphql/mutations/update_canary_ingress.mutation.graphql';
@@ -86,7 +87,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: [] } } });
modal.vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findAlert().exists()).toBe(false);
});
@@ -95,7 +96,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: ['error'] } } });
modal.vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findAlert().text()).toBe('error');
});
@@ -105,7 +106,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
modal.vm.$emit('primary');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findAlert().text()).toBe('Something went wrong. Please try again later');
});
@@ -114,12 +115,12 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate.mockResolvedValue({ data: { environmentsCanaryIngressUpdate: { errors: ['error'] } } });
modal.vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
const alert = findAlert();
alert.vm.$emit('dismiss');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(alert.exists()).toBe(false);
});
diff --git a/spec/frontend/environments/deploy_board_component_spec.js b/spec/frontend/environments/deploy_board_component_spec.js
index 24e94867afd..2033cf00cff 100644
--- a/spec/frontend/environments/deploy_board_component_spec.js
+++ b/spec/frontend/environments/deploy_board_component_spec.js
@@ -1,6 +1,6 @@
import { GlTooltip, GlIcon, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import CanaryIngress from '~/environments/components/canary_ingress.vue';
import DeployBoard from '~/environments/components/deploy_board.vue';
import { deployBoardMockData, environment } from './mock_data';
@@ -24,7 +24,7 @@ describe('Deploy Board', () => {
describe('with valid data', () => {
beforeEach((done) => {
wrapper = createComponent();
- wrapper.vm.$nextTick(done);
+ nextTick(done);
});
it('should render percentage with completion value provided', () => {
@@ -79,7 +79,7 @@ describe('Deploy Board', () => {
isEmpty: true,
logsPath,
});
- wrapper.vm.$nextTick(done);
+ nextTick(done);
});
it('should render the empty state', () => {
@@ -98,7 +98,7 @@ describe('Deploy Board', () => {
isEmpty: false,
logsPath,
});
- wrapper.vm.$nextTick(done);
+ nextTick(done);
});
it('should render loading spinner', () => {
@@ -116,7 +116,7 @@ describe('Deploy Board', () => {
deployBoardData: deployBoardMockData,
});
({ statuses } = wrapper.vm);
- wrapper.vm.$nextTick(done);
+ nextTick(done);
});
it('with all the possible statuses', () => {
diff --git a/spec/frontend/environments/environment_actions_spec.js b/spec/frontend/environments/environment_actions_spec.js
index 1b68a692db8..336c207428e 100644
--- a/spec/frontend/environments/environment_actions_spec.js
+++ b/spec/frontend/environments/environment_actions_spec.js
@@ -1,6 +1,6 @@
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { TEST_HOST } from 'helpers/test_constants';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -108,7 +108,7 @@ describe('EnvironmentActions Component', () => {
jest.spyOn(window, 'confirm').mockImplementation(() => confirm);
findDropdownItem(scheduledJobAction).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
};
beforeEach(() => {
diff --git a/spec/frontend/environments/environment_table_spec.js b/spec/frontend/environments/environment_table_spec.js
index 1851163ac68..c7582e4b06d 100644
--- a/spec/frontend/environments/environment_table_spec.js
+++ b/spec/frontend/environments/environment_table_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue';
import DeployBoard from '~/environments/components/deploy_board.vue';
import EnvironmentTable from '~/environments/components/environments_table.vue';
@@ -181,7 +182,7 @@ describe('Environment table', () => {
});
wrapper.find(DeployBoard).vm.$emit('changeCanaryWeight', 40);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(CanaryUpdateModal).props()).toMatchObject({
weight: 40,
diff --git a/spec/frontend/environments/environments_app_spec.js b/spec/frontend/environments/environments_app_spec.js
index cd05ecbfb53..92d1820681c 100644
--- a/spec/frontend/environments/environments_app_spec.js
+++ b/spec/frontend/environments/environments_app_spec.js
@@ -1,6 +1,7 @@
import { GlTabs } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Container from '~/environments/components/container.vue';
import DeployBoard from '~/environments/components/deploy_board.vue';
@@ -186,14 +187,13 @@ describe('Environment', () => {
expect(wrapper.find('.folder-icon[data-testid="chevron-right-icon"]').exists()).toBe(false);
});
- it('should close an opened folder', () => {
+ it('should close an opened folder', async () => {
expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(true);
// close folder
wrapper.find('.folder-name').trigger('click');
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(false);
});
it('should show children environments', () => {
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index 02baa31289e..493a96c207b 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -8,7 +8,7 @@ import {
GlSprintf,
} from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import {
severityLevel,
@@ -139,32 +139,30 @@ describe('ErrorDetails', () => {
mountComponent();
});
- it('when before timeout, still shows loading', () => {
+ it('when before timeout, still shows loading', async () => {
Date.now.mockReturnValue(endTime - 1);
wrapper.vm.onNoApolloResult();
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
- expect(createFlash).not.toHaveBeenCalled();
- expect(mocks.$apollo.queries.error.stopPolling).not.toHaveBeenCalled();
- });
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(createFlash).not.toHaveBeenCalled();
+ expect(mocks.$apollo.queries.error.stopPolling).not.toHaveBeenCalled();
});
- it('when timeout is hit and no apollo result, stops loading and shows flash', () => {
+ it('when timeout is hit and no apollo result, stops loading and shows flash', async () => {
Date.now.mockReturnValue(endTime + 1);
wrapper.vm.onNoApolloResult();
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- expect(wrapper.find(GlLink).exists()).toBe(false);
- expect(createFlash).toHaveBeenCalledWith({
- message: 'Could not connect to Sentry. Refresh the page to try again.',
- type: 'warning',
- });
- expect(mocks.$apollo.queries.error.stopPolling).toHaveBeenCalled();
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.find(GlLink).exists()).toBe(false);
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'Could not connect to Sentry. Refresh the page to try again.',
+ type: 'warning',
});
+ expect(mocks.$apollo.queries.error.stopPolling).toHaveBeenCalled();
});
});
@@ -224,7 +222,7 @@ describe('ErrorDetails', () => {
});
describe('Badges', () => {
- it('should show language and error level badges', () => {
+ it('should show language and error level badges', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -232,12 +230,11 @@ describe('ErrorDetails', () => {
tags: { level: 'error', logger: 'ruby' },
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.findAll(GlBadge).length).toBe(2);
- });
+ await nextTick();
+ expect(wrapper.findAll(GlBadge).length).toBe(2);
});
- it('should NOT show the badge if the tag is not present', () => {
+ it('should NOT show the badge if the tag is not present', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -245,14 +242,13 @@ describe('ErrorDetails', () => {
tags: { level: 'error' },
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.findAll(GlBadge).length).toBe(1);
- });
+ await nextTick();
+ expect(wrapper.findAll(GlBadge).length).toBe(1);
});
it.each(Object.keys(severityLevel))(
'should set correct severity level variant for %s badge',
- (level) => {
+ async (level) => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -260,15 +256,14 @@ describe('ErrorDetails', () => {
tags: { level: severityLevel[level] },
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlBadge).props('variant')).toEqual(
- severityLevelVariant[severityLevel[level]],
- );
- });
+ await nextTick();
+ expect(wrapper.find(GlBadge).props('variant')).toEqual(
+ severityLevelVariant[severityLevel[level]],
+ );
},
);
- it('should fallback for ERROR severityLevelVariant when severityLevel is unknown', () => {
+ it('should fallback for ERROR severityLevelVariant when severityLevel is unknown', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -276,32 +271,29 @@ describe('ErrorDetails', () => {
tags: { level: 'someNewErrorLevel' },
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlBadge).props('variant')).toEqual(
- severityLevelVariant[severityLevel.ERROR],
- );
- });
+ await nextTick();
+ expect(wrapper.find(GlBadge).props('variant')).toEqual(
+ severityLevelVariant[severityLevel.ERROR],
+ );
});
});
describe('Stacktrace', () => {
- it('should show stacktrace', () => {
+ it('should show stacktrace', async () => {
store.state.details.loadingStacktrace = false;
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- expect(wrapper.find(Stacktrace).exists()).toBe(true);
- expect(findAlert().exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.find(Stacktrace).exists()).toBe(true);
+ expect(findAlert().exists()).toBe(false);
});
- it('should NOT show stacktrace if no entries and show Alert message', () => {
+ it('should NOT show stacktrace if no entries and show Alert message', async () => {
store.state.details.loadingStacktrace = false;
store.getters = { 'details/sentryUrl': () => 'sentry.io', 'details/stacktrace': () => [] };
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- expect(wrapper.find(Stacktrace).exists()).toBe(false);
- expect(findAlert().text()).toBe('No stack trace for this error');
- });
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.find(Stacktrace).exists()).toBe(false);
+ expect(findAlert().text()).toBe('No stack trace for this error');
});
});
@@ -338,10 +330,10 @@ describe('ErrorDetails', () => {
});
describe('when error is unresolved', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.details.errorStatus = errorStatus.UNRESOLVED;
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays Ignore and Resolve buttons', () => {
@@ -365,10 +357,10 @@ describe('ErrorDetails', () => {
});
describe('when error is ignored', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.details.errorStatus = errorStatus.IGNORED;
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays Undo Ignore and Resolve buttons', () => {
@@ -392,10 +384,10 @@ describe('ErrorDetails', () => {
});
describe('when error is resolved', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.details.errorStatus = errorStatus.RESOLVED;
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays Ignore and Unresolve buttons', () => {
@@ -417,7 +409,7 @@ describe('ErrorDetails', () => {
);
});
- it('should show alert with closed issueId', () => {
+ it('should show alert with closed issueId', async () => {
const closedIssueId = 123;
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
@@ -426,10 +418,9 @@ describe('ErrorDetails', () => {
closedIssueId,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findAlert().exists()).toBe(true);
- expect(findAlert().text()).toContain(`#${closedIssueId}`);
- });
+ await nextTick();
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().text()).toContain(`#${closedIssueId}`);
});
});
});
@@ -495,7 +486,7 @@ describe('ErrorDetails', () => {
'/gitlab-org/gitlab-test/commit/7975be0116940bf2ad4321f79d02a55c5f7779aa';
const findGitLabCommitLink = () => wrapper.find(`[href$="${gitlabCommitPath}"]`);
- it('should display a link', () => {
+ it('should display a link', async () => {
mocks.$apollo.queries.error.loading = false;
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
@@ -505,12 +496,11 @@ describe('ErrorDetails', () => {
gitlabCommitPath,
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findGitLabCommitLink().exists()).toBe(true);
- });
+ await nextTick();
+ expect(findGitLabCommitLink().exists()).toBe(true);
});
- it('should not display a link', () => {
+ it('should not display a link', async () => {
mocks.$apollo.queries.error.loading = false;
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
@@ -519,9 +509,8 @@ describe('ErrorDetails', () => {
gitlabCommit: null,
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findGitLabCommitLink().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findGitLabCommitLink().exists()).toBe(false);
});
});
diff --git a/spec/frontend/error_tracking/components/error_tracking_actions_spec.js b/spec/frontend/error_tracking/components/error_tracking_actions_spec.js
index e21c40423c3..7ed4e5f6b05 100644
--- a/spec/frontend/error_tracking/components/error_tracking_actions_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_actions_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue';
describe('Error Tracking Actions', () => {
@@ -37,13 +38,12 @@ describe('Error Tracking Actions', () => {
const findButtons = () => wrapper.findAll(GlButton);
describe('when error status is unresolved', () => {
- it('renders the correct actions buttons to allow ignore and resolve', () => {
+ it('renders the correct actions buttons to allow ignore and resolve', async () => {
expect(findButtons().exists()).toBe(true);
- return wrapper.vm.$nextTick().then(() => {
- expect(findButtons().at(0).attributes('title')).toBe('Ignore');
- expect(findButtons().at(1).attributes('title')).toBe('Resolve');
- });
+ await nextTick();
+ expect(findButtons().at(0).attributes('title')).toBe('Ignore');
+ expect(findButtons().at(1).attributes('title')).toBe('Resolve');
});
});
@@ -52,12 +52,11 @@ describe('Error Tracking Actions', () => {
mountComponent({ error: { status: 'ignored' } });
});
- it('renders the correct action button to undo ignore', () => {
+ it('renders the correct action button to undo ignore', async () => {
expect(findButtons().exists()).toBe(true);
- return wrapper.vm.$nextTick().then(() => {
- expect(findButtons().at(0).attributes('title')).toBe('Undo Ignore');
- });
+ await nextTick();
+ expect(findButtons().at(0).attributes('title')).toBe('Undo Ignore');
});
});
@@ -66,12 +65,11 @@ describe('Error Tracking Actions', () => {
mountComponent({ error: { status: 'resolved' } });
});
- it('renders the correct action button to undo unresolve', () => {
+ it('renders the correct action button to undo unresolve', async () => {
expect(findButtons().exists()).toBe(true);
- return wrapper.vm.$nextTick().then(() => {
- expect(findButtons().at(1).attributes('title')).toBe('Unresolve');
- });
+ await nextTick();
+ expect(findButtons().at(1).attributes('title')).toBe('Unresolve');
});
});
});
diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
index fc89e778127..d4d145b5840 100644
--- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
@@ -1,6 +1,6 @@
import { GlEmptyState, GlLoadingIcon, GlFormInput, GlPagination, GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children';
import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue';
@@ -316,15 +316,14 @@ describe('ErrorTrackingList', () => {
expect(findRecentSearchesDropdown().text()).toContain("You don't have any recent searches");
});
- it('shows items', () => {
+ it('shows items', async () => {
store.state.list.recentSearches = ['great', 'search'];
- return wrapper.vm.$nextTick().then(() => {
- const dropdownItems = wrapper.findAll('.filtered-search-box li');
- expect(dropdownItems.length).toBe(3);
- expect(dropdownItems.at(0).text()).toBe('great');
- expect(dropdownItems.at(1).text()).toBe('search');
- });
+ await nextTick();
+ const dropdownItems = wrapper.findAll('.filtered-search-box li');
+ expect(dropdownItems.length).toBe(3);
+ expect(dropdownItems.at(0).text()).toBe('great');
+ expect(dropdownItems.at(1).text()).toBe('search');
});
describe('clear', () => {
@@ -336,23 +335,21 @@ describe('ErrorTrackingList', () => {
expect(clearRecentButton().exists()).toBe(false);
});
- it('is visible when list has items', () => {
+ it('is visible when list has items', async () => {
store.state.list.recentSearches = ['some', 'searches'];
- return wrapper.vm.$nextTick().then(() => {
- expect(clearRecentButton().exists()).toBe(true);
- expect(clearRecentButton().text()).toBe('Clear recent searches');
- });
+ await nextTick();
+ expect(clearRecentButton().exists()).toBe(true);
+ expect(clearRecentButton().text()).toBe('Clear recent searches');
});
- it('clears items on click', () => {
+ it('clears items on click', async () => {
store.state.list.recentSearches = ['some', 'searches'];
- return wrapper.vm.$nextTick().then(() => {
- clearRecentButton().vm.$emit('click');
+ await nextTick();
+ clearRecentButton().vm.$emit('click');
- expect(actions.clearRecentSearches).toHaveBeenCalledTimes(1);
- });
+ expect(actions.clearRecentSearches).toHaveBeenCalledTimes(1);
});
});
});
@@ -387,7 +384,7 @@ describe('ErrorTrackingList', () => {
describe('and the user is not on the first page', () => {
describe('and the previous button is clicked', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.list.loading = false;
mountComponent({
stubs: {
@@ -398,7 +395,7 @@ describe('ErrorTrackingList', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ pageValue: 2 });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('fetches the previous page of results', () => {
diff --git a/spec/frontend/error_tracking_settings/components/app_spec.js b/spec/frontend/error_tracking_settings/components/app_spec.js
index a67e927910e..4d19ec047ef 100644
--- a/spec/frontend/error_tracking_settings/components/app_spec.js
+++ b/spec/frontend/error_tracking_settings/components/app_spec.js
@@ -79,12 +79,11 @@ describe('error tracking settings app', () => {
expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeFalsy();
});
- it('disables the button when saving', () => {
+ it('disables the button when saving', async () => {
store.state.settingsLoading = true;
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.find('.js-error-tracking-button').attributes('disabled')).toBeTruthy();
});
});
diff --git a/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js b/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
index bf33d76d834..1ba5a505f57 100644
--- a/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
+++ b/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
@@ -1,6 +1,6 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { pick, clone } from 'lodash';
import Vuex from 'vuex';
import ProjectDropdown from '~/error_tracking_settings/components/project_dropdown.vue';
@@ -63,10 +63,10 @@ describe('error tracking settings project dropdown', () => {
});
describe('populated project list', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.setProps({ projects: clone(projectList), hasProjects: true });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('renders the dropdown', () => {
@@ -83,9 +83,9 @@ describe('error tracking settings project dropdown', () => {
describe('selected project', () => {
const selectedProject = clone(projectList[0]);
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.setProps({ projects: clone(projectList), selectedProject, hasProjects: true });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not show helper text', () => {
@@ -95,13 +95,13 @@ describe('error tracking settings project dropdown', () => {
});
describe('invalid project selected', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.setProps({
projects: clone(projectList),
selectedProject: staleProject,
isProjectInvalid: true,
});
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays a error', () => {
diff --git a/spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js b/spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js
index f244da228b3..4a0242b4a46 100644
--- a/spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js
+++ b/spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js
@@ -1,5 +1,6 @@
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
+import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import Component from '~/feature_flags/components/configure_feature_flags_modal.vue';
@@ -56,7 +57,7 @@ describe('Configure Feature Flags Modal', () => {
it('should emit a `token` event when clicking on the Primary action', async () => {
findGlModal().vm.$emit('secondary', mockEvent);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('token')).toEqual([[]]);
expect(mockEvent.preventDefault).toHaveBeenCalled();
});
@@ -64,7 +65,7 @@ describe('Configure Feature Flags Modal', () => {
it('should clear the project name input after generating the token', async () => {
findProjectNameInput().vm.$emit('input', provide.projectName);
findGlModal().vm.$emit('primary', mockEvent);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findProjectNameInput().attributes('value')).toBe('');
});
@@ -116,7 +117,7 @@ describe('Configure Feature Flags Modal', () => {
it('should enable the secondary action', async () => {
findProjectNameInput().vm.$emit('input', provide.projectName);
- await wrapper.vm.$nextTick();
+ await nextTick();
const [{ disabled }] = findSecondaryAction().attributes;
expect(disabled).toBe(false);
});
diff --git a/spec/frontend/feature_flags/components/edit_feature_flag_spec.js b/spec/frontend/feature_flags/components/edit_feature_flag_spec.js
index 721b7249abc..05709cd05e6 100644
--- a/spec/frontend/feature_flags/components/edit_feature_flag_spec.js
+++ b/spec/frontend/feature_flags/components/edit_feature_flag_spec.js
@@ -1,7 +1,7 @@
import { GlToggle, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -12,6 +12,7 @@ import createStore from '~/feature_flags/store/edit';
import axios from '~/lib/utils/axios_utils';
Vue.use(Vuex);
+
describe('Edit feature flag form', () => {
let wrapper;
let mock;
@@ -66,13 +67,12 @@ describe('Edit feature flag form', () => {
});
describe('with error', () => {
- it('should render the error', () => {
+ it('should render the error', async () => {
store.dispatch('receiveUpdateFeatureFlagError', { message: ['The name is required'] });
- return wrapper.vm.$nextTick(() => {
- const warningGlAlert = findWarningGlAlert();
- expect(warningGlAlert.exists()).toEqual(true);
- expect(warningGlAlert.text()).toContain('The name is required');
- });
+ await nextTick();
+ const warningGlAlert = findWarningGlAlert();
+ expect(warningGlAlert.exists()).toEqual(true);
+ expect(warningGlAlert.text()).toContain('The name is required');
});
});
diff --git a/spec/frontend/feature_flags/components/empty_state_spec.js b/spec/frontend/feature_flags/components/empty_state_spec.js
index 86d0c1a05fd..4ac82ae44a6 100644
--- a/spec/frontend/feature_flags/components/empty_state_spec.js
+++ b/spec/frontend/feature_flags/components/empty_state_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlEmptyState, GlLink, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import EmptyState from '~/feature_flags/components/empty_state.vue';
const DEFAULT_PROPS = {
@@ -123,7 +124,7 @@ describe('feature_flags/components/feature_flags_tab.vue', () => {
beforeEach(async () => {
wrapper = factory();
- await wrapper.vm.$nextTick();
+ await nextTick();
slot = wrapper.find('[data-testid="test-slot"]');
});
diff --git a/spec/frontend/feature_flags/components/environments_dropdown_spec.js b/spec/frontend/feature_flags/components/environments_dropdown_spec.js
index 9194db3a182..cca472012e9 100644
--- a/spec/frontend/feature_flags/components/environments_dropdown_spec.js
+++ b/spec/frontend/feature_flags/components/environments_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlButton, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import { TEST_HOST } from 'spec/test_constants';
import EnvironmentsDropdown from '~/feature_flags/components/environments_dropdown.vue';
@@ -54,7 +55,7 @@ describe('Feature flags > Environments dropdown ', () => {
factory();
findEnvironmentSearchInput().vm.$emit('focus');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find('.dropdown-content > ul').exists()).toBe(true);
expect(wrapper.findAll('.dropdown-content > ul > li').exists()).toBe(true);
});
@@ -66,7 +67,7 @@ describe('Feature flags > Environments dropdown ', () => {
factory();
findEnvironmentSearchInput().vm.$emit('keyup');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find('.dropdown-content > ul').exists()).toBe(true);
expect(wrapper.findAll('.dropdown-content > ul > li').exists()).toBe(true);
});
@@ -80,7 +81,7 @@ describe('Feature flags > Environments dropdown ', () => {
findEnvironmentSearchInput().vm.$emit('focus');
findEnvironmentSearchInput().vm.$emit('input', 'production');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets filter value', () => {
@@ -103,7 +104,7 @@ describe('Feature flags > Environments dropdown ', () => {
.filter((b) => b.text() === 'production')
.at(0);
button.vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('selectEnvironment')).toEqual([['production']]);
});
});
@@ -111,7 +112,7 @@ describe('Feature flags > Environments dropdown ', () => {
describe('on click clear button', () => {
beforeEach(async () => {
wrapper.find(GlButton).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('resets filter value', () => {
@@ -132,12 +133,12 @@ describe('Feature flags > Environments dropdown ', () => {
findEnvironmentSearchInput().vm.$emit('focus');
findEnvironmentSearchInput().vm.$emit('input', 'production');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('emits create event', async () => {
wrapper.findAll(GlButton).at(0).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('createClicked')).toEqual([['production']]);
});
});
diff --git a/spec/frontend/feature_flags/components/feature_flags_spec.js b/spec/frontend/feature_flags/components/feature_flags_spec.js
index 141db7c0eb3..728c6abb23a 100644
--- a/spec/frontend/feature_flags/components/feature_flags_spec.js
+++ b/spec/frontend/feature_flags/components/feature_flags_spec.js
@@ -1,6 +1,6 @@
import { GlAlert, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import MockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
@@ -172,7 +172,7 @@ describe('Feature flags', () => {
factory();
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
emptyState = wrapper.findComponent(GlEmptyState);
});
diff --git a/spec/frontend/feature_flags/components/feature_flags_table_spec.js b/spec/frontend/feature_flags/components/feature_flags_table_spec.js
index d06d60ae310..99864a95f59 100644
--- a/spec/frontend/feature_flags/components/feature_flags_table_spec.js
+++ b/spec/frontend/feature_flags/components/feature_flags_table_spec.js
@@ -1,5 +1,6 @@
import { GlToggle, GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper';
import { mockTracking } from 'helpers/tracking_helper';
import FeatureFlagsTable from '~/feature_flags/components/feature_flags_table.vue';
@@ -148,13 +149,12 @@ describe('Feature flag table', () => {
});
});
- it('should trigger a toggle event', () => {
+ it('should trigger a toggle event', async () => {
toggle.vm.$emit('change');
const flag = { ...props.featureFlags[0], active: !props.featureFlags[0].active };
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]);
- });
+ await nextTick();
+ expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]);
});
it('tracks a click', () => {
diff --git a/spec/frontend/feature_flags/components/form_spec.js b/spec/frontend/feature_flags/components/form_spec.js
index c0f9638390a..3ad1225906b 100644
--- a/spec/frontend/feature_flags/components/form_spec.js
+++ b/spec/frontend/feature_flags/components/form_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Api from '~/api';
import Form from '~/feature_flags/components/form.vue';
@@ -126,28 +127,26 @@ describe('feature flag form', () => {
expect(wrapper.findAll(Strategy)).toHaveLength(2);
});
- it('adds an all users strategy when clicking the Add button', () => {
+ it('adds an all users strategy when clicking the Add button', async () => {
wrapper.find(GlButton).vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- const strategies = wrapper.findAll(Strategy);
+ await nextTick();
+ const strategies = wrapper.findAll(Strategy);
- expect(strategies).toHaveLength(3);
- expect(strategies.at(2).props('strategy')).toEqual(allUsersStrategy);
- });
+ expect(strategies).toHaveLength(3);
+ expect(strategies.at(2).props('strategy')).toEqual(allUsersStrategy);
});
- it('should remove a strategy on delete', () => {
+ it('should remove a strategy on delete', async () => {
const strategy = {
type: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
parameters: { percentage: '30' },
scopes: [],
};
wrapper.find(Strategy).vm.$emit('delete');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.findAll(Strategy)).toHaveLength(1);
- expect(wrapper.find(Strategy).props('strategy')).not.toEqual(strategy);
- });
+ await nextTick();
+ expect(wrapper.findAll(Strategy)).toHaveLength(1);
+ expect(wrapper.find(Strategy).props('strategy')).not.toEqual(strategy);
});
});
});
diff --git a/spec/frontend/feature_flags/components/new_environments_dropdown_spec.js b/spec/frontend/feature_flags/components/new_environments_dropdown_spec.js
index 6342ac0bda7..63fa5d19982 100644
--- a/spec/frontend/feature_flags/components/new_environments_dropdown_spec.js
+++ b/spec/frontend/feature_flags/components/new_environments_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import NewEnvironmentsDropdown from '~/feature_flags/components/new_environments_dropdown.vue';
import axios from '~/lib/utils/axios_utils';
import httpStatusCodes from '~/lib/utils/http_status';
@@ -47,16 +48,13 @@ describe('New Environments Dropdown', () => {
describe('with empty results', () => {
let item;
- beforeEach(() => {
+ beforeEach(async () => {
axiosMock.onGet(TEST_HOST).reply(200, []);
wrapper.find(GlSearchBoxByType).vm.$emit('focus');
wrapper.find(GlSearchBoxByType).vm.$emit('input', TEST_SEARCH);
- return axios
- .waitForAll()
- .then(() => wrapper.vm.$nextTick())
- .then(() => {
- item = wrapper.find(GlDropdownItem);
- });
+ await axios.waitForAll();
+ await nextTick();
+ item = wrapper.find(GlDropdownItem);
});
it('should display a Create item label', () => {
diff --git a/spec/frontend/feature_flags/components/new_feature_flag_spec.js b/spec/frontend/feature_flags/components/new_feature_flag_spec.js
index f14c674353b..9c1657bc0d2 100644
--- a/spec/frontend/feature_flags/components/new_feature_flag_spec.js
+++ b/spec/frontend/feature_flags/components/new_feature_flag_spec.js
@@ -1,6 +1,6 @@
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { TEST_HOST } from 'spec/test_constants';
import Form from '~/feature_flags/components/form.vue';
@@ -51,13 +51,12 @@ describe('New feature flag form', () => {
});
describe('with error', () => {
- it('should render the error', () => {
+ it('should render the error', async () => {
store.dispatch('receiveCreateFeatureFlagError', { message: ['The name is required'] });
- return wrapper.vm.$nextTick(() => {
- const warningGlAlert = findWarningGlAlert();
- expect(warningGlAlert.at(0).exists()).toBe(true);
- expect(warningGlAlert.at(0).text()).toContain('The name is required');
- });
+ await nextTick();
+ const warningGlAlert = findWarningGlAlert();
+ expect(warningGlAlert.at(0).exists()).toBe(true);
+ expect(warningGlAlert.at(0).text()).toContain('The name is required');
});
});
diff --git a/spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js b/spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js
index 07aa456e69e..56b14d80ab3 100644
--- a/spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js
+++ b/spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js
@@ -1,5 +1,6 @@
import { GlFormInput, GlFormSelect } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import FlexibleRollout from '~/feature_flags/components/strategies/flexible_rollout.vue';
import ParameterFormGroup from '~/feature_flags/components/strategies/parameter_form_group.vue';
import { PERCENT_ROLLOUT_GROUP_ID } from '~/feature_flags/constants';
@@ -51,7 +52,7 @@ describe('feature_flags/components/strategies/flexible_rollout.vue', () => {
it('emits a change when the percentage value changes', async () => {
percentageInput.setValue('75');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('change')).toEqual([
[
{
diff --git a/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js b/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
index ebfcba6316b..3b69194494f 100644
--- a/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
+++ b/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
@@ -1,6 +1,6 @@
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import Api from '~/api';
import GitlabUserList from '~/feature_flags/components/strategies/gitlab_user_list.vue';
@@ -71,7 +71,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => {
);
const searchWrapper = wrapper.find(GlSearchBoxByType);
searchWrapper.vm.$emit('input', 'new');
- await wrapper.vm.$nextTick();
+ await nextTick();
const loadingIcon = wrapper.find(GlLoadingIcon);
expect(loadingIcon.exists()).toBe(true);
@@ -79,7 +79,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => {
r({ data: [userList] });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(loadingIcon.exists()).toBe(false);
});
diff --git a/spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js b/spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js
index 442f7faf161..180697e93e4 100644
--- a/spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js
+++ b/spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js
@@ -1,5 +1,6 @@
import { GlFormInput } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import ParameterFormGroup from '~/feature_flags/components/strategies/parameter_form_group.vue';
import PercentRollout from '~/feature_flags/components/strategies/percent_rollout.vue';
import { PERCENT_ROLLOUT_GROUP_ID } from '~/feature_flags/constants';
@@ -39,7 +40,7 @@ describe('~/feature_flags/components/strategies/percent_rollout.vue', () => {
it('emits a change when the value changes', async () => {
input.setValue('75');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('change')).toEqual([
[{ parameters: { percentage: '75', groupId: PERCENT_ROLLOUT_GROUP_ID } }],
]);
diff --git a/spec/frontend/feature_flags/components/strategy_spec.js b/spec/frontend/feature_flags/components/strategy_spec.js
index 2464583b636..aee3873721c 100644
--- a/spec/frontend/feature_flags/components/strategy_spec.js
+++ b/spec/frontend/feature_flags/components/strategy_spec.js
@@ -1,6 +1,6 @@
import { GlAlert, GlFormSelect, GlLink, GlToken, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { last } from 'lodash';
import Vuex from 'vuex';
import Api from '~/api';
@@ -85,11 +85,11 @@ describe('Feature flags strategy', () => {
let propsData;
let strategy;
- beforeEach(() => {
+ beforeEach(async () => {
strategy = { name, parameters: {}, scopes: [] };
propsData = { strategy, index: 0 };
factory({ propsData, provide });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('should set the select to match the strategy name', () => {
@@ -138,19 +138,18 @@ describe('Feature flags strategy', () => {
factory({ propsData, provide });
});
- it('should revert to all-environments scope when last scope is removed', () => {
+ it('should revert to all-environments scope when last scope is removed', async () => {
const token = wrapper.find(GlToken);
token.vm.$emit('close');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.findAll(GlToken)).toHaveLength(0);
- expect(last(wrapper.emitted('change'))).toEqual([
- {
- name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
- parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
- scopes: [{ environmentScope: '*' }],
- },
- ]);
- });
+ await nextTick();
+ expect(wrapper.findAll(GlToken)).toHaveLength(0);
+ expect(last(wrapper.emitted('change'))).toEqual([
+ {
+ name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
+ parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
+ scopes: [{ environmentScope: '*' }],
+ },
+ ]);
});
});
@@ -167,56 +166,52 @@ describe('Feature flags strategy', () => {
factory({ propsData, provide });
});
- it('should change the parameters if a different strategy is chosen', () => {
+ it('should change the parameters if a different strategy is chosen', async () => {
const select = wrapper.find(GlFormSelect);
select.setValue(ROLLOUT_STRATEGY_ALL_USERS);
- return wrapper.vm.$nextTick().then(() => {
- expect(last(wrapper.emitted('change'))).toEqual([
- {
- name: ROLLOUT_STRATEGY_ALL_USERS,
- parameters: {},
- scopes: [{ environmentScope: '*' }],
- },
- ]);
- });
+ await nextTick();
+ expect(last(wrapper.emitted('change'))).toEqual([
+ {
+ name: ROLLOUT_STRATEGY_ALL_USERS,
+ parameters: {},
+ scopes: [{ environmentScope: '*' }],
+ },
+ ]);
});
- it('should display selected scopes', () => {
+ it('should display selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.findAll(GlToken)).toHaveLength(1);
- expect(wrapper.find(GlToken).text()).toBe('production');
- });
+ await nextTick();
+ expect(wrapper.findAll(GlToken)).toHaveLength(1);
+ expect(wrapper.find(GlToken).text()).toBe('production');
});
- it('should display all selected scopes', () => {
+ it('should display all selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production');
dropdown.vm.$emit('add', 'staging');
- return wrapper.vm.$nextTick().then(() => {
- const tokens = wrapper.findAll(GlToken);
- expect(tokens).toHaveLength(2);
- expect(tokens.at(0).text()).toBe('production');
- expect(tokens.at(1).text()).toBe('staging');
- });
+ await nextTick();
+ const tokens = wrapper.findAll(GlToken);
+ expect(tokens).toHaveLength(2);
+ expect(tokens.at(0).text()).toBe('production');
+ expect(tokens.at(1).text()).toBe('staging');
});
- it('should emit selected scopes', () => {
+ it('should emit selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production');
- return wrapper.vm.$nextTick().then(() => {
- expect(last(wrapper.emitted('change'))).toEqual([
- {
- name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
- parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
- scopes: [
- { environmentScope: '*', shouldBeDestroyed: true },
- { environmentScope: 'production' },
- ],
- },
- ]);
- });
+ await nextTick();
+ expect(last(wrapper.emitted('change'))).toEqual([
+ {
+ name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
+ parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
+ scopes: [
+ { environmentScope: '*', shouldBeDestroyed: true },
+ { environmentScope: 'production' },
+ ],
+ },
+ ]);
});
it('should emit a delete if the delete button is clicked', () => {
@@ -236,39 +231,36 @@ describe('Feature flags strategy', () => {
factory({ propsData, provide });
});
- it('should display selected scopes', () => {
+ it('should display selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.findAll(GlToken)).toHaveLength(1);
- expect(wrapper.find(GlToken).text()).toBe('production');
- });
+ await nextTick();
+ expect(wrapper.findAll(GlToken)).toHaveLength(1);
+ expect(wrapper.find(GlToken).text()).toBe('production');
});
- it('should display all selected scopes', () => {
+ it('should display all selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production');
dropdown.vm.$emit('add', 'staging');
- return wrapper.vm.$nextTick().then(() => {
- const tokens = wrapper.findAll(GlToken);
- expect(tokens).toHaveLength(2);
- expect(tokens.at(0).text()).toBe('production');
- expect(tokens.at(1).text()).toBe('staging');
- });
+ await nextTick();
+ const tokens = wrapper.findAll(GlToken);
+ expect(tokens).toHaveLength(2);
+ expect(tokens.at(0).text()).toBe('production');
+ expect(tokens.at(1).text()).toBe('staging');
});
- it('should emit selected scopes', () => {
+ it('should emit selected scopes', async () => {
const dropdown = wrapper.find(NewEnvironmentsDropdown);
dropdown.vm.$emit('add', 'production');
- return wrapper.vm.$nextTick().then(() => {
- expect(last(wrapper.emitted('change'))).toEqual([
- {
- name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
- parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
- scopes: [{ environmentScope: 'production' }],
- },
- ]);
- });
+ await nextTick();
+ expect(last(wrapper.emitted('change'))).toEqual([
+ {
+ name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
+ parameters: { percentage: '50', groupId: PERCENT_ROLLOUT_GROUP_ID },
+ scopes: [{ environmentScope: 'production' }],
+ },
+ ]);
});
});
});
diff --git a/spec/frontend/feature_highlight/feature_highlight_popover_spec.js b/spec/frontend/feature_highlight/feature_highlight_popover_spec.js
index e5e3974e103..650f9eb1bbc 100644
--- a/spec/frontend/feature_highlight/feature_highlight_popover_spec.js
+++ b/spec/frontend/feature_highlight/feature_highlight_popover_spec.js
@@ -1,5 +1,6 @@
import { GlPopover, GlLink, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { POPOVER_TARGET_ID } from '~/feature_highlight/constants';
import { dismiss } from '~/feature_highlight/feature_highlight_helper';
import FeatureHighlightPopover from '~/feature_highlight/feature_highlight_popover.vue';
@@ -71,7 +72,7 @@ describe('feature_highlight/feature_highlight_popover', () => {
it('hides the popover target', async () => {
await findDismissButton().trigger('click');
findPopover().vm.$emit('hidden');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findPopoverTarget().exists()).toBe(false);
});
diff --git a/spec/frontend/frequent_items/components/app_spec.js b/spec/frontend/frequent_items/components/app_spec.js
index a94cb3e2fcc..ba989bf53ab 100644
--- a/spec/frontend/frequent_items/components/app_spec.js
+++ b/spec/frontend/frequent_items/components/app_spec.js
@@ -1,5 +1,5 @@
import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
@@ -97,7 +97,7 @@ describe('Frequent Items App Component', () => {
triggerDropdownOpen();
store.state[TEST_VUEX_MODULE].isLoadingItems = true;
- await wrapper.vm.$nextTick();
+ await nextTick();
const loading = findLoading();
@@ -119,7 +119,7 @@ describe('Frequent Items App Component', () => {
expect(findFrequentItems().length).toBe(1);
triggerDropdownOpen();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findFrequentItems().length).toBe(expectedResult.length);
expect(findFrequentItemsList().props()).toEqual({
@@ -135,7 +135,7 @@ describe('Frequent Items App Component', () => {
mock.onGet(/\/api\/v4\/projects.json(.*)$/).replyOnce(200, mockSearchedProjects.data);
setSearch('gitlab');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findLoading().exists()).toBe(true);
diff --git a/spec/frontend/frequent_items/components/frequent_items_list_spec.js b/spec/frontend/frequent_items/components/frequent_items_list_spec.js
index 5d09a588b1d..beaab1913d0 100644
--- a/spec/frontend/frequent_items/components/frequent_items_list_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_list_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import frequentItemsListComponent from '~/frequent_items/components/frequent_items_list.vue';
import frequentItemsListItemComponent from '~/frequent_items/components/frequent_items_list_item.vue';
@@ -44,7 +44,7 @@ describe('FrequentItemsListComponent', () => {
wrapper.setProps({
items: mockFrequentProjects,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.isListEmpty).toBe(false);
});
@@ -63,7 +63,7 @@ describe('FrequentItemsListComponent', () => {
wrapper.setProps({
isFetchFailed: false,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.listEmptyMessage).toBe('Projects you visit often will appear here');
});
@@ -81,7 +81,7 @@ describe('FrequentItemsListComponent', () => {
wrapper.setProps({
isFetchFailed: false,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.listEmptyMessage).toBe('Sorry, no projects matched your search');
});
@@ -89,25 +89,23 @@ describe('FrequentItemsListComponent', () => {
});
describe('template', () => {
- it('should render component element with list of projects', () => {
+ it('should render component element with list of projects', async () => {
createComponent();
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.classes('frequent-items-list-container')).toBe(true);
- expect(wrapper.findAll({ ref: 'frequentItemsList' })).toHaveLength(1);
- expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(5);
- });
+ await nextTick();
+ expect(wrapper.classes('frequent-items-list-container')).toBe(true);
+ expect(wrapper.findAll({ ref: 'frequentItemsList' })).toHaveLength(1);
+ expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(5);
});
- it('should render component element with empty message', () => {
+ it('should render component element with empty message', async () => {
createComponent({
items: [],
});
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$el.querySelectorAll('li.section-empty')).toHaveLength(1);
- expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(0);
- });
+ await nextTick();
+ expect(wrapper.vm.$el.querySelectorAll('li.section-empty')).toHaveLength(1);
+ expect(wrapper.findAll(frequentItemsListItemComponent)).toHaveLength(0);
});
});
});
diff --git a/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
index e1e2a42d330..d0a4cf70f5f 100644
--- a/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
@@ -1,6 +1,6 @@
import { GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import searchComponent from '~/frequent_items/components/frequent_items_search_input.vue';
@@ -61,7 +61,7 @@ describe('FrequentItemsSearchInputComponent', () => {
findSearchBoxByType().vm.$emit('input', value);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'type_search_query', {
label: 'projects_dropdown_frequent_items_search_input',
diff --git a/spec/frontend/grafana_integration/components/grafana_integration_spec.js b/spec/frontend/grafana_integration/components/grafana_integration_spec.js
index d5338430054..d2111194097 100644
--- a/spec/frontend/grafana_integration/components/grafana_integration_spec.js
+++ b/spec/frontend/grafana_integration/components/grafana_integration_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import createFlash from '~/flash';
@@ -93,29 +94,28 @@ describe('grafana integration component', () => {
},
];
- it('submits form on click', () => {
+ it('submits form on click', async () => {
axios.patch.mockResolvedValue();
findSubmitButton(wrapper).trigger('click');
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
- return wrapper.vm.$nextTick().then(() => expect(refreshCurrentPage).toHaveBeenCalled());
+ await nextTick();
+ expect(refreshCurrentPage).toHaveBeenCalled();
});
- it('creates flash banner on error', () => {
+ it('creates flash banner on error', async () => {
const message = 'mockErrorMessage';
axios.patch.mockRejectedValue({ response: { data: { message } } });
findSubmitButton().trigger('click');
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
- return wrapper.vm
- .$nextTick()
- .then(jest.runAllTicks)
- .then(() =>
- expect(createFlash).toHaveBeenCalledWith({
- message: `There was an error saving your changes. ${message}`,
- }),
- );
+
+ await nextTick();
+ await jest.runAllTicks();
+ expect(createFlash).toHaveBeenCalledWith({
+ message: `There was an error saving your changes. ${message}`,
+ });
});
});
});
diff --git a/spec/frontend/group_settings/components/shared_runners_form_spec.js b/spec/frontend/group_settings/components/shared_runners_form_spec.js
index 617d91178e4..26e9cd39cfd 100644
--- a/spec/frontend/group_settings/components/shared_runners_form_spec.js
+++ b/spec/frontend/group_settings/components/shared_runners_form_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAxiosAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import SharedRunnersForm from '~/group_settings/components/shared_runners_form.vue';
import axios from '~/lib/utils/axios_utils';
@@ -76,7 +77,7 @@ describe('group_settings/components/shared_runners_form', () => {
findEnabledToggle().vm.$emit('change', true);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(isLoadingIconVisible()).toBe(true);
diff --git a/spec/frontend/groups/components/invite_members_banner_spec.js b/spec/frontend/groups/components/invite_members_banner_spec.js
index c81edad499c..ef784018205 100644
--- a/spec/frontend/groups/components/invite_members_banner_spec.js
+++ b/spec/frontend/groups/components/invite_members_banner_spec.js
@@ -1,6 +1,7 @@
import { GlBanner } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import InviteMembersBanner from '~/groups/components/invite_members_banner.vue';
import eventHub from '~/invite_members/event_hub';
@@ -140,7 +141,7 @@ describe('InviteMembersBanner', () => {
expect(wrapper.find(GlBanner).exists()).toBe(true);
wrapper.find(GlBanner).vm.$emit('close');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlBanner).exists()).toBe(false);
});
});
diff --git a/spec/frontend/header_search/components/app_spec.js b/spec/frontend/header_search/components/app_spec.js
index 3200c6614f1..dcbeeeffb2d 100644
--- a/spec/frontend/header_search/components/app_spec.js
+++ b/spec/frontend/header_search/components/app_spec.js
@@ -1,5 +1,5 @@
import { GlSearchBoxByType } from '@gitlab/ui';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import HeaderSearchApp from '~/header_search/components/app.vue';
@@ -202,7 +202,7 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(false);
findHeaderSearchInput().vm.$emit('focus');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findHeaderSearchDropdown().exists()).toBe(true);
});
@@ -211,7 +211,7 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(false);
findHeaderSearchInput().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findHeaderSearchDropdown().exists()).toBe(true);
});
@@ -265,7 +265,7 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(true);
findDropdownKeyboardNavigation().vm.$emit('tab');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findHeaderSearchDropdown().exists()).toBe(false);
});
@@ -284,7 +284,7 @@ describe('HeaderSearchApp', () => {
it(`when currentFocusIndex changes to ${MOCK_INDEX} updates the data to searchOptions[${MOCK_INDEX}]`, async () => {
findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.currentFocusedOption).toBe(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX]);
});
});
@@ -299,7 +299,7 @@ describe('HeaderSearchApp', () => {
it('onKey-enter submits a search', async () => {
findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(visitUrl).toHaveBeenCalledWith(MOCK_SEARCH_QUERY);
});
@@ -316,7 +316,7 @@ describe('HeaderSearchApp', () => {
it('onKey-enter clicks the selected dropdown item rather than submitting a search', async () => {
findDropdownKeyboardNavigation().vm.$emit('change', MOCK_INDEX);
- await wrapper.vm.$nextTick();
+ await nextTick();
findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
expect(visitUrl).toHaveBeenCalledWith(MOCK_DEFAULT_SEARCH_OPTIONS[MOCK_INDEX].url);
});
diff --git a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
index bec0cbc8a5c..502f10ff771 100644
--- a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
@@ -1,6 +1,6 @@
import { GlDropdownItem, GlLoadingIcon, GlAvatar } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import HeaderSearchAutocompleteItems from '~/header_search/components/header_search_autocomplete_items.vue';
import {
@@ -143,7 +143,7 @@ describe('HeaderSearchAutocompleteItems', () => {
wrapper.setProps({ currentFocusedOption: MOCK_SORTED_AUTOCOMPLETE_OPTIONS[0] });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(scrollSpy).toHaveBeenCalledWith(false);
scrollSpy.mockRestore();
diff --git a/spec/frontend/ide/components/branches/search_list_spec.js b/spec/frontend/ide/components/branches/search_list_spec.js
index 35e006a26ce..b6e3274153a 100644
--- a/spec/frontend/ide/components/branches/search_list_spec.js
+++ b/spec/frontend/ide/components/branches/search_list_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import Item from '~/ide/components/branches/item.vue';
import List from '~/ide/components/branches/search_list.vue';
@@ -50,13 +50,12 @@ describe('IDE branches search list', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
- it('renders branches not found when search is not empty and branches list is empty', () => {
+ it('renders branches not found when search is not empty and branches list is empty', async () => {
createComponent({ branches: [] });
wrapper.find('input[type="search"]').setValue('something');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.text()).toContain(__('No branches found'));
- });
+ await nextTick();
+ expect(wrapper.text()).toContain(__('No branches found'));
});
describe('with branches', () => {
diff --git a/spec/frontend/ide/components/commit_sidebar/form_spec.js b/spec/frontend/ide/components/commit_sidebar/form_spec.js
index 83d1bbb842e..2f191d2dac8 100644
--- a/spec/frontend/ide/components/commit_sidebar/form_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/form_spec.js
@@ -1,6 +1,6 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import waitForPromises from 'helpers/wait_for_promises';
@@ -98,7 +98,7 @@ describe('IDE commit form', () => {
it(`at view=${viewFn.name}, ${buttonFn.name} has disabled=${disabled} tooltip=${tooltip}`, async () => {
viewFn();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(buttonFn()).toEqual({
disabled,
@@ -116,7 +116,7 @@ describe('IDE commit form', () => {
goToEditView();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('renders commit button in compact mode', () => {
@@ -135,7 +135,7 @@ describe('IDE commit form', () => {
it('when begin commit button is clicked, shows form', async () => {
findBeginCommitButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForm().exists()).toBe(true);
});
@@ -143,7 +143,7 @@ describe('IDE commit form', () => {
it('when begin commit button is clicked, sets activity view', async () => {
findBeginCommitButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
});
@@ -153,14 +153,14 @@ describe('IDE commit form', () => {
setLastCommitMessage('test');
goToEditView();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForm().exists()).toBe(true);
// Now test that it collapses when lastCommitMsg is cleared
setLastCommitMessage('');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForm().exists()).toBe(false);
});
@@ -177,7 +177,7 @@ describe('IDE commit form', () => {
goToCommitView();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
@@ -188,12 +188,12 @@ describe('IDE commit form', () => {
expect(findForm().exists()).toBe(false);
store.state.stagedFiles = [];
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForm().exists()).toBe(false);
store.state.stagedFiles.push('test');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForm().exists()).toBe(false);
});
@@ -208,7 +208,7 @@ describe('IDE commit form', () => {
goToCommitView();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows form', () => {
@@ -222,7 +222,7 @@ describe('IDE commit form', () => {
describe('when no changed files', () => {
beforeEach(async () => {
store.state.stagedFiles = [];
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('hides form', () => {
@@ -231,7 +231,7 @@ describe('IDE commit form', () => {
it('expands again when staged files are added', async () => {
store.state.stagedFiles.push('test');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForm().exists()).toBe(true);
});
@@ -240,7 +240,7 @@ describe('IDE commit form', () => {
it('updates commitMessage in store on input', async () => {
setCommitMessageInput('testing commit message');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(store.state.commit.commitMessage).toBe('testing commit message');
});
@@ -253,14 +253,14 @@ describe('IDE commit form', () => {
it('resets commitMessage when clicking discard button', async () => {
setCommitMessageInput('testing commit message');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCommitMessageInput().props('text')).toBe('testing commit message');
// Test that commitMessage is cleared on click
findDiscardDraftButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCommitMessageInput().props('text')).toBe('');
});
@@ -274,11 +274,11 @@ describe('IDE commit form', () => {
goToCommitView();
- await wrapper.vm.$nextTick();
+ await nextTick();
setCommitMessageInput('testing commit message');
- await wrapper.vm.$nextTick();
+ await nextTick();
jest.spyOn(store, 'dispatch').mockResolvedValue();
});
@@ -291,7 +291,7 @@ describe('IDE commit form', () => {
it('when cannot push code, submitting does nothing', async () => {
store.state.projects.abcproject.userPermissions.pushCode = false;
- await wrapper.vm.$nextTick();
+ await nextTick();
submitForm();
@@ -309,7 +309,7 @@ describe('IDE commit form', () => {
const error = createError();
store.state.commit.commitError = error;
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(modal.vm.show).toHaveBeenCalled();
expect(modal.props()).toMatchObject({
@@ -342,7 +342,7 @@ describe('IDE commit form', () => {
async ({ commitError, expectedActions }) => {
store.state.commit.commitError = commitError('test message');
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.find(GlModal).vm.$emit('ok');
diff --git a/spec/frontend/ide/components/error_message_spec.js b/spec/frontend/ide/components/error_message_spec.js
index 28278aa656f..17568158131 100644
--- a/spec/frontend/ide/components/error_message_spec.js
+++ b/spec/frontend/ide/components/error_message_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ErrorMessage from '~/ide/components/error_message.vue';
@@ -86,19 +86,15 @@ describe('IDE error message component', () => {
expect(actionMock).toHaveBeenCalledWith(message.actionPayload);
});
- it('does not dispatch action when already loading', () => {
+ it('does not dispatch action when already loading', async () => {
findActionButton().trigger('click');
actionMock.mockReset();
- return wrapper.vm.$nextTick(() => {
- findActionButton().trigger('click');
-
- return wrapper.vm.$nextTick().then(() => {
- expect(actionMock).not.toHaveBeenCalled();
- });
- });
+ findActionButton().trigger('click');
+ await nextTick();
+ expect(actionMock).not.toHaveBeenCalled();
});
- it('shows loading icon when loading', () => {
+ it('shows loading icon when loading', async () => {
let resolveAction;
actionMock.mockImplementation(
() =>
@@ -108,19 +104,16 @@ describe('IDE error message component', () => {
);
findActionButton().trigger('click');
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
- resolveAction();
- });
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(true);
+ resolveAction();
});
- it('hides loading icon when operation finishes', () => {
+ it('hides loading icon when operation finishes', async () => {
findActionButton().trigger('click');
- return actionMock()
- .then(() => wrapper.vm.$nextTick())
- .then(() => {
- expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(false);
- });
+ await actionMock();
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).isVisible()).toBe(false);
});
});
});
diff --git a/spec/frontend/ide/components/file_templates/dropdown_spec.js b/spec/frontend/ide/components/file_templates/dropdown_spec.js
index 426a65dd918..e54b322b9db 100644
--- a/spec/frontend/ide/components/file_templates/dropdown_spec.js
+++ b/spec/frontend/ide/components/file_templates/dropdown_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import $ from 'jquery';
import Vuex from 'vuex';
import Dropdown from '~/ide/components/file_templates/dropdown.vue';
@@ -54,15 +54,14 @@ describe('IDE file templates dropdown component', () => {
wrapper = null;
});
- it('calls clickItem on click', () => {
+ it('calls clickItem on click', async () => {
const itemData = { name: 'test.yml ' };
createComponent({ props: { data: [itemData] } });
const item = findItemButtons().at(0);
item.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().click[0][0]).toBe(itemData);
- });
+ await nextTick();
+ expect(wrapper.emitted().click[0][0]).toBe(itemData);
});
it('renders dropdown title', () => {
@@ -111,7 +110,7 @@ describe('IDE file templates dropdown component', () => {
expect(items.wrappers.map((x) => x.text())).toEqual(templates.map((x) => x.name));
});
- it('searches template data', () => {
+ it('searches template data', async () => {
const templates = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }];
const matches = ['match 1', 'match 2'];
createComponent({
@@ -119,12 +118,11 @@ describe('IDE file templates dropdown component', () => {
state: { templates },
});
findSearch().setValue('match');
- return wrapper.vm.$nextTick().then(() => {
- const items = findItemButtons();
+ await nextTick();
+ const items = findItemButtons();
- expect(items.length).toBe(matches.length);
- expect(items.wrappers.map((x) => x.text())).toEqual(matches);
- });
+ expect(items.length).toBe(matches.length);
+ expect(items.wrappers.map((x) => x.text())).toEqual(matches);
});
it('does not render input when `searchable` is true & `showLoading` is true', () => {
@@ -159,17 +157,16 @@ describe('IDE file templates dropdown component', () => {
expect(findSearch().exists()).toBe(true);
});
- it('searches data', () => {
+ it('searches data', async () => {
const data = [{ name: 'match 1' }, { name: 'other' }, { name: 'match 2' }];
const matches = ['match 1', 'match 2'];
createComponent({ props: { searchable: true, data } });
findSearch().setValue('match');
- return wrapper.vm.$nextTick().then(() => {
- const items = findItemButtons();
+ await nextTick();
+ const items = findItemButtons();
- expect(items.length).toBe(matches.length);
- expect(items.wrappers.map((x) => x.text())).toEqual(matches);
- });
+ expect(items.length).toBe(matches.length);
+ expect(items.wrappers.map((x) => x.text())).toEqual(matches);
});
});
});
diff --git a/spec/frontend/ide/components/ide_file_row_spec.js b/spec/frontend/ide/components/ide_file_row_spec.js
index 5f287078aa1..baf3d7cca9d 100644
--- a/spec/frontend/ide/components/ide_file_row_spec.js
+++ b/spec/frontend/ide/components/ide_file_row_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import FileRowExtra from '~/ide/components/file_row_extra.vue';
import IdeFileRow from '~/ide/components/ide_file_row.vue';
@@ -43,7 +43,7 @@ describe('Ide File Row component', () => {
const findFileRow = () => wrapper.find(FileRow);
const hasDropdownOpen = () => findFileRowExtra().props('dropdownOpen');
- it('fileRow component has listeners', () => {
+ it('fileRow component has listeners', async () => {
const toggleTreeOpen = jest.fn();
createComponent(
{},
@@ -56,9 +56,8 @@ describe('Ide File Row component', () => {
findFileRow().vm.$emit('toggleTreeOpen');
- return wrapper.vm.$nextTick().then(() => {
- expect(toggleTreeOpen).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(toggleTreeOpen).toHaveBeenCalled();
});
describe('default', () => {
@@ -85,32 +84,30 @@ describe('Ide File Row component', () => {
});
describe('with open dropdown', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createComponent();
findFileRowExtra().vm.$emit('toggle', true);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows open dropdown', () => {
expect(hasDropdownOpen()).toBe(true);
});
- it('hides dropdown when mouseleave', () => {
+ it('hides dropdown when mouseleave', async () => {
findFileRow().vm.$emit('mouseleave');
- return wrapper.vm.$nextTick().then(() => {
- expect(hasDropdownOpen()).toEqual(false);
- });
+ await nextTick();
+ expect(hasDropdownOpen()).toEqual(false);
});
- it('hides dropdown on toggle', () => {
+ it('hides dropdown on toggle', async () => {
findFileRowExtra().vm.$emit('toggle', false);
- return wrapper.vm.$nextTick().then(() => {
- expect(hasDropdownOpen()).toEqual(false);
- });
+ await nextTick();
+ expect(hasDropdownOpen()).toEqual(false);
});
});
});
diff --git a/spec/frontend/ide/components/ide_review_spec.js b/spec/frontend/ide/components/ide_review_spec.js
index 47270b6e1e9..13d20761263 100644
--- a/spec/frontend/ide/components/ide_review_spec.js
+++ b/spec/frontend/ide/components/ide_review_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { keepAlive } from 'helpers/keep_alive_component_helper';
import { trimText } from 'helpers/text_helper';
@@ -74,14 +74,14 @@ describe('IDE review mode', () => {
});
describe('merge request', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.currentMergeRequestId = '1';
store.state.projects.abcproject.mergeRequests['1'] = {
iid: 123,
web_url: 'testing123',
};
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('renders edit dropdown', () => {
@@ -91,7 +91,7 @@ describe('IDE review mode', () => {
it('renders merge request link & IID', async () => {
store.state.viewer = 'mrdiff';
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(trimText(wrapper.text())).toContain('Merge request (!123)');
});
@@ -99,7 +99,7 @@ describe('IDE review mode', () => {
it('changes text to latest changes when viewer is not mrdiff', async () => {
store.state.viewer = 'diff';
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.text()).toContain('Latest changes');
});
diff --git a/spec/frontend/ide/components/ide_side_bar_spec.js b/spec/frontend/ide/components/ide_side_bar_spec.js
index af8f6b79c7f..34f14ef23a4 100644
--- a/spec/frontend/ide/components/ide_side_bar_spec.js
+++ b/spec/frontend/ide/components/ide_side_bar_spec.js
@@ -1,6 +1,6 @@
import { GlSkeletonLoading } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import IdeReview from '~/ide/components/ide_review.vue';
@@ -45,7 +45,7 @@ describe('IdeSidebar', () => {
store.state.loading = true;
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.findAll(GlSkeletonLoading)).toHaveLength(3);
});
@@ -60,7 +60,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.review.name;
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(IdeReview).exists()).toBe(true);
@@ -68,7 +68,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.commit.name;
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(IdeReview).exists()).toBe(false);
@@ -84,7 +84,7 @@ describe('IdeSidebar', () => {
view,
});
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(tree);
expect(wrapper.find(IdeReview).exists()).toBe(review);
@@ -99,7 +99,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.commit.name;
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(IdeTree).exists()).toBe(false);
expect(wrapper.find(RepoCommitSection).exists()).toBe(true);
@@ -107,7 +107,7 @@ describe('IdeSidebar', () => {
store.state.currentActivityView = leftSidebarViews.edit.name;
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
// reference to the elements remains the same, meaning the components were kept alive
expect(wrapper.find(IdeTree).element).toEqual(ideTreeComponent);
diff --git a/spec/frontend/ide/components/jobs/stage_spec.js b/spec/frontend/ide/components/jobs/stage_spec.js
index 9accd81a2ba..f158c59cd32 100644
--- a/spec/frontend/ide/components/jobs/stage_spec.js
+++ b/spec/frontend/ide/components/jobs/stage_spec.js
@@ -1,5 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Item from '~/ide/components/jobs/item.vue';
import Stage from '~/ide/components/jobs/stage.vue';
import { stages, jobs } from '../../mock_data';
@@ -47,23 +48,21 @@ describe('IDE pipeline stage', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
- it('emits toggleCollaped event with stage id when clicking header', () => {
+ it('emits toggleCollaped event with stage id when clicking header', async () => {
const id = 5;
createComponent({ stage: { ...defaultProps.stage, id } });
findHeader().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id);
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id);
});
- it('emits clickViewLog entity with job', () => {
+ it('emits clickViewLog entity with job', async () => {
const [job] = defaultProps.stage.jobs;
createComponent();
wrapper.findAll(Item).at(0).vm.$emit('clickViewLog', job);
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().clickViewLog[0][0]).toBe(job);
- });
+ await nextTick();
+ expect(wrapper.emitted().clickViewLog[0][0]).toBe(job);
});
it('renders stage details & icon', () => {
diff --git a/spec/frontend/ide/components/merge_requests/list_spec.js b/spec/frontend/ide/components/merge_requests/list_spec.js
index 81c7321b22c..583671a0af6 100644
--- a/spec/frontend/ide/components/merge_requests/list_spec.js
+++ b/spec/frontend/ide/components/merge_requests/list_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import Item from '~/ide/components/merge_requests/item.vue';
import List from '~/ide/components/merge_requests/list.vue';
@@ -66,33 +66,28 @@ describe('IDE merge requests list', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
- it('renders no search results text when search is not empty', () => {
+ it('renders no search results text when search is not empty', async () => {
createComponent();
findTokenedInput().vm.$emit('input', 'something');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.text()).toContain('No merge requests found');
- });
+ await nextTick();
+ expect(wrapper.text()).toContain('No merge requests found');
});
- it('clicking on search type, sets currentSearchType and loads merge requests', () => {
+ it('clicking on search type, sets currentSearchType and loads merge requests', async () => {
createComponent();
findTokenedInput().vm.$emit('focus');
- return wrapper.vm
- .$nextTick()
- .then(() => {
- findSearchTypeButtons().at(0).trigger('click');
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- const searchType = wrapper.vm.$options.searchTypes[0];
+ await nextTick();
+ findSearchTypeButtons().at(0).trigger('click');
- expect(findTokenedInput().props('tokens')).toEqual([searchType]);
- expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), {
- type: searchType.type,
- search: '',
- });
- });
+ await nextTick();
+ const searchType = wrapper.vm.$options.searchTypes[0];
+
+ expect(findTokenedInput().props('tokens')).toEqual([searchType]);
+ expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), {
+ type: searchType.type,
+ search: '',
+ });
});
describe('with merge requests', () => {
@@ -119,16 +114,15 @@ describe('IDE merge requests list', () => {
});
describe('when searching merge requests', () => {
- it('calls `loadMergeRequests` on input in search field', () => {
+ it('calls `loadMergeRequests` on input in search field', async () => {
createComponent(defaultStateWithMergeRequests);
const input = findTokenedInput();
input.vm.$emit('input', 'something');
- return wrapper.vm.$nextTick().then(() => {
- expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), {
- search: 'something',
- type: '',
- });
+ await nextTick();
+ expect(fetchMergeRequestsMock).toHaveBeenCalledWith(expect.any(Object), {
+ search: 'something',
+ type: '',
});
});
});
@@ -143,9 +137,9 @@ describe('IDE merge requests list', () => {
});
describe('without search value', () => {
- beforeEach(() => {
+ beforeEach(async () => {
input.vm.$emit('focus');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows search types', () => {
@@ -155,22 +149,20 @@ describe('IDE merge requests list', () => {
);
});
- it('hides search types when search changes', () => {
+ it('hides search types when search changes', async () => {
input.vm.$emit('input', 'something');
- return wrapper.vm.$nextTick().then(() => {
- expect(findSearchTypeButtons().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findSearchTypeButtons().exists()).toBe(false);
});
describe('with search type', () => {
- beforeEach(() => {
+ beforeEach(async () => {
findSearchTypeButtons().at(0).trigger('click');
- return wrapper.vm
- .$nextTick()
- .then(() => input.vm.$emit('focus'))
- .then(() => wrapper.vm.$nextTick());
+ await nextTick();
+ await input.vm.$emit('focus');
+ await nextTick();
});
it('does not show search types', () => {
@@ -180,10 +172,10 @@ describe('IDE merge requests list', () => {
});
describe('with search value', () => {
- beforeEach(() => {
+ beforeEach(async () => {
input.vm.$emit('input', 'something');
input.vm.$emit('focus');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not show search types', () => {
diff --git a/spec/frontend/ide/components/panes/right_spec.js b/spec/frontend/ide/components/panes/right_spec.js
index da9f0286cfb..d12acd6dc4c 100644
--- a/spec/frontend/ide/components/panes/right_spec.js
+++ b/spec/frontend/ide/components/panes/right_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
import RightPane from '~/ide/components/panes/right.vue';
@@ -86,19 +86,18 @@ describe('ide/components/panes/right.vue', () => {
createComponent();
});
- it('adds terminal tab', () => {
+ it('adds terminal tab', async () => {
store.state.terminal.isVisible = true;
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
- expect.arrayContaining([
- expect.objectContaining({
- show: true,
- title: 'Terminal',
- }),
- ]),
- );
- });
+ await nextTick();
+ expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ show: true,
+ title: 'Terminal',
+ }),
+ ]),
+ );
});
it('hides terminal tab when not visible', () => {
diff --git a/spec/frontend/ide/components/preview/clientside_spec.js b/spec/frontend/ide/components/preview/clientside_spec.js
index 08e9a069cf6..0c0ddcbbfd3 100644
--- a/spec/frontend/ide/components/preview/clientside_spec.js
+++ b/spec/frontend/ide/components/preview/clientside_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import smooshpack from 'smooshpack';
import Vuex from 'vuex';
import Clientside from '~/ide/components/preview/clientside.vue';
@@ -351,39 +351,36 @@ describe('IDE clientside preview', () => {
});
describe('template', () => {
- it('renders ide-preview element when showPreview is true', () => {
+ it('renders ide-preview element when showPreview is true', async () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('#ide-preview').exists()).toBe(true);
- });
+ await nextTick();
+ expect(wrapper.find('#ide-preview').exists()).toBe(true);
});
- it('renders empty state', () => {
+ it('renders empty state', async () => {
createComponent();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: false });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain(
- 'Preview your web application using Web IDE client-side evaluation.',
- );
- });
+ await nextTick();
+ expect(wrapper.text()).toContain(
+ 'Preview your web application using Web IDE client-side evaluation.',
+ );
});
- it('renders loading icon', () => {
+ it('renders loading icon', async () => {
createComponent();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ loading: true });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
- });
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
});
diff --git a/spec/frontend/ide/components/preview/navigator_spec.js b/spec/frontend/ide/components/preview/navigator_spec.js
index ee760364c7e..a199f4704f7 100644
--- a/spec/frontend/ide/components/preview/navigator_spec.js
+++ b/spec/frontend/ide/components/preview/navigator_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { listen } from 'codesandbox-api';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import ClientsideNavigator from '~/ide/components/preview/navigator.vue';
@@ -29,31 +30,28 @@ describe('IDE clientside preview navigator', () => {
wrapper.destroy();
});
- it('renders readonly URL bar', () => {
+ it('renders readonly URL bar', async () => {
listenHandler({ type: 'urlchange', url: manager.bundlerURL });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('input[readonly]').element.value).toBe('/');
- });
+ await nextTick();
+ expect(wrapper.find('input[readonly]').element.value).toBe('/');
});
it('renders loading icon by default', () => {
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
- it('removes loading icon when done event is fired', () => {
+ it('removes loading icon when done event is fired', async () => {
listenHandler({ type: 'done' });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
});
- it('does not count visiting same url multiple times', () => {
+ it('does not count visiting same url multiple times', async () => {
listenHandler({ type: 'done' });
listenHandler({ type: 'done', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'done', url: `${TEST_HOST}/url1` });
- return wrapper.vm.$nextTick().then(() => {
- expect(findBackButton().attributes('disabled')).toBe('disabled');
- });
+ await nextTick();
+ expect(findBackButton().attributes('disabled')).toBe('disabled');
});
it('unsubscribes from listen on destroy', () => {
@@ -64,107 +62,93 @@ describe('IDE clientside preview navigator', () => {
});
describe('back button', () => {
- beforeEach(() => {
+ beforeEach(async () => {
listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url: TEST_HOST });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('is disabled by default', () => {
expect(findBackButton().attributes('disabled')).toBe('disabled');
});
- it('is enabled when there is previous entry', () => {
+ it('is enabled when there is previous entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
- return wrapper.vm.$nextTick().then(() => {
- findBackButton().trigger('click');
- expect(findBackButton().attributes('disabled')).toBeFalsy();
- });
+ await nextTick();
+ findBackButton().trigger('click');
+ expect(findBackButton().attributes('disabled')).toBeFalsy();
});
- it('is disabled when there is no previous entry', () => {
+ it('is disabled when there is no previous entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
- return wrapper.vm
- .$nextTick()
- .then(() => {
- findBackButton().trigger('click');
-
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- expect(findBackButton().attributes('disabled')).toBe('disabled');
- });
+
+ await nextTick();
+ findBackButton().trigger('click');
+
+ await nextTick();
+ expect(findBackButton().attributes('disabled')).toBe('disabled');
});
- it('updates manager iframe src', () => {
+ it('updates manager iframe src', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
- return wrapper.vm.$nextTick().then(() => {
- findBackButton().trigger('click');
+ await nextTick();
+ findBackButton().trigger('click');
- expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
- });
+ expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
});
});
describe('forward button', () => {
- beforeEach(() => {
+ beforeEach(async () => {
listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url: TEST_HOST });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('is disabled by default', () => {
expect(findForwardButton().attributes('disabled')).toBe('disabled');
});
- it('is enabled when there is next entry', () => {
+ it('is enabled when there is next entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
- return wrapper.vm
- .$nextTick()
- .then(() => {
- findBackButton().trigger('click');
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- expect(findForwardButton().attributes('disabled')).toBeFalsy();
- });
+
+ await nextTick();
+ findBackButton().trigger('click');
+
+ await nextTick();
+ expect(findForwardButton().attributes('disabled')).toBeFalsy();
});
- it('is disabled when there is no next entry', () => {
+ it('is disabled when there is no next entry', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
- return wrapper.vm
- .$nextTick()
- .then(() => {
- findBackButton().trigger('click');
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- findForwardButton().trigger('click');
- return wrapper.vm.$nextTick();
- })
- .then(() => {
- expect(findForwardButton().attributes('disabled')).toBe('disabled');
- });
+
+ await nextTick();
+ findBackButton().trigger('click');
+
+ await nextTick();
+ findForwardButton().trigger('click');
+
+ await nextTick();
+ expect(findForwardButton().attributes('disabled')).toBe('disabled');
});
- it('updates manager iframe src', () => {
+ it('updates manager iframe src', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
- return wrapper.vm.$nextTick().then(() => {
- findBackButton().trigger('click');
+ await nextTick();
+ findBackButton().trigger('click');
- expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
- });
+ expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
});
});
describe('refresh button', () => {
const url = `${TEST_HOST}/some_url`;
- beforeEach(() => {
+ beforeEach(async () => {
listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('calls refresh with current path', () => {
diff --git a/spec/frontend/ide/components/repo_tabs_spec.js b/spec/frontend/ide/components/repo_tabs_spec.js
index 843c00d9943..1cfc1f12745 100644
--- a/spec/frontend/ide/components/repo_tabs_spec.js
+++ b/spec/frontend/ide/components/repo_tabs_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import RepoTabs from '~/ide/components/repo_tabs.vue';
import { createStore } from '~/ide/stores';
@@ -29,17 +29,14 @@ describe('RepoTabs', () => {
wrapper.destroy();
});
- it('renders a list of tabs', (done) => {
+ it('renders a list of tabs', async () => {
store.state.openFiles[0].active = true;
- wrapper.vm.$nextTick(() => {
- const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')];
+ await nextTick();
+ const tabs = [...wrapper.vm.$el.querySelectorAll('.multi-file-tab')];
- expect(tabs.length).toEqual(2);
- expect(tabs[0].parentNode.classList.contains('active')).toEqual(true);
- expect(tabs[1].parentNode.classList.contains('active')).toEqual(false);
-
- done();
- });
+ expect(tabs.length).toEqual(2);
+ expect(tabs[0].parentNode.classList.contains('active')).toEqual(true);
+ expect(tabs[1].parentNode.classList.contains('active')).toEqual(false);
});
});
diff --git a/spec/frontend/ide/components/resizable_panel_spec.js b/spec/frontend/ide/components/resizable_panel_spec.js
index cdd089c5588..55b9423aba8 100644
--- a/spec/frontend/ide/components/resizable_panel_spec.js
+++ b/spec/frontend/ide/components/resizable_panel_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ResizablePanel from '~/ide/components/resizable_panel.vue';
import { SIDE_LEFT, SIDE_RIGHT } from '~/ide/constants';
@@ -99,15 +99,14 @@ describe('~/ide/components/resizable_panel', () => {
});
});
- it('when resizer emits update:size, changes inline width', () => {
+ it('when resizer emits update:size, changes inline width', async () => {
const newSize = TEST_WIDTH - 100;
const resizer = findResizer();
resizer.vm.$emit('update:size', newSize);
- return wrapper.vm.$nextTick().then(() => {
- expect(findInlineStyle()).toBe(createInlineStyle(newSize));
- });
+ await nextTick();
+ expect(findInlineStyle()).toBe(createInlineStyle(newSize));
});
});
});
diff --git a/spec/frontend/ide/components/terminal/session_spec.js b/spec/frontend/ide/components/terminal/session_spec.js
index c988138e9c4..6a70ddb46a8 100644
--- a/spec/frontend/ide/components/terminal/session_spec.js
+++ b/spec/frontend/ide/components/terminal/session_spec.js
@@ -1,6 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import TerminalSession from '~/ide/components/terminal/session.vue';
import Terminal from '~/ide/components/terminal/terminal.vue';
@@ -67,32 +67,30 @@ describe('IDE TerminalSession', () => {
});
[STARTING, PENDING, RUNNING].forEach((status) => {
- it(`show stop button when status is ${status}`, () => {
+ it(`show stop button when status is ${status}`, async () => {
state.session = { status };
factory();
const button = findButton();
button.vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(button.text()).toEqual('Stop Terminal');
- expect(actions.stopSession).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(button.text()).toEqual('Stop Terminal');
+ expect(actions.stopSession).toHaveBeenCalled();
});
});
[STOPPING, STOPPED].forEach((status) => {
- it(`show stop button when status is ${status}`, () => {
+ it(`show stop button when status is ${status}`, async () => {
state.session = { status };
factory();
const button = findButton();
button.vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(button.text()).toEqual('Restart Terminal');
- expect(actions.restartSession).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(button.text()).toEqual('Restart Terminal');
+ expect(actions.restartSession).toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/ide/components/terminal/terminal_controls_spec.js b/spec/frontend/ide/components/terminal/terminal_controls_spec.js
index 416096083f0..71ec0dca89d 100644
--- a/spec/frontend/ide/components/terminal/terminal_controls_spec.js
+++ b/spec/frontend/ide/components/terminal/terminal_controls_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue';
import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
@@ -39,27 +40,25 @@ describe('IDE TerminalControls', () => {
);
});
- it('emits "scroll-up" when click up button', () => {
+ it('emits "scroll-up" when click up button', async () => {
factory({ propsData: { canScrollUp: true } });
expect(wrapper.emitted()).toEqual({});
buttons.at(0).vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('scroll-up')).toEqual([[]]);
- });
+ await nextTick();
+ expect(wrapper.emitted('scroll-up')).toEqual([[]]);
});
- it('emits "scroll-down" when click down button', () => {
+ it('emits "scroll-down" when click down button', async () => {
factory({ propsData: { canScrollDown: true } });
expect(wrapper.emitted()).toEqual({});
buttons.at(1).vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('scroll-down')).toEqual([[]]);
- });
+ await nextTick();
+ expect(wrapper.emitted('scroll-down')).toEqual([[]]);
});
});
diff --git a/spec/frontend/incidents/components/incidents_list_spec.js b/spec/frontend/incidents/components/incidents_list_spec.js
index 48545ffd2d6..1be6007d844 100644
--- a/spec/frontend/incidents/components/incidents_list_spec.js
+++ b/spec/frontend/incidents/components/incidents_list_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlEmptyState } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import IncidentsList from '~/incidents/components/incidents_list.vue';
import {
I18N,
@@ -210,7 +211,7 @@ describe('Incidents List', () => {
it('sets button loading on click', async () => {
findCreateIncidentBtn().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCreateIncidentBtn().attributes('loading')).toBe('true');
});
@@ -233,7 +234,7 @@ describe('Incidents List', () => {
it('should track create new incident button', async () => {
findCreateIncidentBtn().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(Tracking.event).toHaveBeenCalled();
});
});
@@ -263,10 +264,10 @@ describe('Incidents List', () => {
const columnHeader = () => wrapper.find(`[${attr}="${value}"]`);
expect(columnHeader().attributes('aria-sort')).toBe(initialSort);
columnHeader().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(columnHeader().attributes('aria-sort')).toBe(firstSort);
columnHeader().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(columnHeader().attributes('aria-sort')).toBe(nextSort);
},
);
@@ -287,7 +288,7 @@ describe('Incidents List', () => {
it('should track incident creation events', async () => {
findCreateIncidentBtn().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
const { category, action } = trackIncidentCreateNewOptions;
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
diff --git a/spec/frontend/integrations/edit/components/active_checkbox_spec.js b/spec/frontend/integrations/edit/components/active_checkbox_spec.js
index 0dc31616166..c335b593f7d 100644
--- a/spec/frontend/integrations/edit/components/active_checkbox_spec.js
+++ b/spec/frontend/integrations/edit/components/active_checkbox_spec.js
@@ -1,6 +1,7 @@
import { GlFormCheckbox } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
import { createStore } from '~/integrations/edit/store';
@@ -68,7 +69,7 @@ describe('ActiveCheckbox', () => {
it('switches the form value', async () => {
findInputInCheckbox().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findGlFormCheckbox().vm.$attrs.checked).toBe(false);
});
});
diff --git a/spec/frontend/integrations/edit/components/confirmation_modal_spec.js b/spec/frontend/integrations/edit/components/confirmation_modal_spec.js
index 805d3971994..cbe3402727a 100644
--- a/spec/frontend/integrations/edit/components/confirmation_modal_spec.js
+++ b/spec/frontend/integrations/edit/components/confirmation_modal_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import ConfirmationModal from '~/integrations/edit/components/confirmation_modal.vue';
import { createStore } from '~/integrations/edit/store';
@@ -40,7 +41,7 @@ describe('ConfirmationModal', () => {
findGlModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted().submit).toHaveLength(1);
});
diff --git a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
index 18afbf25bf0..33fd08a5959 100644
--- a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
+++ b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
@@ -1,4 +1,5 @@
import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
+import { nextTick } from 'vue';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
@@ -193,7 +194,7 @@ describe('JiraIssuesFields', () => {
await setEnableCheckbox(true);
expect(findJiraForVulnerabilities().attributes('show-full-feature')).toBe('true');
wrapper.setProps({ showJiraVulnerabilitiesIntegration: false });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findJiraForVulnerabilities().attributes('show-full-feature')).toBeUndefined();
});
diff --git a/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js b/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
index 9e01371f542..49fbebb9396 100644
--- a/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
+++ b/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
@@ -1,4 +1,5 @@
import { GlFormCheckbox } from '@gitlab/ui';
+import { nextTick } from 'vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
@@ -71,12 +72,11 @@ describe('JiraTriggerFields', () => {
});
describe('on enable comments', () => {
- it('shows comment detail', () => {
+ it('shows comment detail', async () => {
findCommentSettingsCheckbox().vm.$emit('input', true);
- return wrapper.vm.$nextTick().then(() => {
- expect(findCommentDetail().isVisible()).toBe(true);
- });
+ await nextTick();
+ expect(findCommentDetail().isVisible()).toBe(true);
});
});
});
@@ -107,7 +107,7 @@ describe('JiraTriggerFields', () => {
});
describe('initialJiraIssueTransitionAutomatic is false, initialJiraIssueTransitionId is not set', () => {
- it('selects automatic transitions when enabling transitions', () => {
+ it('selects automatic transitions when enabling transitions', async () => {
createComponent({
initialTriggerCommit: true,
initialEnableComments: true,
@@ -117,11 +117,10 @@ describe('JiraTriggerFields', () => {
expect(checkbox.element.checked).toBe(false);
checkbox.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- const [radio1, radio2] = findIssueTransitionModeRadios().wrappers;
- expect(radio1.element.checked).toBe(true);
- expect(radio2.element.checked).toBe(false);
- });
+ await nextTick();
+ const [radio1, radio2] = findIssueTransitionModeRadios().wrappers;
+ expect(radio1.element.checked).toBe(true);
+ expect(radio2.element.checked).toBe(false);
});
});
diff --git a/spec/frontend/invite_members/components/import_a_project_modal_spec.js b/spec/frontend/invite_members/components/import_a_project_modal_spec.js
index fecbf84fb57..6db881d5c75 100644
--- a/spec/frontend/invite_members/components/import_a_project_modal_spec.js
+++ b/spec/frontend/invite_members/components/import_a_project_modal_spec.js
@@ -1,5 +1,6 @@
import { GlFormGroup, GlSprintf, GlModal } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -91,7 +92,7 @@ describe('ImportAProjectModal', () => {
it('sets isLoading to true when the Invite button is clicked', async () => {
clickImportButton();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findImportButton().props('loading')).toBe(true);
});
@@ -157,7 +158,7 @@ describe('ImportAProjectModal', () => {
clickCancelButton();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(formGroupInvalidFeedback()).toBe('');
expect(formGroupErrorState()).not.toBe(false);
diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js
index 3ab89b3dff2..8b02d916045 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -8,6 +8,7 @@ import {
GlModal,
} from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { stubComponent } from 'helpers/stub_component';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -508,7 +509,7 @@ describe('InviteMembersModal', () => {
findMembersSelect().vm.$emit('clear');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe('');
expect(findMembersFormGroup().props('state')).not.toBe(false);
@@ -518,7 +519,7 @@ describe('InviteMembersModal', () => {
it('clears the error when the cancel button is clicked', async () => {
clickCancelButton();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe('');
expect(findMembersFormGroup().props('state')).not.toBe(false);
@@ -528,7 +529,7 @@ describe('InviteMembersModal', () => {
it('clears the error when the modal is hidden', async () => {
wrapper.findComponent(GlModal).vm.$emit('hide');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(membersFormGroupInvalidFeedback()).toBe('');
expect(findMembersFormGroup().props('state')).not.toBe(false);
diff --git a/spec/frontend/issuable/components/related_issuable_item_spec.js b/spec/frontend/issuable/components/related_issuable_item_spec.js
index 6a896ccd21a..6b48f83041a 100644
--- a/spec/frontend/issuable/components/related_issuable_item_spec.js
+++ b/spec/frontend/issuable/components/related_issuable_item_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import IssueDueDate from '~/boards/components/issue_due_date.vue';
import { formatDate } from '~/lib/utils/datetime_utility';
@@ -105,7 +106,7 @@ describe('RelatedIssuableItem', () => {
state: 'closed',
closedAt: '2018-12-01T00:00:00.00Z',
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(tokenState().classes('issue-token-state-icon-closed')).toBe(true);
});
@@ -140,7 +141,7 @@ describe('RelatedIssuableItem', () => {
closedAt: '2018-12-01T00:00:00.00Z',
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(IssueDueDate).props('closed')).toBe(true);
});
@@ -172,14 +173,14 @@ describe('RelatedIssuableItem', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ removeDisabled: true });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findRemoveButton().attributes('disabled')).toEqual('disabled');
});
it('triggers onRemoveRequest when clicked', async () => {
findRemoveButton().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
const { relatedIssueRemoveRequest } = wrapper.emitted();
expect(relatedIssueRemoveRequest.length).toBe(1);
diff --git a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
index ff6922989cb..2ae32e89605 100644
--- a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
+++ b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
@@ -1,4 +1,5 @@
import { mount, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
import IssueToken from '~/related_issues/components/issue_token.vue';
import { issuableTypesMap, linkedIssueTypesMap, PathIdSeparator } from '~/related_issues/constants';
@@ -194,63 +195,55 @@ describe('AddIssuableForm', () => {
});
describe('when the form is submitted', () => {
- it('emits an event with a "relates_to" link type when the "relates to" radio input selected', (done) => {
+ it('emits an event with a "relates_to" link type when the "relates to" radio input selected', async () => {
jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
wrapper.vm.linkedIssueType = linkedIssueTypesMap.RELATES_TO;
wrapper.vm.onFormSubmit();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
- pendingReferences: '',
- linkedIssueType: linkedIssueTypesMap.RELATES_TO,
- });
- done();
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
+ pendingReferences: '',
+ linkedIssueType: linkedIssueTypesMap.RELATES_TO,
});
});
- it('emits an event with a "blocks" link type when the "blocks" radio input selected', (done) => {
+ it('emits an event with a "blocks" link type when the "blocks" radio input selected', async () => {
jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
wrapper.vm.linkedIssueType = linkedIssueTypesMap.BLOCKS;
wrapper.vm.onFormSubmit();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
- pendingReferences: '',
- linkedIssueType: linkedIssueTypesMap.BLOCKS,
- });
- done();
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
+ pendingReferences: '',
+ linkedIssueType: linkedIssueTypesMap.BLOCKS,
});
});
- it('emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected', (done) => {
+ it('emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected', async () => {
jest.spyOn(wrapper.vm, '$emit').mockImplementation(() => {});
wrapper.vm.linkedIssueType = linkedIssueTypesMap.IS_BLOCKED_BY;
wrapper.vm.onFormSubmit();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
- pendingReferences: '',
- linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY,
- });
- done();
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('addIssuableFormSubmit', {
+ pendingReferences: '',
+ linkedIssueType: linkedIssueTypesMap.IS_BLOCKED_BY,
});
});
- it('shows error message when error is present', (done) => {
+ it('shows error message when error is present', async () => {
const itemAddFailureMessage = 'Something went wrong while submitting.';
wrapper.setProps({
hasError: true,
itemAddFailureMessage,
});
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.gl-field-error').exists()).toBe(true);
- expect(wrapper.find('.gl-field-error').text()).toContain(itemAddFailureMessage);
- done();
- });
+ await nextTick();
+ expect(wrapper.find('.gl-field-error').exists()).toBe(true);
+ expect(wrapper.find('.gl-field-error').text()).toContain(itemAddFailureMessage);
});
});
});
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
index 01de4da7900..b59717a1f60 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
@@ -1,5 +1,6 @@
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import {
defaultProps,
@@ -210,40 +211,37 @@ describe('RelatedIssuesRoot', () => {
}),
);
- it('when canceling and hiding add issuable form', () => {
+ it('when canceling and hiding add issuable form', async () => {
wrapper.vm.onPendingFormCancel();
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.isFormVisible).toEqual(false);
- expect(wrapper.vm.inputValue).toEqual('');
- expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
- });
+ await nextTick();
+ expect(wrapper.vm.isFormVisible).toEqual(false);
+ expect(wrapper.vm.inputValue).toEqual('');
+ expect(wrapper.vm.state.pendingReferences).toHaveLength(0);
});
});
describe('fetchRelatedIssues', () => {
beforeEach(() => createComponent());
- it('sets isFetching while fetching', () => {
+ it('sets isFetching while fetching', async () => {
wrapper.vm.fetchRelatedIssues();
expect(wrapper.vm.isFetching).toEqual(true);
- return waitForPromises().then(() => {
- expect(wrapper.vm.isFetching).toEqual(false);
- });
+ await waitForPromises();
+ expect(wrapper.vm.isFetching).toEqual(false);
});
- it('should fetch related issues', () => {
+ it('should fetch related issues', async () => {
mock.onGet(defaultProps.endpoint).reply(200, [issuable1, issuable2]);
wrapper.vm.fetchRelatedIssues();
- return waitForPromises().then(() => {
- expect(wrapper.vm.state.relatedIssues).toHaveLength(2);
- expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
- expect(wrapper.vm.state.relatedIssues[1].id).toEqual(issuable2.id);
- });
+ await waitForPromises();
+ expect(wrapper.vm.state.relatedIssues).toHaveLength(2);
+ expect(wrapper.vm.state.relatedIssues[0].id).toEqual(issuable1.id);
+ expect(wrapper.vm.state.relatedIssues[1].id).toEqual(issuable2.id);
});
});
diff --git a/spec/frontend/issues/list/components/new_issue_dropdown_spec.js b/spec/frontend/issues/list/components/new_issue_dropdown_spec.js
index 7bec3d13d44..2c8cf9caf5d 100644
--- a/spec/frontend/issues/list/components/new_issue_dropdown_spec.js
+++ b/spec/frontend/issues/list/components/new_issue_dropdown_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
-import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -17,8 +18,7 @@ import {
describe('NewIssueDropdown component', () => {
let wrapper;
- const localVue = createLocalVue();
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const mountComponent = ({
search = '',
@@ -29,7 +29,6 @@ describe('NewIssueDropdown component', () => {
const apolloProvider = createMockApollo(requestHandlers);
return mountFn(NewIssueDropdown, {
- localVue,
apolloProvider,
provide: {
fullPath: 'mushroom-kingdom',
diff --git a/spec/frontend/issues/new/components/title_suggestions_spec.js b/spec/frontend/issues/new/components/title_suggestions_spec.js
index f6b93cc5a62..0a64890e4ca 100644
--- a/spec/frontend/issues/new/components/title_suggestions_spec.js
+++ b/spec/frontend/issues/new/components/title_suggestions_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import TitleSuggestions from '~/issues/new/components/title_suggestions.vue';
import TitleSuggestionsItem from '~/issues/new/components/title_suggestions_item.vue';
@@ -22,12 +23,11 @@ describe('Issue title suggestions component', () => {
wrapper.destroy();
});
- it('does not render with empty search', () => {
+ it('does not render with empty search', async () => {
wrapper.setProps({ search: '' });
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.isVisible()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.isVisible()).toBe(false);
});
describe('with data', () => {
@@ -37,28 +37,26 @@ describe('Issue title suggestions component', () => {
data = { issues: [{ id: 1 }, { id: 2 }] };
});
- it('renders component', () => {
+ it('renders component', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.findAll('li').length).toBe(data.issues.length);
- });
+ await nextTick();
+ expect(wrapper.findAll('li').length).toBe(data.issues.length);
});
- it('does not render with empty search', () => {
+ it('does not render with empty search', async () => {
wrapper.setProps({ search: '' });
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.isVisible()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.isVisible()).toBe(false);
});
- it('does not render when loading', () => {
+ it('does not render when loading', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -66,49 +64,44 @@ describe('Issue title suggestions component', () => {
loading: 1,
});
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.isVisible()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.isVisible()).toBe(false);
});
- it('does not render with empty issues data', () => {
+ it('does not render with empty issues data', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ issues: [] });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.isVisible()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.isVisible()).toBe(false);
});
- it('renders list of issues', () => {
+ it('renders list of issues', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.findAll(TitleSuggestionsItem).length).toBe(2);
- });
+ await nextTick();
+ expect(wrapper.findAll(TitleSuggestionsItem).length).toBe(2);
});
- it('adds margin class to first item', () => {
+ it('adds margin class to first item', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.findAll('li').at(0).classes()).toContain('gl-mb-3');
- });
+ await nextTick();
+ expect(wrapper.findAll('li').at(0).classes()).toContain('gl-mb-3');
});
- it('does not add margin class to last item', () => {
+ it('does not add margin class to last item', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData(data);
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.findAll('li').at(1).classes()).not.toContain('gl-mb-3');
- });
+ await nextTick();
+ expect(wrapper.findAll('li').at(1).classes()).not.toContain('gl-mb-3');
});
});
});
diff --git a/spec/frontend/issues/show/components/app_spec.js b/spec/frontend/issues/show/components/app_spec.js
index 02db82b84dc..ac2717a5028 100644
--- a/spec/frontend/issues/show/components/app_spec.js
+++ b/spec/frontend/issues/show/components/app_spec.js
@@ -145,33 +145,30 @@ describe('Issuable output', () => {
});
});
- it('shows actions if permissions are correct', () => {
+ it('shows actions if permissions are correct', async () => {
wrapper.vm.showForm = true;
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('.markdown-selector').exists()).toBe(true);
- });
+ await nextTick();
+ expect(wrapper.find('.markdown-selector').exists()).toBe(true);
});
- it('does not show actions if permissions are incorrect', () => {
+ it('does not show actions if permissions are incorrect', async () => {
wrapper.vm.showForm = true;
wrapper.setProps({ canUpdate: false });
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('.markdown-selector').exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find('.markdown-selector').exists()).toBe(false);
});
- it('does not update formState if form is already open', () => {
+ it('does not update formState if form is already open', async () => {
wrapper.vm.updateAndShowForm();
wrapper.vm.state.titleText = 'testing 123';
wrapper.vm.updateAndShowForm();
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.store.formState.title).not.toBe('testing 123');
- });
+ await nextTick();
+ expect(wrapper.vm.store.formState.title).not.toBe('testing 123');
});
describe('Pinned links propagated', () => {
@@ -186,31 +183,29 @@ describe('Issuable output', () => {
});
describe('updateIssuable', () => {
- it('fetches new data after update', () => {
+ it('fetches new data after update', async () => {
const updateStoreSpy = jest.spyOn(wrapper.vm, 'updateStoreState');
const getDataSpy = jest.spyOn(wrapper.vm.service, 'getData');
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { web_url: window.location.pathname },
});
- return wrapper.vm.updateIssuable().then(() => {
- expect(updateStoreSpy).toHaveBeenCalled();
- expect(getDataSpy).toHaveBeenCalled();
- });
+ await wrapper.vm.updateIssuable();
+ expect(updateStoreSpy).toHaveBeenCalled();
+ expect(getDataSpy).toHaveBeenCalled();
});
- it('correctly updates issuable data', () => {
+ it('correctly updates issuable data', async () => {
const spy = jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: { web_url: window.location.pathname },
});
- return wrapper.vm.updateIssuable().then(() => {
- expect(spy).toHaveBeenCalledWith(wrapper.vm.formState);
- expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
- });
+ await wrapper.vm.updateIssuable();
+ expect(spy).toHaveBeenCalledWith(wrapper.vm.formState);
+ expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
});
- it('does not redirect if issue has not moved', () => {
+ it('does not redirect if issue has not moved', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
web_url: window.location.pathname,
@@ -218,12 +213,11 @@ describe('Issuable output', () => {
},
});
- return wrapper.vm.updateIssuable().then(() => {
- expect(visitUrl).not.toHaveBeenCalled();
- });
+ await wrapper.vm.updateIssuable();
+ expect(visitUrl).not.toHaveBeenCalled();
});
- it('does not redirect if issue has not moved and user has switched tabs', () => {
+ it('does not redirect if issue has not moved and user has switched tabs', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
web_url: '',
@@ -231,12 +225,11 @@ describe('Issuable output', () => {
},
});
- return wrapper.vm.updateIssuable().then(() => {
- expect(visitUrl).not.toHaveBeenCalled();
- });
+ await wrapper.vm.updateIssuable();
+ expect(visitUrl).not.toHaveBeenCalled();
});
- it('redirects if returned web_url has changed', () => {
+ it('redirects if returned web_url has changed', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockResolvedValue({
data: {
web_url: '/testing-issue-move',
@@ -246,108 +239,95 @@ describe('Issuable output', () => {
wrapper.vm.updateIssuable();
- return wrapper.vm.updateIssuable().then(() => {
- expect(visitUrl).toHaveBeenCalledWith('/testing-issue-move');
- });
+ await wrapper.vm.updateIssuable();
+ expect(visitUrl).toHaveBeenCalledWith('/testing-issue-move');
});
describe('shows dialog when issue has unsaved changed', () => {
- it('confirms on title change', () => {
+ it('confirms on title change', async () => {
wrapper.vm.showForm = true;
wrapper.vm.state.titleText = 'title has changed';
const e = { returnValue: null };
wrapper.vm.handleBeforeUnloadEvent(e);
- return wrapper.vm.$nextTick().then(() => {
- expect(e.returnValue).not.toBeNull();
- });
+ await nextTick();
+ expect(e.returnValue).not.toBeNull();
});
- it('confirms on description change', () => {
+ it('confirms on description change', async () => {
wrapper.vm.showForm = true;
wrapper.vm.state.descriptionText = 'description has changed';
const e = { returnValue: null };
wrapper.vm.handleBeforeUnloadEvent(e);
- return wrapper.vm.$nextTick().then(() => {
- expect(e.returnValue).not.toBeNull();
- });
+ await nextTick();
+ expect(e.returnValue).not.toBeNull();
});
- it('does nothing when nothing has changed', () => {
+ it('does nothing when nothing has changed', async () => {
const e = { returnValue: null };
wrapper.vm.handleBeforeUnloadEvent(e);
- return wrapper.vm.$nextTick().then(() => {
- expect(e.returnValue).toBeNull();
- });
+ await nextTick();
+ expect(e.returnValue).toBeNull();
});
});
describe('error when updating', () => {
- it('closes form on error', () => {
+ it('closes form on error', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue();
- return wrapper.vm.updateIssuable().then(() => {
- expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- `Error updating issue`,
- );
- });
+ await wrapper.vm.updateIssuable();
+ expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
+ expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
+ `Error updating issue`,
+ );
});
- it('returns the correct error message for issuableType', () => {
+ it('returns the correct error message for issuableType', async () => {
jest.spyOn(wrapper.vm.service, 'updateIssuable').mockRejectedValue();
wrapper.setProps({ issuableType: 'merge request' });
- return wrapper.vm
- .$nextTick()
- .then(wrapper.vm.updateIssuable)
- .then(() => {
- expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- `Error updating merge request`,
- );
- });
+ await nextTick();
+ await wrapper.vm.updateIssuable();
+ expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form');
+ expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
+ `Error updating merge request`,
+ );
});
- it('shows error message from backend if exists', () => {
+ it('shows error message from backend if exists', async () => {
const msg = 'Custom error message from backend';
jest
.spyOn(wrapper.vm.service, 'updateIssuable')
.mockRejectedValue({ response: { data: { errors: [msg] } } });
- return wrapper.vm.updateIssuable().then(() => {
- expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
- `${wrapper.vm.defaultErrorMessage}. ${msg}`,
- );
- });
+ await wrapper.vm.updateIssuable();
+ expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
+ `${wrapper.vm.defaultErrorMessage}. ${msg}`,
+ );
});
});
});
describe('updateAndShowForm', () => {
- it('shows locked warning if form is open & data is different', () => {
- return wrapper.vm
- .$nextTick()
- .then(() => {
- wrapper.vm.updateAndShowForm();
-
- wrapper.vm.poll.makeRequest();
-
- return new Promise((resolve) => {
- wrapper.vm.$watch('formState.lockedWarningVisible', (value) => {
- if (value) {
- resolve();
- }
- });
- });
- })
- .then(() => {
- expect(wrapper.vm.formState.lockedWarningVisible).toBe(true);
- expect(wrapper.vm.formState.lock_version).toBe(1);
- expect(findAlert().exists()).toBe(true);
+ it('shows locked warning if form is open & data is different', async () => {
+ await nextTick();
+ wrapper.vm.updateAndShowForm();
+
+ wrapper.vm.poll.makeRequest();
+
+ await new Promise((resolve) => {
+ wrapper.vm.$watch('formState.lockedWarningVisible', (value) => {
+ if (value) {
+ resolve();
+ }
});
+ });
+
+ expect(wrapper.vm.formState.lockedWarningVisible).toBe(true);
+ expect(wrapper.vm.formState.lock_version).toBe(1);
+ expect(findAlert().exists()).toBe(true);
});
});
@@ -398,12 +378,11 @@ describe('Issuable output', () => {
expect(wrapper.find('.btn-edit').exists()).toBe(true);
});
- it('should render if showInlineEditButton', () => {
+ it('should render if showInlineEditButton', async () => {
wrapper.setProps({ showInlineEditButton: true });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.btn-edit').exists()).toBe(true);
- });
+ await nextTick();
+ expect(wrapper.find('.btn-edit').exists()).toBe(true);
});
});
diff --git a/spec/frontend/issues/show/components/fields/type_spec.js b/spec/frontend/issues/show/components/fields/type_spec.js
index 7f7b16583e6..3333ceffca9 100644
--- a/spec/frontend/issues/show/components/fields/type_spec.js
+++ b/spec/frontend/issues/show/components/fields/type_spec.js
@@ -1,5 +1,6 @@
import { GlFormGroup, GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -10,8 +11,7 @@ import {
updateIssueStateQueryResponse,
} from '../../mock_data/apollo_mock';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Issue type field component', () => {
let wrapper;
@@ -43,7 +43,6 @@ describe('Issue type field component', () => {
fakeApollo = createMockApollo([], mockResolvers);
wrapper = shallowMount(IssueTypeField, {
- localVue,
apolloProvider: fakeApollo,
data() {
return {
@@ -93,7 +92,7 @@ describe('Issue type field component', () => {
it('updates the `issue_type` in the apollo cache when the value is changed', async () => {
findTypeFromDropDownItems().at(1).vm.$emit('click', issuableTypes.incident);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findTypeFromDropDown().attributes('value')).toBe(issuableTypes.incident);
});
diff --git a/spec/frontend/issues/show/components/form_spec.js b/spec/frontend/issues/show/components/form_spec.js
index db49d2635ba..5c0fe991b22 100644
--- a/spec/frontend/issues/show/components/form_spec.js
+++ b/spec/frontend/issues/show/components/form_spec.js
@@ -1,5 +1,6 @@
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Autosave from '~/autosave';
import DescriptionTemplate from '~/issues/show/components/fields/description_template.vue';
import IssueTypeField from '~/issues/show/components/fields/type.vue';
@@ -148,7 +149,7 @@ describe('Inline edit form component', () => {
formState: { ...defaultProps.formState, lock_version: 'lock version from server' },
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findAlert().exists()).toBe(true);
});
});
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index d09bf6faa13..4a557a60b94 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -1,5 +1,5 @@
import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
@@ -153,7 +153,7 @@ describe('HeaderActions component', () => {
it('dispatches a custom event to update the issue page', async () => {
findToggleIssueStateButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(dispatchEventSpy).toHaveBeenCalledTimes(1);
});
diff --git a/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js b/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js
index 7326b84ad54..901d9b5c267 100644
--- a/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js
+++ b/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlForm, GlFormInput, GlButton } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -45,8 +46,6 @@ const mockCreateBranchMutationWithErrors = jest
const mockCreateBranchMutationFailed = jest.fn().mockRejectedValue(new Error('GraphQL error'));
const mockMutationLoading = jest.fn().mockReturnValue(new Promise(() => {}));
-const localVue = createLocalVue();
-
describe('NewBranchForm', () => {
let wrapper;
@@ -66,7 +65,7 @@ describe('NewBranchForm', () => {
function createMockApolloProvider({
mockCreateBranchMutation = mockCreateBranchMutationSuccess,
} = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const mockApollo = createMockApollo([[createBranchMutation, mockCreateBranchMutation]]);
@@ -75,7 +74,6 @@ describe('NewBranchForm', () => {
function createComponent({ mockApollo, provide } = {}) {
wrapper = shallowMount(NewBranchForm, {
- localVue,
apolloProvider: mockApollo || createMockApolloProvider(),
provide: {
initialBranchName: '',
diff --git a/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js b/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
index ec4cb2739f8..6c344ec2667 100644
--- a/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
+++ b/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
-import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -7,8 +8,6 @@ import ProjectDropdown from '~/jira_connect/branches/components/project_dropdown
import { PROJECTS_PER_PAGE } from '~/jira_connect/branches/constants';
import getProjectsQuery from '~/jira_connect/branches/graphql/queries/get_projects.query.graphql';
-const localVue = createLocalVue();
-
const mockProjects = [
{
id: 'test',
@@ -62,7 +61,7 @@ describe('ProjectDropdown', () => {
const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
function createMockApolloProvider({ mockGetProjectsQuery = mockGetProjectsQuerySuccess } = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const mockApollo = createMockApollo([[getProjectsQuery, mockGetProjectsQuery]]);
@@ -71,7 +70,6 @@ describe('ProjectDropdown', () => {
function createComponent({ mockApollo, props, mountFn = shallowMount } = {}) {
wrapper = mountFn(ProjectDropdown, {
- localVue,
apolloProvider: mockApollo || createMockApolloProvider(),
propsData: props,
});
@@ -101,7 +99,7 @@ describe('ProjectDropdown', () => {
beforeEach(async () => {
createComponent();
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets dropdown `loading` prop to `false`', () => {
diff --git a/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js b/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js
index 9dd11dd6345..161bcc8c86d 100644
--- a/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js
+++ b/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
-import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -7,8 +8,6 @@ import SourceBranchDropdown from '~/jira_connect/branches/components/source_bran
import { BRANCHES_PER_PAGE } from '~/jira_connect/branches/constants';
import getProjectQuery from '~/jira_connect/branches/graphql/queries/get_project.query.graphql';
-const localVue = createLocalVue();
-
const mockProject = {
id: 'test',
fullPath: 'test-path',
@@ -45,7 +44,7 @@ describe('SourceBranchDropdown', () => {
};
function createMockApolloProvider({ getProjectQueryLoading = false } = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const mockApollo = createMockApollo([
[getProjectQuery, getProjectQueryLoading ? mockQueryLoading : mockGetProjectQuery],
@@ -56,7 +55,6 @@ describe('SourceBranchDropdown', () => {
function createComponent({ mockApollo, props, mountFn = shallowMount } = {}) {
wrapper = mountFn(SourceBranchDropdown, {
- localVue,
apolloProvider: mockApollo || createMockApolloProvider(),
propsData: props,
});
diff --git a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
index 15e9a740c83..b0d5859cd31 100644
--- a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
@@ -63,7 +64,7 @@ describe('GroupsListItem', () => {
clickLinkButton();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findLinkButton().props('loading')).toBe(true);
diff --git a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
index 04aba8bda23..660368cd99c 100644
--- a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlLoadingIcon, GlSearchBoxByType, GlPagination } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { fetchGroups } from '~/jira_connect/subscriptions/api';
@@ -61,7 +62,7 @@ describe('GroupsList', () => {
fetchGroups.mockReturnValue(new Promise(() => {}));
createComponent();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findGlLoadingIcon().exists()).toBe(true);
});
@@ -124,7 +125,7 @@ describe('GroupsList', () => {
findFirstItem().vm.$emit('error', errorMessage);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findGlAlert().exists()).toBe(true);
expect(findGlAlert().text()).toContain(errorMessage);
@@ -139,7 +140,7 @@ describe('GroupsList', () => {
fetchGroups.mockReturnValue(new Promise(() => {}));
findSearchBox().vm.$emit('input', mockSearchTeam);
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('calls `fetchGroups` with search term', () => {
diff --git a/spec/frontend/jira_connect/subscriptions/components/app_spec.js b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
index 47fe96262ee..8d6a97bc0ea 100644
--- a/spec/frontend/jira_connect/subscriptions/components/app_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlAlert, GlLink, GlEmptyState } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import JiraConnectApp from '~/jira_connect/subscriptions/components/app.vue';
import AddNamespaceButton from '~/jira_connect/subscriptions/components/add_namespace_button.vue';
import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue';
@@ -116,7 +117,7 @@ describe('JiraConnectApp', () => {
createComponent();
store.commit(SET_ALERT, { message, variant });
- await wrapper.vm.$nextTick();
+ await nextTick();
const alert = findAlert();
@@ -134,10 +135,10 @@ describe('JiraConnectApp', () => {
createComponent();
store.commit(SET_ALERT, { message: 'test message' });
- await wrapper.vm.$nextTick();
+ await nextTick();
findAlert().vm.$emit('dismiss');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findAlert().exists()).toBe(false);
});
@@ -149,7 +150,7 @@ describe('JiraConnectApp', () => {
message: __('test message %{linkStart}test link%{linkEnd}'),
linkUrl: 'https://gitlab.com',
});
- await wrapper.vm.$nextTick();
+ await nextTick();
const alertLink = findAlertLink();
diff --git a/spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js b/spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
index 4e4a2b58600..2aad533f677 100644
--- a/spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
@@ -71,7 +72,7 @@ describe('SubscriptionsList', () => {
clickUnlinkButton();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findUnlinkButton().props('loading')).toBe(true);
diff --git a/spec/frontend/jobs/bridge/app_spec.js b/spec/frontend/jobs/bridge/app_spec.js
index cd7c2fd5322..210dcfa364b 100644
--- a/spec/frontend/jobs/bridge/app_spec.js
+++ b/spec/frontend/jobs/bridge/app_spec.js
@@ -1,5 +1,6 @@
-import { nextTick } from 'vue';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { GlLoadingIcon } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
@@ -17,9 +18,6 @@ import {
mockPipelineQueryResponse,
} from './mock_data';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
-
describe('Bridge Show Page', () => {
let wrapper;
let mockApollo;
@@ -47,10 +45,10 @@ describe('Bridge Show Page', () => {
const createComponentWithApollo = () => {
const handlers = [[getPipelineQuery, mockPipelineQuery]];
+ Vue.use(VueApollo);
mockApollo = createMockApollo(handlers);
createComponent({
- localVue,
apolloProvider: mockApollo,
mocks: {},
});
diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js
index a6e98013d88..d4e1e711777 100644
--- a/spec/frontend/jobs/components/job_app_spec.js
+++ b/spec/frontend/jobs/components/job_app_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import MockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex';
import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
@@ -45,7 +45,7 @@ describe('Job App', () => {
wrapper = mount(JobApp, { propsData: { ...props }, store });
};
- const setupAndMount = ({ jobData = {}, jobLogData = {} } = {}) => {
+ const setupAndMount = async ({ jobData = {}, jobLogData = {} } = {}) => {
mock.onGet(initSettings.endpoint).replyOnce(200, { ...job, ...jobData });
mock.onGet(`${initSettings.pagePath}/trace.json`).reply(200, jobLogData);
@@ -53,12 +53,10 @@ describe('Job App', () => {
createComponent();
- return asyncInit
- .then(() => {
- jest.runOnlyPendingTimers();
- })
- .then(() => axios.waitForAll())
- .then(() => wrapper.vm.$nextTick());
+ await asyncInit;
+ jest.runOnlyPendingTimers();
+ await axios.waitForAll();
+ await nextTick();
};
const findLoadingComponent = () => wrapper.find(GlLoadingIcon);
diff --git a/spec/frontend/jobs/components/job_container_item_spec.js b/spec/frontend/jobs/components/job_container_item_spec.js
index 6b488821bc1..eb2b0184e5f 100644
--- a/spec/frontend/jobs/components/job_container_item_spec.js
+++ b/spec/frontend/jobs/components/job_container_item_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
import JobContainerItem from '~/jobs/components/job_container_item.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
@@ -87,7 +88,7 @@ describe('JobContainerItem', () => {
});
it('displays remaining time in tooltip', async () => {
- await wrapper.vm.$nextTick();
+ await nextTick();
const link = wrapper.findComponent(GlLink);
diff --git a/spec/frontend/jobs/components/job_log_controllers_spec.js b/spec/frontend/jobs/components/job_log_controllers_spec.js
index 0ba07522243..226322a2951 100644
--- a/spec/frontend/jobs/components/job_log_controllers_spec.js
+++ b/spec/frontend/jobs/components/job_log_controllers_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import JobLogControllers from '~/jobs/components/job_log_controllers.vue';
describe('Job log controllers', () => {
@@ -111,7 +112,7 @@ describe('Job log controllers', () => {
it('emits scrollJobLogTop event on click', async () => {
findScrollTop().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted().scrollJobLogTop).toHaveLength(1);
});
@@ -133,7 +134,7 @@ describe('Job log controllers', () => {
it('does not emit scrollJobLogTop event on click', async () => {
findScrollTop().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted().scrollJobLogTop).toBeUndefined();
});
@@ -149,7 +150,7 @@ describe('Job log controllers', () => {
it('emits scrollJobLogBottom event on click', async () => {
findScrollBottom().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted().scrollJobLogBottom).toHaveLength(1);
});
@@ -171,7 +172,7 @@ describe('Job log controllers', () => {
it('does not emit scrollJobLogBottom event on click', async () => {
findScrollBottom().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted().scrollJobLogBottom).toBeUndefined();
});
diff --git a/spec/frontend/jobs/components/log/collapsible_section_spec.js b/spec/frontend/jobs/components/log/collapsible_section_spec.js
index 96bdf03796b..22ddc8b1c2d 100644
--- a/spec/frontend/jobs/components/log/collapsible_section_spec.js
+++ b/spec/frontend/jobs/components/log/collapsible_section_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import CollapsibleSection from '~/jobs/components/log/collapsible_section.vue';
import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data';
@@ -69,7 +70,7 @@ describe('Job Log Collapsible Section', () => {
});
});
- it('emits onClickCollapsibleLine on click', () => {
+ it('emits onClickCollapsibleLine on click', async () => {
createComponent({
section: collapsibleSectionOpened,
jobLogEndpoint,
@@ -77,8 +78,7 @@ describe('Job Log Collapsible Section', () => {
findCollapsibleLine().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('onClickCollapsibleLine').length).toBe(1);
- });
+ await nextTick();
+ expect(wrapper.emitted('onClickCollapsibleLine').length).toBe(1);
});
});
diff --git a/spec/frontend/jobs/components/log/line_header_spec.js b/spec/frontend/jobs/components/log/line_header_spec.js
index 9763e2f437b..8055fe64d95 100644
--- a/spec/frontend/jobs/components/log/line_header_spec.js
+++ b/spec/frontend/jobs/components/log/line_header_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import DurationBadge from '~/jobs/components/log/duration_badge.vue';
import LineHeader from '~/jobs/components/log/line_header.vue';
import LineNumber from '~/jobs/components/log/line_number.vue';
@@ -75,12 +76,11 @@ describe('Job Log Header Line', () => {
createComponent(data);
});
- it('emits toggleLine event', () => {
+ it('emits toggleLine event', async () => {
wrapper.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleLine.length).toBe(1);
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleLine.length).toBe(1);
});
});
diff --git a/spec/frontend/jobs/components/sidebar_spec.js b/spec/frontend/jobs/components/sidebar_spec.js
index 500a1b48950..6e327725627 100644
--- a/spec/frontend/jobs/components/sidebar_spec.js
+++ b/spec/frontend/jobs/components/sidebar_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ArtifactsBlock from '~/jobs/components/artifacts_block.vue';
import JobRetryForwardDeploymentModal from '~/jobs/components/job_retry_forward_deployment_modal.vue';
@@ -189,7 +190,7 @@ describe('Sidebar details block', () => {
locked: false,
};
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findArtifactsBlock().exists()).toBe(true);
});
diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js
index 389bcf670c9..7808a22e1f6 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -1,5 +1,6 @@
import { GlSkeletonLoader, GlAlert, GlEmptyState, GlPagination } from '@gitlab/ui';
-import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -10,8 +11,7 @@ import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
import { mockJobsQueryResponse, mockJobsQueryEmptyResponse } from '../../mock_data';
const projectPath = 'gitlab-org/gitlab';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Job table app', () => {
let wrapper;
@@ -50,7 +50,6 @@ describe('Job table app', () => {
provide: {
projectPath,
},
- localVue,
apolloProvider: createMockApolloProvider(handler),
});
};
@@ -124,7 +123,7 @@ describe('Job table app', () => {
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findPrevious().exists()).toBe(true);
expect(findNext().exists()).toBe(true);
diff --git a/spec/frontend/jobs/mixins/delayed_job_mixin_spec.js b/spec/frontend/jobs/mixins/delayed_job_mixin_spec.js
index 63dcd72f967..1d3845b19bb 100644
--- a/spec/frontend/jobs/mixins/delayed_job_mixin_spec.js
+++ b/spec/frontend/jobs/mixins/delayed_job_mixin_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin';
@@ -34,7 +35,7 @@ describe('DelayedJobMixin', () => {
});
it('does not update remaining time after mounting', async () => {
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.text()).toBe('00:00:00');
});
@@ -57,7 +58,7 @@ describe('DelayedJobMixin', () => {
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets remaining time', () => {
@@ -68,7 +69,7 @@ describe('DelayedJobMixin', () => {
remainingTimeInMilliseconds = 41000;
jest.advanceTimersByTime(1000);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.text()).toBe('00:00:41');
});
});
@@ -104,7 +105,7 @@ describe('DelayedJobMixin', () => {
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets remaining time', () => {
@@ -115,7 +116,7 @@ describe('DelayedJobMixin', () => {
remainingTimeInMilliseconds = 41000;
jest.advanceTimersByTime(1000);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.text()).toBe('00:00:41');
});
});
diff --git a/spec/frontend/logs/components/environment_logs_spec.js b/spec/frontend/logs/components/environment_logs_spec.js
index b107708ac2c..84dc0bdf6cd 100644
--- a/spec/frontend/logs/components/environment_logs_spec.js
+++ b/spec/frontend/logs/components/environment_logs_spec.js
@@ -1,5 +1,6 @@
import { GlSprintf, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { scrollDown } from '~/lib/utils/scroll_utils';
import EnvironmentLogs from '~/logs/components/environment_logs.vue';
@@ -338,35 +339,32 @@ describe('EnvironmentLogs', () => {
expect(store.dispatch).not.toHaveBeenCalledWith(`${module}/fetchMoreLogsPrepend`, undefined);
});
- it('`scroll` on a scrollable target results in enabled scroll buttons', () => {
+ it('`scroll` on a scrollable target results in enabled scroll buttons', async () => {
const target = { scrollTop: 10, clientHeight: 10, scrollHeight: 21 };
state.logs.isLoading = true;
findInfiniteScroll().vm.$emit('scroll', { target });
- return wrapper.vm.$nextTick(() => {
- expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(false);
- });
+ await nextTick();
+ expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(false);
});
- it('`scroll` on a non-scrollable target in disabled scroll buttons', () => {
+ it('`scroll` on a non-scrollable target in disabled scroll buttons', async () => {
const target = { scrollTop: 10, clientHeight: 10, scrollHeight: 20 };
state.logs.isLoading = true;
findInfiniteScroll().vm.$emit('scroll', { target });
- return wrapper.vm.$nextTick(() => {
- expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true);
- });
+ await nextTick();
+ expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true);
});
- it('`scroll` on no target results in disabled scroll buttons', () => {
+ it('`scroll` on no target results in disabled scroll buttons', async () => {
state.logs.isLoading = true;
findInfiniteScroll().vm.$emit('scroll', { target: undefined });
- return wrapper.vm.$nextTick(() => {
- expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true);
- });
+ await nextTick();
+ expect(findLogControlButtons().props('scrollDownButtonDisabled')).toEqual(true);
});
});
});
diff --git a/spec/frontend/logs/components/log_control_buttons_spec.js b/spec/frontend/logs/components/log_control_buttons_spec.js
index 9c1617e4daa..e249272b87d 100644
--- a/spec/frontend/logs/components/log_control_buttons_spec.js
+++ b/spec/frontend/logs/components/log_control_buttons_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import LogControlButtons from '~/logs/components/log_control_buttons.vue';
describe('LogControlButtons', () => {
@@ -33,7 +34,7 @@ describe('LogControlButtons', () => {
expect(findRefreshBtn().is(GlButton)).toBe(true);
});
- it('emits a `refresh` event on click on `refresh` button', () => {
+ it('emits a `refresh` event on click on `refresh` button', async () => {
initWrapper();
// An `undefined` value means no event was emitted
@@ -41,16 +42,15 @@ describe('LogControlButtons', () => {
findRefreshBtn().vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('refresh')).toHaveLength(1);
- });
+ await nextTick();
+ expect(wrapper.emitted('refresh')).toHaveLength(1);
});
describe('when scrolling actions are enabled', () => {
- beforeEach(() => {
+ beforeEach(async () => {
// mock scrolled to the middle of a long page
initWrapper();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('click on "scroll to top" scrolls up', () => {
@@ -71,19 +71,18 @@ describe('LogControlButtons', () => {
});
describe('when scrolling actions are disabled', () => {
- beforeEach(() => {
+ beforeEach(async () => {
initWrapper({ listeners: {} });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
- it('buttons are disabled', () => {
- return wrapper.vm.$nextTick(() => {
- expect(findScrollToTop().exists()).toBe(false);
- expect(findScrollToBottom().exists()).toBe(false);
- // This should be enabled when gitlab-ui contains:
- // https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1149
- // expect(findScrollToBottom().is('[disabled]')).toBe(true);
- });
+ it('buttons are disabled', async () => {
+ await nextTick();
+ expect(findScrollToTop().exists()).toBe(false);
+ expect(findScrollToBottom().exists()).toBe(false);
+ // This should be enabled when gitlab-ui contains:
+ // https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/1149
+ // expect(findScrollToBottom().is('[disabled]')).toBe(true);
});
});
});
diff --git a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
index fabf65742f5..750fff9b0aa 100644
--- a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
+++ b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
@@ -1,6 +1,6 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import InlineConflictLines from '~/merge_conflicts/components/inline_conflict_lines.vue';
import ParallelConflictLines from '~/merge_conflicts/components/parallel_conflict_lines.vue';
@@ -93,7 +93,7 @@ describe('Merge Conflict Resolver App', () => {
expect(inlineButton.props('selected')).toBe(false);
inlineButton.vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(inlineButton.props('selected')).toBe(true);
});
@@ -111,7 +111,7 @@ describe('Merge Conflict Resolver App', () => {
mountComponent();
findSideBySideButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
const parallelConflictLinesComponent = findParallelConflictLines(findFiles().at(0));
diff --git a/spec/frontend/monitoring/components/charts/stacked_column_spec.js b/spec/frontend/monitoring/components/charts/stacked_column_spec.js
index f47728313c6..9cab3650f28 100644
--- a/spec/frontend/monitoring/components/charts/stacked_column_spec.js
+++ b/spec/frontend/monitoring/components/charts/stacked_column_spec.js
@@ -2,6 +2,7 @@ import { GlStackedColumnChart, GlChartLegend } from '@gitlab/ui/dist/charts';
import { shallowMount, mount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import timezoneMock from 'timezone-mock';
+import { nextTick } from 'vue';
import StackedColumnChart from '~/monitoring/components/charts/stacked_column.vue';
import { stackedColumnGraphData } from '../../graph_data';
@@ -34,9 +35,9 @@ describe('Stacked column chart component', () => {
});
describe('when graphData is present', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('chart is rendered', () => {
@@ -116,25 +117,24 @@ describe('Stacked column chart component', () => {
expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('4:01 AM');
});
- it('date is shown in UTC', () => {
+ it('date is shown in UTC', async () => {
wrapper.setProps({ timezone: 'UTC' });
- return wrapper.vm.$nextTick().then(() => {
- const { xAxis } = findChart().props('option');
- expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
- });
+ await nextTick();
+ const { xAxis } = findChart().props('option');
+ expect(xAxis.axisLabel.formatter('2020-01-30T12:01:00.000Z')).toBe('12:01 PM');
});
});
});
describe('when graphData has results missing', () => {
- beforeEach(() => {
+ beforeEach(async () => {
const graphData = cloneDeep(stackedColumnMockedData);
graphData.metrics[0].result = null;
createWrapper({ graphData });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('chart is rendered', () => {
@@ -147,7 +147,7 @@ describe('Stacked column chart component', () => {
wrapper = createWrapper({}, mount);
});
- it('allows user to override legend label texts using props', () => {
+ it('allows user to override legend label texts using props', async () => {
const legendRelatedProps = {
legendMinText: 'legendMinText',
legendMaxText: 'legendMaxText',
@@ -158,9 +158,8 @@ describe('Stacked column chart component', () => {
...legendRelatedProps,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findChart().props()).toMatchObject(legendRelatedProps);
- });
+ await nextTick();
+ expect(findChart().props()).toMatchObject(legendRelatedProps);
});
it('should render a tabular legend layout by default', () => {
diff --git a/spec/frontend/monitoring/components/charts/time_series_spec.js b/spec/frontend/monitoring/components/charts/time_series_spec.js
index ff6f0b9b0c7..73abd81d889 100644
--- a/spec/frontend/monitoring/components/charts/time_series_spec.js
+++ b/spec/frontend/monitoring/components/charts/time_series_spec.js
@@ -7,6 +7,7 @@ import {
} from '@gitlab/ui/dist/charts';
import { mount, shallowMount } from '@vue/test-utils';
import timezoneMock from 'timezone-mock';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import { setTestTimeout } from 'helpers/timeout';
import { shallowWrapperContainsSlotText } from 'helpers/vue_test_utils_helper';
@@ -70,12 +71,12 @@ describe('Time series component', () => {
describe('general functions', () => {
const findChart = () => wrapper.find({ ref: 'chart' });
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper({}, mount);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
- it('allows user to override legend label texts using props', () => {
+ it('allows user to override legend label texts using props', async () => {
const legendRelatedProps = {
legendMinText: 'legendMinText',
legendMaxText: 'legendMaxText',
@@ -86,9 +87,8 @@ describe('Time series component', () => {
...legendRelatedProps,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findChart().props()).toMatchObject(legendRelatedProps);
- });
+ await nextTick();
+ expect(findChart().props()).toMatchObject(legendRelatedProps);
});
it('chart sets a default height', () => {
@@ -96,14 +96,13 @@ describe('Time series component', () => {
expect(wrapper.props('height')).toBe(chartHeight);
});
- it('chart has a configurable height', () => {
+ it('chart has a configurable height', async () => {
const mockHeight = 599;
createWrapper();
wrapper.setProps({ height: mockHeight });
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.props('height')).toBe(mockHeight);
- });
+ await nextTick();
+ expect(wrapper.props('height')).toBe(mockHeight);
});
describe('events', () => {
@@ -112,7 +111,7 @@ describe('Time series component', () => {
let startValue;
let endValue;
- beforeEach(() => {
+ beforeEach(async () => {
eChartMock = {
handlers: {},
getOption: () => ({
@@ -132,9 +131,8 @@ describe('Time series component', () => {
};
createWrapper({}, mount);
- return wrapper.vm.$nextTick(() => {
- findChart().vm.$emit('created', eChartMock);
- });
+ await nextTick();
+ findChart().vm.$emit('created', eChartMock);
});
it('handles datazoom event from chart', () => {
@@ -203,10 +201,10 @@ describe('Time series component', () => {
});
describe('when series is of line type', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper({}, mount);
wrapper.vm.formatTooltipText(mockLineSeriesData());
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('formats tooltip title', () => {
@@ -241,34 +239,31 @@ describe('Time series component', () => {
timezoneMock.unregister();
});
- it('formats tooltip title in local timezone by default', () => {
+ it('formats tooltip title in local timezone by default', async () => {
createWrapper();
wrapper.vm.formatTooltipText(mockLineSeriesData());
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 3:14AM (GMT-0700)');
- });
+ await nextTick();
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 3:14AM (GMT-0700)');
});
- it('formats tooltip title in local timezone', () => {
+ it('formats tooltip title in local timezone', async () => {
createWrapper({ timezone: 'LOCAL' });
wrapper.vm.formatTooltipText(mockLineSeriesData());
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 3:14AM (GMT-0700)');
- });
+ await nextTick();
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 3:14AM (GMT-0700)');
});
- it('formats tooltip title in UTC format', () => {
+ it('formats tooltip title in UTC format', async () => {
createWrapper({ timezone: 'UTC' });
wrapper.vm.formatTooltipText(mockLineSeriesData());
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM (UTC)');
- });
+ await nextTick();
+ expect(wrapper.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM (UTC)');
});
});
});
describe('when series is of scatter type, for deployments', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.vm.formatTooltipText({
...mockAnnotationsSeriesData,
seriesData: mockAnnotationsSeriesData.seriesData.map((data) => ({
@@ -276,7 +271,7 @@ describe('Time series component', () => {
data: annotationsMetadata,
})),
});
- return wrapper.vm.$nextTick;
+ await nextTick();
});
it('set tooltip type to deployments', () => {
@@ -297,9 +292,9 @@ describe('Time series component', () => {
});
describe('when series is of scatter type and deployments data is missing', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.vm.formatTooltipText(mockAnnotationsSeriesData);
- return wrapper.vm.$nextTick;
+ await nextTick();
});
it('formats tooltip title', () => {
@@ -397,14 +392,13 @@ describe('Time series component', () => {
});
});
- it('is not set if time range is not set or incorrectly set', () => {
+ it('is not set if time range is not set or incorrectly set', async () => {
wrapper.setProps({
timeRange: {},
});
- return wrapper.vm.$nextTick(() => {
- expect(getChartOptions().xAxis).not.toHaveProperty('min');
- expect(getChartOptions().xAxis).not.toHaveProperty('max');
- });
+ await nextTick();
+ expect(getChartOptions().xAxis).not.toHaveProperty('min');
+ expect(getChartOptions().xAxis).not.toHaveProperty('max');
});
});
@@ -430,17 +424,16 @@ describe('Time series component', () => {
option2: 'option2',
};
- it('arbitrary options', () => {
+ it('arbitrary options', async () => {
wrapper.setProps({
option: mockOption,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(getChartOptions()).toEqual(expect.objectContaining(mockOption));
- });
+ await nextTick();
+ expect(getChartOptions()).toEqual(expect.objectContaining(mockOption));
});
- it('additional series', () => {
+ it('additional series', async () => {
wrapper.setProps({
option: {
series: [
@@ -453,15 +446,14 @@ describe('Time series component', () => {
},
});
- return wrapper.vm.$nextTick().then(() => {
- const optionSeries = getChartOptions().series;
+ await nextTick();
+ const optionSeries = getChartOptions().series;
- expect(optionSeries.length).toEqual(2);
- expect(optionSeries[0].name).toEqual(mockSeriesName);
- });
+ expect(optionSeries.length).toEqual(2);
+ expect(optionSeries[0].name).toEqual(mockSeriesName);
});
- it('additional y-axis data', () => {
+ it('additional y-axis data', async () => {
const mockCustomYAxisOption = {
name: 'Custom y-axis label',
axisLabel: {
@@ -475,14 +467,13 @@ describe('Time series component', () => {
},
});
- return wrapper.vm.$nextTick().then(() => {
- const { yAxis } = getChartOptions();
+ await nextTick();
+ const { yAxis } = getChartOptions();
- expect(yAxis[0]).toMatchObject(mockCustomYAxisOption);
- });
+ expect(yAxis[0]).toMatchObject(mockCustomYAxisOption);
});
- it('additional x axis data', () => {
+ it('additional x axis data', async () => {
const mockCustomXAxisOption = {
name: 'Custom x axis label',
};
@@ -493,11 +484,10 @@ describe('Time series component', () => {
},
});
- return wrapper.vm.$nextTick().then(() => {
- const { xAxis } = getChartOptions();
+ await nextTick();
+ const { xAxis } = getChartOptions();
- expect(xAxis).toMatchObject(mockCustomXAxisOption);
- });
+ expect(xAxis).toMatchObject(mockCustomXAxisOption);
});
});
@@ -625,12 +615,12 @@ describe('Time series component', () => {
describe(`GitLab UI: ${dynamicComponent.chartType}`, () => {
const findChartComponent = () => wrapper.find(dynamicComponent.component);
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper(
{ graphData: timeSeriesGraphData({ type: dynamicComponent.chartType }) },
mount,
);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('exists', () => {
@@ -645,22 +635,21 @@ describe('Time series component', () => {
expect(props.formatTooltipText).toBe(wrapper.vm.formatTooltipText);
});
- it('receives a tooltip title', () => {
+ it('receives a tooltip title', async () => {
const mockTitle = 'mockTitle';
wrapper.vm.tooltip.title = mockTitle;
- return wrapper.vm.$nextTick(() => {
- expect(
- shallowWrapperContainsSlotText(findChartComponent(), 'tooltip-title', mockTitle),
- ).toBe(true);
- });
+ await nextTick();
+ expect(
+ shallowWrapperContainsSlotText(findChartComponent(), 'tooltip-title', mockTitle),
+ ).toBe(true);
});
describe('when tooltip is showing deployment data', () => {
const mockSha = 'mockSha';
const commitUrl = `${mockProjectDir}/-/commit/${mockSha}`;
- beforeEach(() => {
+ beforeEach(async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -668,7 +657,7 @@ describe('Time series component', () => {
type: 'deployments',
},
});
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('uses deployment title', () => {
@@ -677,16 +666,15 @@ describe('Time series component', () => {
).toBe(true);
});
- it('renders clickable commit sha in tooltip content', () => {
+ it('renders clickable commit sha in tooltip content', async () => {
wrapper.vm.tooltip.sha = mockSha;
wrapper.vm.tooltip.commitUrl = commitUrl;
- return wrapper.vm.$nextTick(() => {
- const commitLink = wrapper.find(GlLink);
+ await nextTick();
+ const commitLink = wrapper.find(GlLink);
- expect(shallowWrapperContainsSlotText(commitLink, 'default', mockSha)).toBe(true);
- expect(commitLink.attributes('href')).toEqual(commitUrl);
- });
+ expect(shallowWrapperContainsSlotText(commitLink, 'default', mockSha)).toBe(true);
+ expect(commitLink.attributes('href')).toEqual(commitUrl);
});
});
});
@@ -696,11 +684,11 @@ describe('Time series component', () => {
describe('with multiple time series', () => {
describe('General functions', () => {
- beforeEach(() => {
+ beforeEach(async () => {
const graphData = timeSeriesGraphData({ type: panelTypes.AREA_CHART, multiMetric: true });
createWrapper({ graphData }, mount);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
describe('Color match', () => {
@@ -742,9 +730,9 @@ describe('Time series component', () => {
describe('legend layout', () => {
const findLegend = () => wrapper.find(GlChartLegend);
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper({}, mount);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('should render a tabular legend layout by default', () => {
diff --git a/spec/frontend/monitoring/components/create_dashboard_modal_spec.js b/spec/frontend/monitoring/components/create_dashboard_modal_spec.js
index 8202d423ff3..88de3467580 100644
--- a/spec/frontend/monitoring/components/create_dashboard_modal_spec.js
+++ b/spec/frontend/monitoring/components/create_dashboard_modal_spec.js
@@ -1,5 +1,6 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import CreateDashboardModal from '~/monitoring/components/create_dashboard_modal.vue';
describe('Create dashboard modal', () => {
@@ -32,13 +33,12 @@ describe('Create dashboard modal', () => {
wrapper.destroy();
});
- it('has button that links to the project url', () => {
+ it('has button that links to the project url', async () => {
findRepoButton().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findRepoButton().exists()).toBe(true);
- expect(findRepoButton().attributes('href')).toBe(defaultProps.projectPath);
- });
+ await nextTick();
+ expect(findRepoButton().exists()).toBe(true);
+ expect(findRepoButton().attributes('href')).toBe(defaultProps.projectPath);
});
it('has button that links to the docs', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_actions_menu_spec.js b/spec/frontend/monitoring/components/dashboard_actions_menu_spec.js
index f2116c1f478..d0d0c3071d5 100644
--- a/spec/frontend/monitoring/components/dashboard_actions_menu_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_actions_menu_spec.js
@@ -1,5 +1,6 @@
import { GlDropdownItem, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
import { redirectTo } from '~/lib/utils/url_utility';
import ActionsMenu from '~/monitoring/components/dashboard_actions_menu.vue';
@@ -60,22 +61,20 @@ describe('Actions menu', () => {
});
describe('add metric item', () => {
- it('is rendered when custom metrics are available', () => {
+ it('is rendered when custom metrics are available', async () => {
createShallowWrapper();
- return wrapper.vm.$nextTick(() => {
- expect(findAddMetricItem().exists()).toBe(true);
- });
+ await nextTick();
+ expect(findAddMetricItem().exists()).toBe(true);
});
- it('is not rendered when custom metrics are not available', () => {
+ it('is not rendered when custom metrics are not available', async () => {
createShallowWrapper({
addingMetricsAvailable: false,
});
- return wrapper.vm.$nextTick(() => {
- expect(findAddMetricItem().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findAddMetricItem().exists()).toBe(false);
});
describe('when available', () => {
@@ -119,30 +118,23 @@ describe('Actions menu', () => {
origPage = document.body.dataset.page;
document.body.dataset.page = 'projects:environments:metrics';
- wrapper.vm.$nextTick(done);
+ nextTick(done);
});
afterEach(() => {
document.body.dataset.page = origPage;
});
- it('is tracked', (done) => {
+ it('is tracked', async () => {
const submitButton = findAddMetricModalSubmitButton().vm;
- wrapper.vm.$nextTick(() => {
- submitButton.$el.click();
- wrapper.vm.$nextTick(() => {
- expect(Tracking.event).toHaveBeenCalledWith(
- document.body.dataset.page,
- 'click_button',
- {
- label: 'add_new_metric',
- property: 'modal',
- value: undefined,
- },
- );
- done();
- });
+ await nextTick();
+ submitButton.$el.click();
+ await nextTick();
+ expect(Tracking.event).toHaveBeenCalledWith(document.body.dataset.page, 'click_button', {
+ label: 'add_new_metric',
+ property: 'modal',
+ value: undefined,
});
});
});
@@ -172,14 +164,13 @@ describe('Actions menu', () => {
);
});
- it('is disabled for ootb dashboards', () => {
+ it('is disabled for ootb dashboards', async () => {
createShallowWrapper({
isOotbDashboard: true,
});
- return wrapper.vm.$nextTick(() => {
- expect(findAddPanelItemDisabled().exists()).toBe(true);
- });
+ await nextTick();
+ expect(findAddPanelItemDisabled().exists()).toBe(true);
});
it('is visible for custom dashboards', () => {
@@ -256,16 +247,15 @@ describe('Actions menu', () => {
expect(findDuplicateDashboardModal().exists()).toBe(true);
});
- it('clicking on item opens up the duplicate dashboard modal', () => {
+ it('clicking on item opens up the duplicate dashboard modal', async () => {
const modalId = 'duplicateDashboard';
const modalTrigger = findDuplicateDashboardItem();
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
modalTrigger.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
- });
+ await nextTick();
+ expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
});
});
@@ -300,16 +290,15 @@ describe('Actions menu', () => {
setupAllDashboards(store, dashboardGitResponse[0].path);
});
- it('redirects to the newly created dashboard', () => {
+ it('redirects to the newly created dashboard', async () => {
const newDashboard = dashboardGitResponse[1];
const newDashboardUrl = 'root/sandbox/-/metrics/dashboard.yml';
findDuplicateDashboardModal().vm.$emit('dashboardDuplicated', newDashboard);
- return wrapper.vm.$nextTick().then(() => {
- expect(redirectTo).toHaveBeenCalled();
- expect(redirectTo).toHaveBeenCalledWith(newDashboardUrl);
- });
+ await nextTick();
+ expect(redirectTo).toHaveBeenCalled();
+ expect(redirectTo).toHaveBeenCalledWith(newDashboardUrl);
});
});
});
@@ -330,32 +319,30 @@ describe('Actions menu', () => {
expect(findStarDashboardItem().attributes('disabled')).toBeFalsy();
});
- it('is disabled when starring is taking place', () => {
+ it('is disabled when starring is taking place', async () => {
store.commit(`monitoringDashboard/${types.REQUEST_DASHBOARD_STARRING}`);
- return wrapper.vm.$nextTick(() => {
- expect(findStarDashboardItem().exists()).toBe(true);
- expect(findStarDashboardItem().attributes('disabled')).toBe('true');
- });
+ await nextTick();
+ expect(findStarDashboardItem().exists()).toBe(true);
+ expect(findStarDashboardItem().attributes('disabled')).toBe('true');
});
- it('on click it dispatches a toggle star action', () => {
+ it('on click it dispatches a toggle star action', async () => {
findStarDashboardItem().vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/toggleStarredValue',
- undefined,
- );
- });
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/toggleStarredValue',
+ undefined,
+ );
});
describe('when dashboard is not starred', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard: dashboardGitResponse[0].path,
});
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('item text shows "Star dashboard"', () => {
@@ -364,11 +351,11 @@ describe('Actions menu', () => {
});
describe('when dashboard is starred', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard: dashboardGitResponse[1].path,
});
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('item text shows "Unstar dashboard"', () => {
@@ -403,16 +390,15 @@ describe('Actions menu', () => {
expect(findCreateDashboardModal().exists()).toBe(true);
});
- it('clicking opens up the modal', () => {
+ it('clicking opens up the modal', async () => {
const modalId = 'createDashboard';
const modalTrigger = findCreateDashboardItem();
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
modalTrigger.trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
- });
+ await nextTick();
+ expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
});
it('modal gets passed correct props', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_header_spec.js b/spec/frontend/monitoring/components/dashboard_header_spec.js
index 8be7d641953..e28c2913949 100644
--- a/spec/frontend/monitoring/components/dashboard_header_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_header_spec.js
@@ -1,5 +1,6 @@
import { GlDropdownItem, GlSearchBoxByType, GlLoadingIcon, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { redirectTo } from '~/lib/utils/url_utility';
import ActionsMenu from '~/monitoring/components/dashboard_actions_menu.vue';
import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
@@ -110,9 +111,9 @@ describe('Dashboard header', () => {
});
describe('when environments data is not loaded', () => {
- beforeEach(() => {
+ beforeEach(async () => {
setupStoreWithDashboard(store);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('there are no environments listed', () => {
@@ -124,13 +125,13 @@ describe('Dashboard header', () => {
const currentDashboard = dashboardGitResponse[0].path;
const currentEnvironmentName = environmentData[0].name;
- beforeEach(() => {
+ beforeEach(async () => {
setupStoreWithData(store);
store.state.monitoringDashboard.projectPath = mockProjectPath;
store.state.monitoringDashboard.currentDashboard = currentDashboard;
store.state.monitoringDashboard.currentEnvironmentName = currentEnvironmentName;
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('renders dropdown items with the environment name', () => {
@@ -159,51 +160,41 @@ describe('Dashboard header', () => {
expect(selectedItems.at(0).text()).toBe(currentEnvironmentName);
});
- it('filters rendered dropdown items', () => {
+ it('filters rendered dropdown items', async () => {
const searchTerm = 'production';
const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1);
setSearchTerm(searchTerm);
- return wrapper.vm.$nextTick().then(() => {
- expect(findEnvsDropdownItems()).toHaveLength(resultEnvs.length);
- });
+ await nextTick();
+ expect(findEnvsDropdownItems()).toHaveLength(resultEnvs.length);
});
- it('does not filter dropdown items if search term is empty string', () => {
+ it('does not filter dropdown items if search term is empty string', async () => {
const searchTerm = '';
setSearchTerm(searchTerm);
- return wrapper.vm.$nextTick(() => {
- expect(findEnvsDropdownItems()).toHaveLength(environmentData.length);
- });
+ await nextTick();
+ expect(findEnvsDropdownItems()).toHaveLength(environmentData.length);
});
- it("shows error message if search term doesn't match", () => {
+ it("shows error message if search term doesn't match", async () => {
const searchTerm = 'does-not-exist';
setSearchTerm(searchTerm);
- return wrapper.vm.$nextTick(() => {
- expect(findEnvsDropdownSearchMsg().isVisible()).toBe(true);
- });
+ await nextTick();
+ expect(findEnvsDropdownSearchMsg().isVisible()).toBe(true);
});
- it('shows loading element when environments fetch is still loading', () => {
+ it('shows loading element when environments fetch is still loading', async () => {
store.commit(`monitoringDashboard/${types.REQUEST_ENVIRONMENTS_DATA}`);
- return wrapper.vm
- .$nextTick()
- .then(() => {
- expect(findEnvsDropdownLoadingIcon().exists()).toBe(true);
- })
- .then(() => {
- store.commit(
- `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
- environmentData,
- );
- })
- .then(() => {
- expect(findEnvsDropdownLoadingIcon().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findEnvsDropdownLoadingIcon().exists()).toBe(true);
+ await store.commit(
+ `monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
+ environmentData,
+ );
+ expect(findEnvsDropdownLoadingIcon().exists()).toBe(false);
});
});
});
@@ -262,11 +253,11 @@ describe('Dashboard header', () => {
});
describe('external dashboard link', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.monitoringDashboard.externalDashboardUrl = '/mockUrl';
createShallowWrapper();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows the link', () => {
@@ -295,82 +286,78 @@ describe('Dashboard header', () => {
});
describe('adding metrics prop', () => {
- it.each(ootbDashboards)('gets passed true if current dashboard is OOTB', (dashboardPath) => {
- createShallowWrapper({ customMetricsAvailable: true });
+ it.each(ootbDashboards)(
+ 'gets passed true if current dashboard is OOTB',
+ async (dashboardPath) => {
+ createShallowWrapper({ customMetricsAvailable: true });
- store.state.monitoringDashboard.emptyState = false;
- setupAllDashboards(store, dashboardPath);
+ store.state.monitoringDashboard.emptyState = false;
+ setupAllDashboards(store, dashboardPath);
- return wrapper.vm.$nextTick().then(() => {
+ await nextTick();
expect(findActionsMenu().props('addingMetricsAvailable')).toBe(true);
- });
- });
+ },
+ );
it.each(customDashboards)(
'gets passed false if current dashboard is custom',
- (dashboardPath) => {
+ async (dashboardPath) => {
createShallowWrapper({ customMetricsAvailable: true });
store.state.monitoringDashboard.emptyState = false;
setupAllDashboards(store, dashboardPath);
- return wrapper.vm.$nextTick().then(() => {
- expect(findActionsMenu().props('addingMetricsAvailable')).toBe(false);
- });
+ await nextTick();
+ expect(findActionsMenu().props('addingMetricsAvailable')).toBe(false);
},
);
- it('gets passed false if empty state is shown', () => {
+ it('gets passed false if empty state is shown', async () => {
createShallowWrapper({ customMetricsAvailable: true });
store.state.monitoringDashboard.emptyState = true;
setupAllDashboards(store, ootbDashboards[0]);
- return wrapper.vm.$nextTick().then(() => {
- expect(findActionsMenu().props('addingMetricsAvailable')).toBe(false);
- });
+ await nextTick();
+ expect(findActionsMenu().props('addingMetricsAvailable')).toBe(false);
});
- it('gets passed false if custom metrics are not available', () => {
+ it('gets passed false if custom metrics are not available', async () => {
createShallowWrapper({ customMetricsAvailable: false });
store.state.monitoringDashboard.emptyState = false;
setupAllDashboards(store, ootbDashboards[0]);
- return wrapper.vm.$nextTick().then(() => {
- expect(findActionsMenu().props('addingMetricsAvailable')).toBe(false);
- });
+ await nextTick();
+ expect(findActionsMenu().props('addingMetricsAvailable')).toBe(false);
});
});
- it('custom metrics path gets passed', () => {
+ it('custom metrics path gets passed', async () => {
const path = 'https://path/to/customMetrics';
createShallowWrapper({ customMetricsPath: path });
- return wrapper.vm.$nextTick().then(() => {
- expect(findActionsMenu().props('customMetricsPath')).toBe(path);
- });
+ await nextTick();
+ expect(findActionsMenu().props('customMetricsPath')).toBe(path);
});
- it('validate query path gets passed', () => {
+ it('validate query path gets passed', async () => {
const path = 'https://path/to/validateQuery';
createShallowWrapper({ validateQueryPath: path });
- return wrapper.vm.$nextTick().then(() => {
- expect(findActionsMenu().props('validateQueryPath')).toBe(path);
- });
+ await nextTick();
+ expect(findActionsMenu().props('validateQueryPath')).toBe(path);
});
- it('default branch gets passed', () => {
+ it('default branch gets passed', async () => {
const branch = 'branchName';
createShallowWrapper({ defaultBranch: branch });
- return wrapper.vm.$nextTick().then(() => {
- expect(findActionsMenu().props('defaultBranch')).toBe(branch);
- });
+ await nextTick();
+ expect(findActionsMenu().props('defaultBranch')).toBe(branch);
});
});
@@ -385,40 +372,36 @@ describe('Dashboard header', () => {
store.state.monitoringDashboard.operationsSettingsPath = '';
});
- it('is rendered when the user can access the project settings and path to settings is available', () => {
+ it('is rendered when the user can access the project settings and path to settings is available', async () => {
store.state.monitoringDashboard.canAccessOperationsSettings = true;
store.state.monitoringDashboard.operationsSettingsPath = url;
- return wrapper.vm.$nextTick(() => {
- expect(findSettingsButton().exists()).toBe(true);
- });
+ await nextTick();
+ expect(findSettingsButton().exists()).toBe(true);
});
- it('is not rendered when the user can not access the project settings', () => {
+ it('is not rendered when the user can not access the project settings', async () => {
store.state.monitoringDashboard.canAccessOperationsSettings = false;
store.state.monitoringDashboard.operationsSettingsPath = url;
- return wrapper.vm.$nextTick(() => {
- expect(findSettingsButton().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findSettingsButton().exists()).toBe(false);
});
- it('is not rendered when the path to settings is unavailable', () => {
+ it('is not rendered when the path to settings is unavailable', async () => {
store.state.monitoringDashboard.canAccessOperationsSettings = false;
store.state.monitoringDashboard.operationsSettingsPath = '';
- return wrapper.vm.$nextTick(() => {
- expect(findSettingsButton().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findSettingsButton().exists()).toBe(false);
});
- it('leads to the project settings page', () => {
+ it('leads to the project settings page', async () => {
store.state.monitoringDashboard.canAccessOperationsSettings = true;
store.state.monitoringDashboard.operationsSettingsPath = url;
- return wrapper.vm.$nextTick(() => {
- expect(findSettingsButton().attributes('href')).toBe(url);
- });
+ await nextTick();
+ expect(findSettingsButton().attributes('href')).toBe(url);
});
});
});
diff --git a/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js b/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
index 400ac2e8f85..f19ef6c6fb7 100644
--- a/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
@@ -1,5 +1,6 @@
import { GlCard, GlForm, GlFormTextarea, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
import DashboardPanelBuilder from '~/monitoring/components/dashboard_panel_builder.vue';
import { createStore } from '~/monitoring/stores';
@@ -90,21 +91,20 @@ describe('dashboard invalid url parameters', () => {
expect(mockShowToast).toHaveBeenCalledTimes(1);
});
- it('on submit fetches a panel preview', () => {
+ it('on submit fetches a panel preview', async () => {
findForm().vm.$emit('submit', new Event('submit'));
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/fetchPanelPreview',
- expect.stringContaining('title:'),
- );
- });
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/fetchPanelPreview',
+ expect.stringContaining('title:'),
+ );
});
describe('when form is submitted', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.commit(`monitoringDashboard/${types.REQUEST_PANEL_PREVIEW}`, 'mock yml content');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('submit button is disabled', () => {
@@ -118,23 +118,21 @@ describe('dashboard invalid url parameters', () => {
expect(findTimeRangePicker().exists()).toBe(true);
});
- it('when changed does not trigger data fetch unless preview panel button is clicked', () => {
+ it('when changed does not trigger data fetch unless preview panel button is clicked', async () => {
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
- return wrapper.vm.$nextTick(() => {
- expect(store.dispatch).not.toHaveBeenCalled();
- });
+ await nextTick();
+ expect(store.dispatch).not.toHaveBeenCalled();
});
- it('when changed triggers data fetch if preview panel button is clicked', () => {
+ it('when changed triggers data fetch if preview panel button is clicked', async () => {
findForm().vm.$emit('submit', new Event('submit'));
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange);
- return wrapper.vm.$nextTick(() => {
- expect(store.dispatch).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalled();
});
});
@@ -143,27 +141,25 @@ describe('dashboard invalid url parameters', () => {
expect(findRefreshButton().exists()).toBe(true);
});
- it('when clicked does not trigger data fetch unless preview panel button is clicked', () => {
+ it('when clicked does not trigger data fetch unless preview panel button is clicked', async () => {
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, false);
- return wrapper.vm.$nextTick(() => {
- expect(store.dispatch).not.toHaveBeenCalled();
- });
+ await nextTick();
+ expect(store.dispatch).not.toHaveBeenCalled();
});
- it('when clicked triggers data fetch if preview panel button is clicked', () => {
+ it('when clicked triggers data fetch if preview panel button is clicked', async () => {
// mimic state where preview is visible. SET_PANEL_PREVIEW_IS_SHOWN is set to true
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_IS_SHOWN}`, true);
findRefreshButton().vm.$emit('click');
- return wrapper.vm.$nextTick(() => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/fetchPanelPreviewMetrics',
- undefined,
- );
- });
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/fetchPanelPreviewMetrics',
+ undefined,
+ );
});
});
@@ -190,9 +186,9 @@ describe('dashboard invalid url parameters', () => {
describe('when there is an error', () => {
const mockError = 'an error occurred!';
- beforeEach(() => {
+ beforeEach(async () => {
store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_FAILURE}`, mockError);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays an alert', () => {
@@ -204,19 +200,18 @@ describe('dashboard invalid url parameters', () => {
expect(findPanel().props('graphData')).toBe(null);
});
- it('changing time range should not refetch data', () => {
+ it('changing time range should not refetch data', async () => {
store.commit(`monitoringDashboard/${types.SET_PANEL_PREVIEW_TIME_RANGE}`, mockTimeRange);
- return wrapper.vm.$nextTick(() => {
- expect(store.dispatch).not.toHaveBeenCalled();
- });
+ await nextTick();
+ expect(store.dispatch).not.toHaveBeenCalled();
});
});
describe('when panel data is available', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.commit(`monitoringDashboard/${types.RECEIVE_PANEL_PREVIEW_SUCCESS}`, mockPanel);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays no alert', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_panel_spec.js b/spec/frontend/monitoring/components/dashboard_panel_spec.js
index 9a73dc820af..7bd062b81f1 100644
--- a/spec/frontend/monitoring/components/dashboard_panel_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_panel_spec.js
@@ -2,6 +2,7 @@ import { GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex';
+import { nextTick } from 'vue';
import { setTestTimeout } from 'helpers/timeout';
import axios from '~/lib/utils/axios_utils';
import invalidUrl from '~/lib/utils/invalid_url';
@@ -186,7 +187,7 @@ describe('Dashboard Panel', () => {
expect(findCopyLink().exists()).toBe(false);
});
- it('should emit `timerange` event when a zooming in/out in a chart occcurs', () => {
+ it('should emit `timerange` event when a zooming in/out in a chart occcurs', async () => {
const timeRange = {
start: '2020-01-01T00:00:00.000Z',
end: '2020-01-01T01:00:00.000Z',
@@ -196,9 +197,8 @@ describe('Dashboard Panel', () => {
findTimeChart().vm.$emit('datazoom', timeRange);
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('timerangezoom', timeRange);
- });
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('timerangezoom', timeRange);
});
it('includes a default group id', () => {
@@ -253,16 +253,15 @@ describe('Dashboard Panel', () => {
describe('computed', () => {
describe('fixedCurrentTimeRange', () => {
- it('returns fixed time for valid time range', () => {
+ it('returns fixed time for valid time range', async () => {
state.timeRange = mockTimeRange;
- return wrapper.vm.$nextTick(() => {
- expect(findTimeChart().props('timeRange')).toEqual(
- expect.objectContaining({
- start: expect.any(String),
- end: expect.any(String),
- }),
- );
- });
+ await nextTick();
+ expect(findTimeChart().props('timeRange')).toEqual(
+ expect.objectContaining({
+ start: expect.any(String),
+ end: expect.any(String),
+ }),
+ );
});
it.each`
@@ -271,11 +270,10 @@ describe('Dashboard Panel', () => {
${undefined} | ${{}}
${null} | ${{}}
${'2020-12-03'} | ${{}}
- `('returns $output for invalid input like $input', ({ input, output }) => {
+ `('returns $output for invalid input like $input', async ({ input, output }) => {
state.timeRange = input;
- return wrapper.vm.$nextTick(() => {
- expect(findTimeChart().props('timeRange')).toEqual(output);
- });
+ await nextTick();
+ expect(findTimeChart().props('timeRange')).toEqual(output);
});
});
});
@@ -285,17 +283,16 @@ describe('Dashboard Panel', () => {
const findEditCustomMetricLink = () => wrapper.find({ ref: 'editMetricLink' });
const mockEditPath = '/root/kubernetes-gke-project/prometheus/metrics/23/edit';
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper();
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('is not present if the panel is not a custom metric', () => {
expect(findEditCustomMetricLink().exists()).toBe(false);
});
- it('is present when the panel contains an edit_path property', () => {
+ it('is present when the panel contains an edit_path property', async () => {
wrapper.setProps({
graphData: {
...graphData,
@@ -308,14 +305,13 @@ describe('Dashboard Panel', () => {
},
});
- return wrapper.vm.$nextTick(() => {
- expect(findEditCustomMetricLink().exists()).toBe(true);
- expect(findEditCustomMetricLink().text()).toBe('Edit metric');
- expect(findEditCustomMetricLink().attributes('href')).toBe(mockEditPath);
- });
+ await nextTick();
+ expect(findEditCustomMetricLink().exists()).toBe(true);
+ expect(findEditCustomMetricLink().text()).toBe('Edit metric');
+ expect(findEditCustomMetricLink().attributes('href')).toBe(mockEditPath);
});
- it('shows an "Edit metrics" link pointing to settingsPath for a panel with multiple metrics', () => {
+ it('shows an "Edit metrics" link pointing to settingsPath for a panel with multiple metrics', async () => {
wrapper.setProps({
graphData: {
...graphData,
@@ -332,63 +328,58 @@ describe('Dashboard Panel', () => {
},
});
- return wrapper.vm.$nextTick(() => {
- expect(findEditCustomMetricLink().text()).toBe('Edit metrics');
- expect(findEditCustomMetricLink().attributes('href')).toBe(dashboardProps.settingsPath);
- });
+ await nextTick();
+ expect(findEditCustomMetricLink().text()).toBe('Edit metrics');
+ expect(findEditCustomMetricLink().attributes('href')).toBe(dashboardProps.settingsPath);
});
});
describe('View Logs dropdown item', () => {
const findViewLogsLink = () => wrapper.find({ ref: 'viewLogsLink' });
- beforeEach(() => {
+ beforeEach(async () => {
createWrapper();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
- it('is not present by default', () =>
- wrapper.vm.$nextTick(() => {
- expect(findViewLogsLink().exists()).toBe(false);
- }));
+ it('is not present by default', async () => {
+ await nextTick();
+ expect(findViewLogsLink().exists()).toBe(false);
+ });
- it('is not present if a time range is not set', () => {
+ it('is not present if a time range is not set', async () => {
state.logsPath = mockLogsPath;
state.timeRange = null;
- return wrapper.vm.$nextTick(() => {
- expect(findViewLogsLink().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findViewLogsLink().exists()).toBe(false);
});
- it('is not present if the logs path is default', () => {
+ it('is not present if the logs path is default', async () => {
state.logsPath = invalidUrl;
state.timeRange = mockTimeRange;
- return wrapper.vm.$nextTick(() => {
- expect(findViewLogsLink().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findViewLogsLink().exists()).toBe(false);
});
- it('is not present if the logs path is not set', () => {
+ it('is not present if the logs path is not set', async () => {
state.logsPath = null;
state.timeRange = mockTimeRange;
- return wrapper.vm.$nextTick(() => {
- expect(findViewLogsLink().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findViewLogsLink().exists()).toBe(false);
});
- it('is present when logs path and time a range is present', () => {
+ it('is present when logs path and time a range is present', async () => {
state.logsPath = mockLogsPath;
state.timeRange = mockTimeRange;
- return wrapper.vm.$nextTick(() => {
- expect(findViewLogsLink().attributes('href')).toMatch(mockLogsHref);
- });
+ await nextTick();
+ expect(findViewLogsLink().attributes('href')).toMatch(mockLogsHref);
});
- it('it is overridden when a datazoom event is received', () => {
+ it('it is overridden when a datazoom event is received', async () => {
state.logsPath = mockLogsPath;
state.timeRange = mockTimeRange;
@@ -399,13 +390,12 @@ describe('Dashboard Panel', () => {
findTimeChart().vm.$emit('datazoom', zoomedTimeRange);
- return wrapper.vm.$nextTick(() => {
- const start = encodeURIComponent(zoomedTimeRange.start);
- const end = encodeURIComponent(zoomedTimeRange.end);
- expect(findViewLogsLink().attributes('href')).toMatch(
- `${mockLogsPath}?start=${start}&end=${end}`,
- );
- });
+ await nextTick();
+ const start = encodeURIComponent(zoomedTimeRange.start);
+ const end = encodeURIComponent(zoomedTimeRange.end);
+ expect(findViewLogsLink().attributes('href')).toMatch(
+ `${mockLogsPath}?start=${start}&end=${end}`,
+ );
});
});
@@ -447,7 +437,7 @@ describe('Dashboard Panel', () => {
});
describe('when downloading metrics data as CSV', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper = shallowMount(DashboardPanel, {
propsData: {
clipboardText: exampleText,
@@ -459,7 +449,7 @@ describe('Dashboard Panel', () => {
},
store,
});
- return wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
@@ -509,29 +499,26 @@ describe('Dashboard Panel', () => {
});
});
- it('handles namespaced time range and logs path state', () => {
+ it('handles namespaced time range and logs path state', async () => {
store.state[mockNamespace].timeRange = mockTimeRange;
store.state[mockNamespace].logsPath = mockLogsPath;
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find({ ref: 'viewLogsLink' }).attributes().href).toBe(mockLogsHref);
- });
+ await nextTick();
+ expect(wrapper.find({ ref: 'viewLogsLink' }).attributes().href).toBe(mockLogsHref);
});
- it('handles namespaced deployment data state', () => {
+ it('handles namespaced deployment data state', async () => {
store.state[mockNamespace].deploymentData = mockDeploymentData;
- return wrapper.vm.$nextTick().then(() => {
- expect(findTimeChart().props().deploymentData).toEqual(mockDeploymentData);
- });
+ await nextTick();
+ expect(findTimeChart().props().deploymentData).toEqual(mockDeploymentData);
});
- it('handles namespaced project path state', () => {
+ it('handles namespaced project path state', async () => {
store.state[mockNamespace].projectPath = mockProjectPath;
- return wrapper.vm.$nextTick().then(() => {
- expect(findTimeChart().props().projectPath).toBe(mockProjectPath);
- });
+ await nextTick();
+ expect(findTimeChart().props().projectPath).toBe(mockProjectPath);
});
it('it renders a time series chart with no errors', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index 7730e7f347f..6c5972e1140 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -1,5 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import VueDraggable from 'vuedraggable';
+import { nextTick } from 'vue';
import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'helpers/test_constants';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -77,51 +78,47 @@ describe('Dashboard', () => {
});
describe('request information to the server', () => {
- it('calls to set time range and fetch data', () => {
+ it('calls to set time range and fetch data', async () => {
createShallowWrapper({ hasMetrics: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/setTimeRange',
- expect.any(Object),
- );
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/setTimeRange',
+ expect.any(Object),
+ );
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
- });
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
- it('shows up a loading state', () => {
+ it('shows up a loading state', async () => {
store.state.monitoringDashboard.emptyState = dashboardEmptyStates.LOADING;
createShallowWrapper({ hasMetrics: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(EmptyState).exists()).toBe(true);
- expect(wrapper.find(EmptyState).props('selectedState')).toBe(dashboardEmptyStates.LOADING);
- });
+ await nextTick();
+ expect(wrapper.find(EmptyState).exists()).toBe(true);
+ expect(wrapper.find(EmptyState).props('selectedState')).toBe(dashboardEmptyStates.LOADING);
});
- it('hides the group panels when showPanels is false', () => {
+ it('hides the group panels when showPanels is false', async () => {
createMountedWrapper({ hasMetrics: true, showPanels: false });
setupStoreWithData(store);
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.emptyState).toBeNull();
- expect(wrapper.findAll('.prometheus-panel')).toHaveLength(0);
- });
+ await nextTick();
+ expect(wrapper.vm.emptyState).toBeNull();
+ expect(wrapper.findAll('.prometheus-panel')).toHaveLength(0);
});
- it('fetches the metrics data with proper time window', () => {
+ it('fetches the metrics data with proper time window', async () => {
createMountedWrapper({ hasMetrics: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/setTimeRange',
- expect.objectContaining({ duration: { seconds: 28800 } }),
- );
- });
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/setTimeRange',
+ expect.objectContaining({ duration: { seconds: 28800 } }),
+ );
});
});
@@ -133,69 +130,63 @@ describe('Dashboard', () => {
.at(index);
};
- beforeEach(() => {
+ beforeEach(async () => {
createMountedWrapper({ hasMetrics: true });
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
describe('when the graph group has an even number of panels', () => {
- it('2 panels - all panel wrappers take half width of their parent', () => {
+ it('2 panels - all panel wrappers take half width of their parent', async () => {
setupStoreWithDataForPanelCount(store, 2);
- wrapper.vm.$nextTick(() => {
- expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
- });
+ await nextTick();
+ expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
});
- it('4 panels - all panel wrappers take half width of their parent', () => {
+ it('4 panels - all panel wrappers take half width of their parent', async () => {
setupStoreWithDataForPanelCount(store, 4);
- wrapper.vm.$nextTick(() => {
- expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
- });
+ await nextTick();
+ expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
});
});
describe('when the graph group has an odd number of panels', () => {
- it('1 panel - panel wrapper does not take half width of its parent', () => {
+ it('1 panel - panel wrapper does not take half width of its parent', async () => {
setupStoreWithDataForPanelCount(store, 1);
- wrapper.vm.$nextTick(() => {
- expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(false);
- });
+ await nextTick();
+ expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(false);
});
- it('3 panels - all panels but last take half width of their parents', () => {
+ it('3 panels - all panels but last take half width of their parents', async () => {
setupStoreWithDataForPanelCount(store, 3);
- wrapper.vm.$nextTick(() => {
- expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(false);
- });
+ await nextTick();
+ expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(false);
});
- it('5 panels - all panels but last take half width of their parents', () => {
+ it('5 panels - all panels but last take half width of their parents', async () => {
setupStoreWithDataForPanelCount(store, 5);
- wrapper.vm.$nextTick(() => {
- expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
- expect(findPanelLayoutWrapperAt(4).classes('col-lg-6')).toBe(false);
- });
+ await nextTick();
+ expect(findPanelLayoutWrapperAt(0).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(1).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(2).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(3).classes('col-lg-6')).toBe(true);
+ expect(findPanelLayoutWrapperAt(4).classes('col-lg-6')).toBe(false);
});
});
});
describe('dashboard validation warning', () => {
- it('displays a warning if there are validation warnings', () => {
+ it('displays a warning if there are validation warnings', async () => {
createMountedWrapper({ hasMetrics: true });
store.commit(
@@ -203,12 +194,11 @@ describe('Dashboard', () => {
true,
);
- return wrapper.vm.$nextTick().then(() => {
- expect(createFlash).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(createFlash).toHaveBeenCalled();
});
- it('does not display a warning if there are no validation warnings', () => {
+ it('does not display a warning if there are no validation warnings', async () => {
createMountedWrapper({ hasMetrics: true });
store.commit(
@@ -216,9 +206,8 @@ describe('Dashboard', () => {
false,
);
- return wrapper.vm.$nextTick().then(() => {
- expect(createFlash).not.toHaveBeenCalled();
- });
+ await nextTick();
+ expect(createFlash).not.toHaveBeenCalled();
});
});
@@ -233,7 +222,7 @@ describe('Dashboard', () => {
setWindowLocation(location);
});
- it('when the URL points to a panel it expands', () => {
+ it('when the URL points to a panel it expands', async () => {
const panelGroup = metricsDashboardViewModel.panelGroups[0];
const panel = panelGroup.panels[0];
@@ -246,32 +235,30 @@ describe('Dashboard', () => {
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setExpandedPanel', {
- group: panelGroup.group,
- panel: expect.objectContaining({
- title: panel.title,
- y_label: panel.y_label,
- }),
- });
+ await nextTick();
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setExpandedPanel', {
+ group: panelGroup.group,
+ panel: expect.objectContaining({
+ title: panel.title,
+ y_label: panel.y_label,
+ }),
});
});
- it('when the URL does not link to any panel, no panel is expanded', () => {
+ it('when the URL does not link to any panel, no panel is expanded', async () => {
setSearch();
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).not.toHaveBeenCalledWith(
- 'monitoringDashboard/setExpandedPanel',
- expect.anything(),
- );
- });
+ await nextTick();
+ expect(store.dispatch).not.toHaveBeenCalledWith(
+ 'monitoringDashboard/setExpandedPanel',
+ expect.anything(),
+ );
});
- it('when the URL points to an incorrect panel it shows an error', () => {
+ it('when the URL points to an incorrect panel it shows an error', async () => {
const panelGroup = metricsDashboardViewModel.panelGroups[0];
const panel = panelGroup.panels[0];
@@ -284,13 +271,12 @@ describe('Dashboard', () => {
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
- return wrapper.vm.$nextTick().then(() => {
- expect(createFlash).toHaveBeenCalled();
- expect(store.dispatch).not.toHaveBeenCalledWith(
- 'monitoringDashboard/setExpandedPanel',
- expect.anything(),
- );
- });
+ await nextTick();
+ expect(createFlash).toHaveBeenCalled();
+ expect(store.dispatch).not.toHaveBeenCalledWith(
+ 'monitoringDashboard/setExpandedPanel',
+ expect.anything(),
+ );
});
});
@@ -319,7 +305,7 @@ describe('Dashboard', () => {
window.history.pushState.mockRestore();
});
- it('URL is updated with panel parameters', () => {
+ it('URL is updated with panel parameters', async () => {
createMountedWrapper({ hasMetrics: true });
expandPanel(group, panel);
@@ -329,17 +315,16 @@ describe('Dashboard', () => {
y_label: panel.y_label,
});
- return wrapper.vm.$nextTick(() => {
- expect(window.history.pushState).toHaveBeenCalledTimes(1);
- expect(window.history.pushState).toHaveBeenCalledWith(
- expect.anything(), // state
- expect.any(String), // document title
- expect.stringContaining(`${expectedSearch}`),
- );
- });
+ await nextTick();
+ expect(window.history.pushState).toHaveBeenCalledTimes(1);
+ expect(window.history.pushState).toHaveBeenCalledWith(
+ expect.anything(), // state
+ expect.any(String), // document title
+ expect.stringContaining(`${expectedSearch}`),
+ );
});
- it('URL is updated with panel parameters and custom dashboard', () => {
+ it('URL is updated with panel parameters and custom dashboard', async () => {
const dashboard = 'dashboard.yml';
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
@@ -355,36 +340,34 @@ describe('Dashboard', () => {
y_label: panel.y_label,
});
- return wrapper.vm.$nextTick(() => {
- expect(window.history.pushState).toHaveBeenCalledTimes(1);
- expect(window.history.pushState).toHaveBeenCalledWith(
- expect.anything(), // state
- expect.any(String), // document title
- expect.stringContaining(`${expectedSearch}`),
- );
- });
+ await nextTick();
+ expect(window.history.pushState).toHaveBeenCalledTimes(1);
+ expect(window.history.pushState).toHaveBeenCalledWith(
+ expect.anything(), // state
+ expect.any(String), // document title
+ expect.stringContaining(`${expectedSearch}`),
+ );
});
- it('URL is updated with no parameters', () => {
+ it('URL is updated with no parameters', async () => {
expandPanel(group, panel);
createMountedWrapper({ hasMetrics: true });
expandPanel(null, null);
- return wrapper.vm.$nextTick(() => {
- expect(window.history.pushState).toHaveBeenCalledTimes(1);
- expect(window.history.pushState).toHaveBeenCalledWith(
- expect.anything(), // state
- expect.any(String), // document title
- expect.not.stringMatching(/group|title|y_label/), // no panel params
- );
- });
+ await nextTick();
+ expect(window.history.pushState).toHaveBeenCalledTimes(1);
+ expect(window.history.pushState).toHaveBeenCalledWith(
+ expect.anything(), // state
+ expect.any(String), // document title
+ expect.not.stringMatching(/group|title|y_label/), // no panel params
+ );
});
});
describe('when all panels in the first group are loading', () => {
const findGroupAt = (i) => wrapper.findAll(GraphGroup).at(i);
- beforeEach(() => {
+ beforeEach(async () => {
setupStoreWithDashboard(store);
const { panels } = store.state.monitoringDashboard.dashboard.panelGroups[0];
@@ -396,7 +379,7 @@ describe('Dashboard', () => {
createShallowWrapper();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('a loading icon appears in the first group', () => {
@@ -409,7 +392,7 @@ describe('Dashboard', () => {
});
describe('when all requests have been committed by the store', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentEnvironmentName: 'production',
currentDashboard: dashboardGitResponse[0].path,
@@ -418,26 +401,25 @@ describe('Dashboard', () => {
createMountedWrapper({ hasMetrics: true });
setupStoreWithData(store);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
- it('it does not show loading icons in any group', () => {
+ it('it does not show loading icons in any group', async () => {
setupStoreWithData(store);
- wrapper.vm.$nextTick(() => {
- wrapper.findAll(GraphGroup).wrappers.forEach((groupWrapper) => {
- expect(groupWrapper.props('isLoading')).toBe(false);
- });
+ await nextTick();
+ wrapper.findAll(GraphGroup).wrappers.forEach((groupWrapper) => {
+ expect(groupWrapper.props('isLoading')).toBe(false);
});
});
});
describe('variables section', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
store.state.monitoringDashboard.variables = storeVariables;
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows the variables section', () => {
@@ -446,12 +428,11 @@ describe('Dashboard', () => {
});
describe('links section', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
setupStoreWithLinks(store);
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows the links section', () => {
@@ -464,10 +445,10 @@ describe('Dashboard', () => {
const findExpandedPanel = () => wrapper.find({ ref: 'expandedPanel' });
describe('when the panel is not expanded', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('expanded panel is not visible', () => {
@@ -502,7 +483,7 @@ describe('Dashboard', () => {
template: `<div><slot name="top-left"/></div>`,
};
- beforeEach(() => {
+ beforeEach(async () => {
createShallowWrapper({ hasMetrics: true }, { stubs: { DashboardPanel: MockPanel } });
setupStoreWithData(store);
@@ -517,8 +498,7 @@ describe('Dashboard', () => {
});
jest.spyOn(store, 'dispatch');
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays a single panel and others are hidden', () => {
@@ -561,13 +541,12 @@ describe('Dashboard', () => {
});
describe('when one of the metrics is missing', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createShallowWrapper({ hasMetrics: true });
setupStoreWithDashboard(store);
setMetricResult({ store, result: [], panel: 2 });
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows a group empty area', () => {
@@ -590,14 +569,13 @@ describe('Dashboard', () => {
const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel');
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
- beforeEach(() => {
+ beforeEach(async () => {
// call original dispatch
store.dispatch.mockRestore();
createShallowWrapper({ hasMetrics: true });
setupStoreWithData(store);
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('wraps vuedraggable', () => {
@@ -611,9 +589,9 @@ describe('Dashboard', () => {
});
describe('when rearrange is enabled', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.setProps({ rearrangePanelsAvailable: true });
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays rearrange button', () => {
@@ -624,9 +602,9 @@ describe('Dashboard', () => {
const findFirstDraggableRemoveButton = () =>
findDraggablePanels().at(0).find('.js-draggable-remove');
- beforeEach(() => {
+ beforeEach(async () => {
findRearrangeButton().vm.$emit('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('it enables draggables', () => {
@@ -634,7 +612,7 @@ describe('Dashboard', () => {
expect(findEnabledDraggables().wrappers).toEqual(findDraggables().wrappers);
});
- it('metrics can be swapped', () => {
+ it('metrics can be swapped', async () => {
const firstDraggable = findDraggables().at(0);
const mockMetrics = [...metricsDashboardViewModel.panelGroups[0].panels];
@@ -645,43 +623,40 @@ describe('Dashboard', () => {
[mockMetrics[0], mockMetrics[1]] = [mockMetrics[1], mockMetrics[0]];
firstDraggable.vm.$emit('input', mockMetrics);
- return wrapper.vm.$nextTick(() => {
- const { panels } = wrapper.vm.dashboard.panelGroups[0];
+ await nextTick();
+ const { panels } = wrapper.vm.dashboard.panelGroups[0];
- expect(panels[1].title).toEqual(firstTitle);
- expect(panels[0].title).toEqual(secondTitle);
- });
+ expect(panels[1].title).toEqual(firstTitle);
+ expect(panels[0].title).toEqual(secondTitle);
});
- it('shows a remove button, which removes a panel', () => {
+ it('shows a remove button, which removes a panel', async () => {
expect(findFirstDraggableRemoveButton().find('a').exists()).toBe(true);
expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount);
findFirstDraggableRemoveButton().trigger('click');
- return wrapper.vm.$nextTick(() => {
- expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount - 1);
- });
+ await nextTick();
+ expect(findDraggablePanels().length).toEqual(metricsDashboardPanelCount - 1);
});
- it('it disables draggables when clicked again', () => {
+ it('it disables draggables when clicked again', async () => {
findRearrangeButton().vm.$emit('click');
- return wrapper.vm.$nextTick(() => {
- expect(findRearrangeButton().attributes('pressed')).toBeFalsy();
- expect(findEnabledDraggables().length).toBe(0);
- });
+ await nextTick();
+ expect(findRearrangeButton().attributes('pressed')).toBeFalsy();
+ expect(findEnabledDraggables().length).toBe(0);
});
});
});
});
describe('cluster health', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createShallowWrapper({ hasMetrics: true, showHeader: false });
// all_dashboards is not defined in health dashboards
store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, undefined);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('hides dashboard header by default', () => {
@@ -706,34 +681,31 @@ describe('Dashboard', () => {
document.title = '';
});
- it('is prepended with the overview dashboard name by default', () => {
+ it('is prepended with the overview dashboard name by default', async () => {
setupAllDashboards(store);
- return wrapper.vm.$nextTick().then(() => {
- expect(document.title.startsWith(`${overviewDashboardName} · `)).toBe(true);
- });
+ await nextTick();
+ expect(document.title.startsWith(`${overviewDashboardName} · `)).toBe(true);
});
- it('is prepended with dashboard name if path is known', () => {
+ it('is prepended with dashboard name if path is known', async () => {
const dashboard = dashboardGitResponse[1];
const currentDashboard = dashboard.path;
setupAllDashboards(store, currentDashboard);
- return wrapper.vm.$nextTick().then(() => {
- expect(document.title.startsWith(`${dashboard.display_name} · `)).toBe(true);
- });
+ await nextTick();
+ expect(document.title.startsWith(`${dashboard.display_name} · `)).toBe(true);
});
- it('is prepended with the overview dashboard name if path is not known', () => {
+ it('is prepended with the overview dashboard name if path is not known', async () => {
setupAllDashboards(store, 'unknown/path');
- return wrapper.vm.$nextTick().then(() => {
- expect(document.title.startsWith(`${overviewDashboardName} · `)).toBe(true);
- });
+ await nextTick();
+ expect(document.title.startsWith(`${overviewDashboardName} · `)).toBe(true);
});
- it('is not modified when dashboard name is not provided', () => {
+ it('is not modified when dashboard name is not provided', async () => {
const dashboard = { ...dashboardGitResponse[1], display_name: null };
const currentDashboard = dashboard.path;
@@ -743,9 +715,8 @@ describe('Dashboard', () => {
currentDashboard,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(document.title).toBe(originalTitle);
- });
+ await nextTick();
+ expect(document.title).toBe(originalTitle);
});
});
@@ -756,14 +727,13 @@ describe('Dashboard', () => {
const getClipboardTextFirstPanel = () =>
wrapper.findAll(DashboardPanel).at(panelIndex).props('clipboardText');
- beforeEach(() => {
+ beforeEach(async () => {
setupStoreWithData(store);
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard,
});
createShallowWrapper({ hasMetrics: true });
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('contains a link to the dashboard', () => {
@@ -785,7 +755,7 @@ describe('Dashboard', () => {
// the dashboard panels have a ref attribute set.
const getDashboardPanel = () => wrapper.find({ ref: panelRef });
- beforeEach(() => {
+ beforeEach(async () => {
setupStoreWithData(store);
store.commit(`monitoringDashboard/${types.SET_INITIAL_STATE}`, {
currentDashboard,
@@ -795,8 +765,7 @@ describe('Dashboard', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hoveredPanel: panelRef });
-
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('contains a ref attribute inside a DashboardPanel component', () => {
diff --git a/spec/frontend/monitoring/components/dashboard_url_time_spec.js b/spec/frontend/monitoring/components/dashboard_url_time_spec.js
index e6785f34597..246dd598d19 100644
--- a/spec/frontend/monitoring/components/dashboard_url_time_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_url_time_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import {
@@ -51,23 +52,22 @@ describe('dashboard invalid url parameters', () => {
queryToObject.mockReset();
});
- it('passes default url parameters to the time range picker', () => {
+ it('passes default url parameters to the time range picker', async () => {
queryToObject.mockReturnValue({});
createMountedWrapper();
- return wrapper.vm.$nextTick().then(() => {
- expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange);
+ await nextTick();
+ expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange);
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/setTimeRange',
- expect.any(Object),
- );
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
- });
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/setTimeRange',
+ expect.any(Object),
+ );
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
- it('passes a fixed time range in the URL to the time range picker', () => {
+ it('passes a fixed time range in the URL to the time range picker', async () => {
const params = {
start: '2019-01-01T00:00:00.000Z',
end: '2019-01-10T00:00:00.000Z',
@@ -77,37 +77,35 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper();
- return wrapper.vm.$nextTick().then(() => {
- expect(findDateTimePicker().props('value')).toEqual(params);
+ await nextTick();
+ expect(findDateTimePicker().props('value')).toEqual(params);
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setTimeRange', params);
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
- });
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/setTimeRange', params);
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
- it('passes a rolling time range in the URL to the time range picker', () => {
+ it('passes a rolling time range in the URL to the time range picker', async () => {
queryToObject.mockReturnValue({
duration_seconds: '120',
});
createMountedWrapper();
- return wrapper.vm.$nextTick().then(() => {
- const expectedTimeRange = {
- duration: { seconds: 60 * 2 },
- };
+ await nextTick();
+ const expectedTimeRange = {
+ duration: { seconds: 60 * 2 },
+ };
- expect(findDateTimePicker().props('value')).toMatchObject(expectedTimeRange);
+ expect(findDateTimePicker().props('value')).toMatchObject(expectedTimeRange);
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/setTimeRange',
- expectedTimeRange,
- );
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
- });
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/setTimeRange',
+ expectedTimeRange,
+ );
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
- it('shows an error message and loads a default time range if invalid url parameters are passed', () => {
+ it('shows an error message and loads a default time range if invalid url parameters are passed', async () => {
queryToObject.mockReturnValue({
start: '<script>alert("XSS")</script>',
end: '<script>alert("XSS")</script>',
@@ -115,37 +113,35 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper();
- return wrapper.vm.$nextTick().then(() => {
- expect(createFlash).toHaveBeenCalled();
+ await nextTick();
+ expect(createFlash).toHaveBeenCalled();
- expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange);
+ expect(findDateTimePicker().props('value')).toEqual(defaultTimeRange);
- expect(store.dispatch).toHaveBeenCalledWith(
- 'monitoringDashboard/setTimeRange',
- defaultTimeRange,
- );
- expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
- });
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'monitoringDashboard/setTimeRange',
+ defaultTimeRange,
+ );
+ expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
});
- it('redirects to different time range', () => {
+ it('redirects to different time range', async () => {
const toUrl = `${mockProjectDir}/-/environments/1/metrics`;
removeParams.mockReturnValueOnce(toUrl);
createMountedWrapper();
- return wrapper.vm.$nextTick().then(() => {
- findDateTimePicker().vm.$emit('input', {
- duration: { seconds: 120 },
- });
-
- // redirect to with new parameters
- expect(mergeUrlParams).toHaveBeenCalledWith({ duration_seconds: '120' }, toUrl);
- expect(redirectTo).toHaveBeenCalledTimes(1);
+ await nextTick();
+ findDateTimePicker().vm.$emit('input', {
+ duration: { seconds: 120 },
});
+
+ // redirect to with new parameters
+ expect(mergeUrlParams).toHaveBeenCalledWith({ duration_seconds: '120' }, toUrl);
+ expect(redirectTo).toHaveBeenCalledTimes(1);
});
- it('changes the url when a panel moves the time slider', () => {
+ it('changes the url when a panel moves the time slider', async () => {
const timeRange = {
start: '2020-01-01T00:00:00.000Z',
end: '2020-01-01T01:00:00.000Z',
@@ -155,12 +151,11 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper();
- return wrapper.vm.$nextTick().then(() => {
- wrapper.vm.onTimeRangeZoom(timeRange);
+ await nextTick();
+ wrapper.vm.onTimeRangeZoom(timeRange);
- expect(updateHistory).toHaveBeenCalled();
- expect(wrapper.vm.selectedTimeRange.start.toString()).toBe(timeRange.start);
- expect(wrapper.vm.selectedTimeRange.end.toString()).toBe(timeRange.end);
- });
+ expect(updateHistory).toHaveBeenCalled();
+ expect(wrapper.vm.selectedTimeRange.start.toString()).toBe(timeRange.start);
+ expect(wrapper.vm.selectedTimeRange.end.toString()).toBe(timeRange.end);
});
});
diff --git a/spec/frontend/monitoring/components/embeds/embed_group_spec.js b/spec/frontend/monitoring/components/embeds/embed_group_spec.js
index f6229afd180..47366b345a8 100644
--- a/spec/frontend/monitoring/components/embeds/embed_group_spec.js
+++ b/spec/frontend/monitoring/components/embeds/embed_group_spec.js
@@ -1,6 +1,6 @@
import { GlButton, GlCard } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
import EmbedGroup from '~/monitoring/components/embeds/embed_group.vue';
@@ -75,16 +75,14 @@ describe('Embed Group', () => {
expect(wrapper.find('.gl-card-body').classes()).not.toContain('d-none');
});
- it('collapses when clicked', (done) => {
+ it('collapses when clicked', async () => {
metricsWithDataGetter.mockReturnValue([1]);
mountComponent({ shallow: false, stubs: { MetricEmbed: true } });
wrapper.find(GlButton).trigger('click');
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.gl-card-body').classes()).toContain('d-none');
- done();
- });
+ await nextTick();
+ expect(wrapper.find('.gl-card-body').classes()).toContain('d-none');
});
});
diff --git a/spec/frontend/monitoring/components/graph_group_spec.js b/spec/frontend/monitoring/components/graph_group_spec.js
index 625dd3f0b33..c5b45564089 100644
--- a/spec/frontend/monitoring/components/graph_group_spec.js
+++ b/spec/frontend/monitoring/components/graph_group_spec.js
@@ -1,5 +1,6 @@
import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import GraphGroup from '~/monitoring/components/graph_group.vue';
describe('Graph group component', () => {
@@ -38,13 +39,12 @@ describe('Graph group component', () => {
expect(findCaretIcon().props('name')).toBe('angle-down');
});
- it('should show the angle-right caret icon when the user collapses the group', () => {
+ it('should show the angle-right caret icon when the user collapses the group', async () => {
findToggleButton().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findContent().isVisible()).toBe(false);
- expect(findCaretIcon().props('name')).toBe('angle-right');
- });
+ await nextTick();
+ expect(findContent().isVisible()).toBe(false);
+ expect(findCaretIcon().props('name')).toBe('angle-right');
});
it('should contain a tab index for the collapse button', () => {
@@ -53,15 +53,14 @@ describe('Graph group component', () => {
expect(groupToggle.attributes('tabindex')).toBeDefined();
});
- it('should show the open the group when collapseGroup is set to true', () => {
+ it('should show the open the group when collapseGroup is set to true', async () => {
wrapper.setProps({
collapseGroup: true,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findContent().isVisible()).toBe(true);
- expect(findCaretIcon().props('name')).toBe('angle-down');
- });
+ await nextTick();
+ expect(findContent().isVisible()).toBe(true);
+ expect(findCaretIcon().props('name')).toBe('angle-down');
});
});
@@ -77,12 +76,11 @@ describe('Graph group component', () => {
expect(findCaretIcon().props('name')).toBe('angle-right');
});
- it('should show the angle-right caret icon when collapseGroup is false', () => {
+ it('should show the angle-right caret icon when collapseGroup is false', async () => {
findToggleButton().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findCaretIcon().props('name')).toBe('angle-down');
- });
+ await nextTick();
+ expect(findCaretIcon().props('name')).toBe('angle-down');
});
it('should call collapse the graph group content when enter is pressed on the caret icon', () => {
@@ -137,15 +135,14 @@ describe('Graph group component', () => {
expect(findCaretIcon().exists()).toBe(false);
});
- it('should show the panel content when collapse is set to false', () => {
+ it('should show the panel content when collapse is set to false', async () => {
wrapper.setProps({
collapseGroup: false,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findContent().isVisible()).toBe(true);
- expect(findCaretIcon().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findContent().isVisible()).toBe(true);
+ expect(findCaretIcon().exists()).toBe(false);
});
});
});
diff --git a/spec/frontend/monitoring/components/links_section_spec.js b/spec/frontend/monitoring/components/links_section_spec.js
index e37abf6722a..c9b5aeeecb8 100644
--- a/spec/frontend/monitoring/components/links_section_spec.js
+++ b/spec/frontend/monitoring/components/links_section_spec.js
@@ -36,7 +36,7 @@ describe('Links Section component', () => {
expect(findLinks().length).toBe(0);
});
- it('renders a link inside a section', () => {
+ it('renders a link inside a section', async () => {
setState([
{
title: 'GitLab Website',
@@ -44,23 +44,21 @@ describe('Links Section component', () => {
},
]);
- return wrapper.vm.$nextTick(() => {
- expect(findLinks()).toHaveLength(1);
- const firstLink = findLinks().at(0);
+ await nextTick();
+ expect(findLinks()).toHaveLength(1);
+ const firstLink = findLinks().at(0);
- expect(firstLink.attributes('href')).toBe('https://gitlab.com');
- expect(firstLink.text()).toBe('GitLab Website');
- });
+ expect(firstLink.attributes('href')).toBe('https://gitlab.com');
+ expect(firstLink.text()).toBe('GitLab Website');
});
- it('renders multiple links inside a section', () => {
+ it('renders multiple links inside a section', async () => {
const links = new Array(10)
.fill(null)
.map((_, i) => ({ title: `Title ${i}`, url: `https://gitlab.com/projects/${i}` }));
setState(links);
- return wrapper.vm.$nextTick(() => {
- expect(findLinks()).toHaveLength(10);
- });
+ await nextTick();
+ expect(findLinks()).toHaveLength(10);
});
});
diff --git a/spec/frontend/monitoring/components/refresh_button_spec.js b/spec/frontend/monitoring/components/refresh_button_spec.js
index 248cf32d54b..0e45cc021c5 100644
--- a/spec/frontend/monitoring/components/refresh_button_spec.js
+++ b/spec/frontend/monitoring/components/refresh_button_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Visibility from 'visibilityjs';
+import { nextTick } from 'vue';
import RefreshButton from '~/monitoring/components/refresh_button.vue';
import { createStore } from '~/monitoring/stores';
@@ -79,9 +80,9 @@ describe('RefreshButton', () => {
describe('when a refresh rate is chosen', () => {
const optIndex = 2; // Other option than "Off"
- beforeEach(() => {
+ beforeEach(async () => {
findOptionAt(optIndex).vm.$emit('click');
- return wrapper.vm.$nextTick;
+ await nextTick();
});
it('refresh rate appears in the dropdown', () => {
@@ -101,7 +102,7 @@ describe('RefreshButton', () => {
jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(2);
- await wrapper.vm.$nextTick();
+ await nextTick();
jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(3);
@@ -113,7 +114,7 @@ describe('RefreshButton', () => {
jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(1);
- await wrapper.vm.$nextTick();
+ await nextTick();
jest.runOnlyPendingTimers();
expectFetchDataToHaveBeenCalledTimes(1);
@@ -128,9 +129,9 @@ describe('RefreshButton', () => {
});
describe('when "Off" refresh rate is chosen', () => {
- beforeEach(() => {
+ beforeEach(async () => {
findOptionAt(0).vm.$emit('click');
- return wrapper.vm.$nextTick;
+ await nextTick();
});
it('refresh rate is "Off" in the dropdown', () => {
diff --git a/spec/frontend/monitoring/components/variables/dropdown_field_spec.js b/spec/frontend/monitoring/components/variables/dropdown_field_spec.js
index f5ee32e78e6..643bbb39f04 100644
--- a/spec/frontend/monitoring/components/variables/dropdown_field_spec.js
+++ b/spec/frontend/monitoring/components/variables/dropdown_field_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import DropdownField from '~/monitoring/components/variables/dropdown_field.vue';
describe('Custom variable component', () => {
@@ -53,14 +54,13 @@ describe('Custom variable component', () => {
expect(findDropdown().exists()).toBe(true);
});
- it('changing dropdown items triggers update', () => {
+ it('changing dropdown items triggers update', async () => {
createShallowWrapper();
jest.spyOn(wrapper.vm, '$emit');
findDropdownItems().at(1).vm.$emit('click');
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary');
- });
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary');
});
});
diff --git a/spec/frontend/monitoring/components/variables/text_field_spec.js b/spec/frontend/monitoring/components/variables/text_field_spec.js
index c879803fddd..3073b3968aa 100644
--- a/spec/frontend/monitoring/components/variables/text_field_spec.js
+++ b/spec/frontend/monitoring/components/variables/text_field_spec.js
@@ -1,5 +1,6 @@
import { GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import TextField from '~/monitoring/components/variables/text_field.vue';
describe('Text variable component', () => {
@@ -23,15 +24,14 @@ describe('Text variable component', () => {
expect(findInput().exists()).toBe(true);
});
- it('always has a default value', () => {
+ it('always has a default value', async () => {
createShallowWrapper();
- return wrapper.vm.$nextTick(() => {
- expect(findInput().attributes('value')).toBe(propsData.value);
- });
+ await nextTick();
+ expect(findInput().attributes('value')).toBe(propsData.value);
});
- it('triggers keyup enter', () => {
+ it('triggers keyup enter', async () => {
createShallowWrapper();
jest.spyOn(wrapper.vm, '$emit');
@@ -39,12 +39,11 @@ describe('Text variable component', () => {
findInput().trigger('input');
findInput().trigger('keyup.enter');
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'prod-pod');
- });
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'prod-pod');
});
- it('triggers blur enter', () => {
+ it('triggers blur enter', async () => {
createShallowWrapper();
jest.spyOn(wrapper.vm, '$emit');
@@ -52,8 +51,7 @@ describe('Text variable component', () => {
findInput().trigger('input');
findInput().trigger('blur');
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary-pod');
- });
+ await nextTick();
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', 'canary-pod');
});
});
diff --git a/spec/frontend/monitoring/components/variables_section_spec.js b/spec/frontend/monitoring/components/variables_section_spec.js
index 6157de0dafe..64b93bd3027 100644
--- a/spec/frontend/monitoring/components/variables_section_spec.js
+++ b/spec/frontend/monitoring/components/variables_section_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
+import { nextTick } from 'vue';
import { updateHistory, mergeUrlParams } from '~/lib/utils/url_utility';
import DropdownField from '~/monitoring/components/variables/dropdown_field.vue';
import TextField from '~/monitoring/components/variables/text_field.vue';
@@ -40,11 +41,11 @@ describe('Metrics dashboard/variables section component', () => {
});
describe('when variables are set', () => {
- beforeEach(() => {
+ beforeEach(async () => {
store.state.monitoringDashboard.variables = storeVariables;
createShallowWrapper();
- return wrapper.vm.$nextTick;
+ await nextTick();
});
it('shows the variables section', () => {
@@ -83,34 +84,32 @@ describe('Metrics dashboard/variables section component', () => {
createShallowWrapper();
});
- it('merges the url params and refreshes the dashboard when a text-based variables inputs are updated', () => {
+ it('merges the url params and refreshes the dashboard when a text-based variables inputs are updated', async () => {
const firstInput = findTextInputs().at(0);
firstInput.vm.$emit('input', 'test');
- return wrapper.vm.$nextTick(() => {
- expect(updateVariablesAndFetchData).toHaveBeenCalled();
- expect(mergeUrlParams).toHaveBeenCalledWith(
- convertVariablesForURL(storeVariables),
- window.location.href,
- );
- expect(updateHistory).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(updateVariablesAndFetchData).toHaveBeenCalled();
+ expect(mergeUrlParams).toHaveBeenCalledWith(
+ convertVariablesForURL(storeVariables),
+ window.location.href,
+ );
+ expect(updateHistory).toHaveBeenCalled();
});
- it('merges the url params and refreshes the dashboard when a custom-based variables inputs are updated', () => {
+ it('merges the url params and refreshes the dashboard when a custom-based variables inputs are updated', async () => {
const firstInput = findCustomInputs().at(0);
firstInput.vm.$emit('input', 'test');
- return wrapper.vm.$nextTick(() => {
- expect(updateVariablesAndFetchData).toHaveBeenCalled();
- expect(mergeUrlParams).toHaveBeenCalledWith(
- convertVariablesForURL(storeVariables),
- window.location.href,
- );
- expect(updateHistory).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(updateVariablesAndFetchData).toHaveBeenCalled();
+ expect(mergeUrlParams).toHaveBeenCalledWith(
+ convertVariablesForURL(storeVariables),
+ window.location.href,
+ );
+ expect(updateHistory).toHaveBeenCalled();
});
it('does not merge the url params and refreshes the dashboard if the value entered is not different that is what currently stored', () => {
diff --git a/spec/frontend/mr_popover/mr_popover_spec.js b/spec/frontend/mr_popover/mr_popover_spec.js
index 36ad82e93a5..23f97073e9e 100644
--- a/spec/frontend/mr_popover/mr_popover_spec.js
+++ b/spec/frontend/mr_popover/mr_popover_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import MRPopover from '~/mr_popover/components/mr_popover.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
@@ -25,16 +26,15 @@ describe('MR Popover', () => {
});
});
- it('shows skeleton-loader while apollo is loading', () => {
+ it('shows skeleton-loader while apollo is loading', async () => {
wrapper.vm.$apollo.queries.mergeRequest.loading = true;
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.element).toMatchSnapshot();
- });
+ await nextTick();
+ expect(wrapper.element).toMatchSnapshot();
});
describe('loaded state', () => {
- it('matches the snapshot', () => {
+ it('matches the snapshot', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -51,12 +51,11 @@ describe('MR Popover', () => {
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.element).toMatchSnapshot();
- });
+ await nextTick();
+ expect(wrapper.element).toMatchSnapshot();
});
- it('does not show CI Icon if there is no pipeline data', () => {
+ it('does not show CI Icon if there is no pipeline data', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
@@ -69,15 +68,13 @@ describe('MR Popover', () => {
},
});
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find(CiIcon).exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find(CiIcon).exists()).toBe(false);
});
- it('falls back to cached MR title when request fails', () => {
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.text()).toContain('MR Title');
- });
+ it('falls back to cached MR title when request fails', async () => {
+ await nextTick();
+ expect(wrapper.text()).toContain('MR Title');
});
});
});
diff --git a/spec/frontend/nav/components/responsive_app_spec.js b/spec/frontend/nav/components/responsive_app_spec.js
index 4af8c6020bc..76b8ebdc92f 100644
--- a/spec/frontend/nav/components/responsive_app_spec.js
+++ b/spec/frontend/nav/components/responsive_app_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import ResponsiveApp from '~/nav/components/responsive_app.vue';
import ResponsiveHeader from '~/nav/components/responsive_header.vue';
import ResponsiveHome from '~/nav/components/responsive_home.vue';
@@ -62,7 +63,7 @@ describe('~/nav/components/responsive_app.vue', () => {
wrapper.vm.$root.$emit(evt);
- await wrapper.vm.$nextTick();
+ await nextTick();
}, Promise.resolve());
expect(hasMobileOverlayVisible()).toBe(expectation);
@@ -97,7 +98,7 @@ describe('~/nav/components/responsive_app.vue', () => {
findHome().vm.$emit('menu-item-click', { view });
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows header', () => {
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index 16dbf60cef4..1e4d9f313f0 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -466,8 +466,8 @@ describe('issue_comment_form component', () => {
await findCloseReopenButton().trigger('click');
- await wrapper.vm.$nextTick;
- await wrapper.vm.$nextTick;
+ await nextTick;
+ await nextTick;
expect(createFlash).toHaveBeenCalledWith({
message: `Something went wrong while closing the ${type}. Please try again later.`,
@@ -502,8 +502,8 @@ describe('issue_comment_form component', () => {
await findCloseReopenButton().trigger('click');
- await wrapper.vm.$nextTick;
- await wrapper.vm.$nextTick;
+ await nextTick;
+ await nextTick;
expect(createFlash).toHaveBeenCalledWith({
message: `Something went wrong while reopening the ${type}. Please try again later.`,
@@ -521,7 +521,7 @@ describe('issue_comment_form component', () => {
await findCloseReopenButton().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(refreshUserMergeRequestCounts).toHaveBeenCalled();
});
@@ -581,7 +581,7 @@ describe('issue_comment_form component', () => {
// check checkbox
checkbox.element.checked = shouldCheckboxBeChecked;
checkbox.trigger('change');
- await wrapper.vm.$nextTick();
+ await nextTick();
// submit comment
findCommentButton().trigger('click');
diff --git a/spec/frontend/notes/components/diff_discussion_header_spec.js b/spec/frontend/notes/components/diff_discussion_header_spec.js
index fa34a5e8d39..9f94dd693cb 100644
--- a/spec/frontend/notes/components/diff_discussion_header_spec.js
+++ b/spec/frontend/notes/components/diff_discussion_header_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import diffDiscussionHeader from '~/notes/components/diff_discussion_header.vue';
import createStore from '~/notes/stores';
@@ -24,16 +25,15 @@ describe('diff_discussion_header component', () => {
wrapper.destroy();
});
- it('should render user avatar', () => {
+ it('should render user avatar', async () => {
const discussion = { ...discussionMock };
discussion.diff_file = mockDiffFile;
discussion.diff_discussion = true;
wrapper.setProps({ discussion });
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('.user-avatar-link').exists()).toBe(true);
- });
+ await nextTick();
+ expect(wrapper.find('.user-avatar-link').exists()).toBe(true);
});
describe('action text', () => {
@@ -41,7 +41,7 @@ describe('diff_discussion_header component', () => {
const truncatedCommitId = commitId.substr(0, 8);
let commitElement;
- beforeEach((done) => {
+ beforeEach(async () => {
store.state.diffs = {
projectPath: 'something',
};
@@ -58,41 +58,30 @@ describe('diff_discussion_header component', () => {
},
});
- wrapper.vm
- .$nextTick()
- .then(() => {
- commitElement = wrapper.find('.commit-sha');
- })
- .then(done)
- .catch(done.fail);
+ await nextTick();
+ commitElement = wrapper.find('.commit-sha');
});
describe('for diff threads without a commit id', () => {
- it('should show started a thread on the diff text', (done) => {
+ it('should show started a thread on the diff text', async () => {
Object.assign(wrapper.vm.discussion, {
for_commit: false,
commit_id: null,
});
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain('started a thread on the diff');
-
- done();
- });
+ await nextTick();
+ expect(wrapper.text()).toContain('started a thread on the diff');
});
- it('should show thread on older version text', (done) => {
+ it('should show thread on older version text', async () => {
Object.assign(wrapper.vm.discussion, {
for_commit: false,
commit_id: null,
active: false,
});
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain('started a thread on an old version of the diff');
-
- done();
- });
+ await nextTick();
+ expect(wrapper.text()).toContain('started a thread on an old version of the diff');
});
});
@@ -105,31 +94,25 @@ describe('diff_discussion_header component', () => {
});
describe('for diff thread with a commit id', () => {
- it('should display started thread on commit header', (done) => {
+ it('should display started thread on commit header', async () => {
wrapper.vm.discussion.for_commit = false;
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`);
-
- expect(commitElement).not.toBe(null);
+ await nextTick();
+ expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`);
- done();
- });
+ expect(commitElement).not.toBe(null);
});
- it('should display outdated change on commit header', (done) => {
+ it('should display outdated change on commit header', async () => {
wrapper.vm.discussion.for_commit = false;
wrapper.vm.discussion.active = false;
- wrapper.vm.$nextTick(() => {
- expect(wrapper.text()).toContain(
- `started a thread on an outdated change in commit ${truncatedCommitId}`,
- );
+ await nextTick();
+ expect(wrapper.text()).toContain(
+ `started a thread on an outdated change in commit ${truncatedCommitId}`,
+ );
- expect(commitElement).not.toBe(null);
-
- done();
- });
+ expect(commitElement).not.toBe(null);
});
});
});
diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js
index 924c89c6345..a856d002d2e 100644
--- a/spec/frontend/notes/components/discussion_counter_spec.js
+++ b/spec/frontend/notes/components/discussion_counter_spec.js
@@ -1,6 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import DiscussionCounter from '~/notes/components/discussion_counter.vue';
import notesModule from '~/notes/stores/modules';
@@ -113,7 +113,7 @@ describe('DiscussionCounter component', () => {
expect(setExpandDiscussionsFn).toHaveBeenCalledTimes(1);
});
- it('collapses all discussions if expanded', () => {
+ it('collapses all discussions if expanded', async () => {
updateStoreWithExpanded(true);
expect(wrapper.vm.allExpanded).toBe(true);
@@ -121,13 +121,12 @@ describe('DiscussionCounter component', () => {
toggleAllButton.vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.allExpanded).toBe(false);
- expect(toggleAllButton.props('icon')).toBe('angle-down');
- });
+ await nextTick();
+ expect(wrapper.vm.allExpanded).toBe(false);
+ expect(toggleAllButton.props('icon')).toBe('angle-down');
});
- it('expands all discussions if collapsed', () => {
+ it('expands all discussions if collapsed', async () => {
updateStoreWithExpanded(false);
expect(wrapper.vm.allExpanded).toBe(false);
@@ -135,10 +134,9 @@ describe('DiscussionCounter component', () => {
toggleAllButton.vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.allExpanded).toBe(true);
- expect(toggleAllButton.props('icon')).toBe('angle-up');
- });
+ await nextTick();
+ expect(wrapper.vm.allExpanded).toBe(true);
+ expect(toggleAllButton.props('icon')).toBe('angle-up');
});
});
});
diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js
index 1f97bb97415..27206bddbfc 100644
--- a/spec/frontend/notes/components/discussion_filter_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_spec.js
@@ -1,6 +1,6 @@
import { GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import AxiosMockAdapter from 'axios-mock-adapter';
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
@@ -151,13 +151,11 @@ describe('DiscussionFilter component', () => {
window.mrTabs = undefined;
});
- it('only renders when discussion tab is active', (done) => {
+ it('only renders when discussion tab is active', async () => {
eventHub.$emit('MergeRequestTabChange', 'commit');
- wrapper.vm.$nextTick(() => {
- expect(wrapper.html()).toBe('');
- done();
- });
+ await nextTick();
+ expect(wrapper.html()).toBe('');
});
});
@@ -166,58 +164,48 @@ describe('DiscussionFilter component', () => {
window.location.hash = '';
});
- it('updates the filter when the URL links to a note', (done) => {
+ it('updates the filter when the URL links to a note', async () => {
window.location.hash = `note_${discussionMock.notes[0].id}`;
wrapper.vm.currentValue = discussionFiltersMock[2].value;
wrapper.vm.handleLocationHash();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
- done();
- });
+ await nextTick();
+ expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
});
- it('does not update the filter when the current filter is "Show all activity"', (done) => {
+ it('does not update the filter when the current filter is "Show all activity"', async () => {
window.location.hash = `note_${discussionMock.notes[0].id}`;
wrapper.vm.handleLocationHash();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
- done();
- });
+ await nextTick();
+ expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
});
- it('only updates filter when the URL links to a note', (done) => {
+ it('only updates filter when the URL links to a note', async () => {
window.location.hash = `testing123`;
wrapper.vm.handleLocationHash();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
- done();
- });
+ await nextTick();
+ expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE);
});
- it('fetches discussions when there is a hash', (done) => {
+ it('fetches discussions when there is a hash', async () => {
window.location.hash = `note_${discussionMock.notes[0].id}`;
wrapper.vm.currentValue = discussionFiltersMock[2].value;
jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {});
wrapper.vm.handleLocationHash();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.selectFilter).toHaveBeenCalled();
- done();
- });
+ await nextTick();
+ expect(wrapper.vm.selectFilter).toHaveBeenCalled();
});
- it('does not fetch discussions when there is no hash', (done) => {
+ it('does not fetch discussions when there is no hash', async () => {
window.location.hash = '';
jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {});
wrapper.vm.handleLocationHash();
- wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.selectFilter).not.toHaveBeenCalled();
- done();
- });
+ await nextTick();
+ expect(wrapper.vm.selectFilter).not.toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js
index 59ac75f00e6..3506b6ac9f3 100644
--- a/spec/frontend/notes/components/discussion_notes_spec.js
+++ b/spec/frontend/notes/components/discussion_notes_spec.js
@@ -1,6 +1,7 @@
import { getByRole } from '@testing-library/dom';
import { shallowMount, mount } from '@vue/test-utils';
import '~/behaviors/markdown/render_gfm';
+import { nextTick } from 'vue';
import DiscussionNotes from '~/notes/components/discussion_notes.vue';
import NoteableNote from '~/notes/components/noteable_note.vue';
import { SYSTEM_NOTE } from '~/notes/constants';
@@ -135,28 +136,25 @@ describe('DiscussionNotes', () => {
createComponent({ shouldGroupReplies: true, isExpanded: true });
});
- it('emits deleteNote when first note emits handleDeleteNote', () => {
+ it('emits deleteNote when first note emits handleDeleteNote', async () => {
findNoteAtIndex(0).vm.$emit('handleDeleteNote');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().deleteNote).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().deleteNote).toBeTruthy();
});
- it('emits startReplying when first note emits startReplying', () => {
+ it('emits startReplying when first note emits startReplying', async () => {
findNoteAtIndex(0).vm.$emit('startReplying');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().startReplying).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().startReplying).toBeTruthy();
});
- it('emits deleteNote when second note emits handleDeleteNote', () => {
+ it('emits deleteNote when second note emits handleDeleteNote', async () => {
findNoteAtIndex(1).vm.$emit('handleDeleteNote');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().deleteNote).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().deleteNote).toBeTruthy();
});
});
@@ -167,12 +165,11 @@ describe('DiscussionNotes', () => {
note = wrapper.find('.notes > *');
});
- it('emits deleteNote when first note emits handleDeleteNote', () => {
+ it('emits deleteNote when first note emits handleDeleteNote', async () => {
note.vm.$emit('handleDeleteNote');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().deleteNote).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().deleteNote).toBeTruthy();
});
});
});
diff --git a/spec/frontend/notes/components/discussion_resolve_button_spec.js b/spec/frontend/notes/components/discussion_resolve_button_spec.js
index 64e061830b9..ca0c0ca6de8 100644
--- a/spec/frontend/notes/components/discussion_resolve_button_spec.js
+++ b/spec/frontend/notes/components/discussion_resolve_button_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue';
const buttonTitle = 'Resolve discussion';
@@ -26,15 +27,14 @@ describe('resolveDiscussionButton', () => {
wrapper.destroy();
});
- it('should emit a onClick event on button click', () => {
+ it('should emit a onClick event on button click', async () => {
const button = wrapper.find(GlButton);
button.vm.$emit('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted()).toEqual({
- onClick: [[]],
- });
+ await nextTick();
+ expect(wrapper.emitted()).toEqual({
+ onClick: [[]],
});
});
@@ -57,7 +57,7 @@ describe('resolveDiscussionButton', () => {
expect(button.props('loading')).toEqual(true);
});
- it('should only show a loading spinner while resolving', () => {
+ it('should only show a loading spinner while resolving', async () => {
factory({
propsData: {
isResolving: false,
@@ -67,8 +67,7 @@ describe('resolveDiscussionButton', () => {
const button = wrapper.find(GlButton);
- wrapper.vm.$nextTick(() => {
- expect(button.props('loading')).toEqual(false);
- });
+ await nextTick();
+ expect(button.props('loading')).toEqual(false);
});
});
diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js
index 038aff3be04..c7115a5911b 100644
--- a/spec/frontend/notes/components/noteable_note_spec.js
+++ b/spec/frontend/notes/components/noteable_note_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
@@ -107,11 +107,11 @@ describe('issue_note', () => {
line,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findMultilineComment().text()).toBe('Comment on lines 1 to 2');
});
- it('should only render if it has everything it needs', () => {
+ it('should only render if it has everything it needs', async () => {
const position = {
line_range: {
start: {
@@ -140,12 +140,11 @@ describe('issue_note', () => {
line,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findMultilineComment().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findMultilineComment().exists()).toBe(false);
});
- it('should not render if has single line comment', () => {
+ it('should not render if has single line comment', async () => {
const position = {
line_range: {
start: {
@@ -174,9 +173,8 @@ describe('issue_note', () => {
line,
});
- return wrapper.vm.$nextTick().then(() => {
- expect(findMultilineComment().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findMultilineComment().exists()).toBe(false);
});
it('should not render if `line_range` is unavailable', () => {
@@ -204,7 +202,7 @@ describe('issue_note', () => {
line,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.findComponent(UserAvatarLink).props('imgSize')).toBe(24);
});
@@ -318,13 +316,13 @@ describe('issue_note', () => {
callback: () => {},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
let noteBodyProps = noteBody.props();
expect(noteBodyProps.note.note_html).toBe(`<p>${updatedText}</p>\n`);
noteBody.vm.$emit('cancelForm', {});
- await wrapper.vm.$nextTick();
+ await nextTick();
noteBodyProps = noteBody.props();
diff --git a/spec/frontend/notes/components/timeline_toggle_spec.js b/spec/frontend/notes/components/timeline_toggle_spec.js
index 0b304e5181b..84fa3008835 100644
--- a/spec/frontend/notes/components/timeline_toggle_spec.js
+++ b/spec/frontend/notes/components/timeline_toggle_spec.js
@@ -1,6 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import TimelineToggle, {
timelineEnabledTooltip,
@@ -64,7 +64,7 @@ describe('Timeline toggle', () => {
it('should set correct UI state', async () => {
store.state.isTimelineEnabled = true;
findGlButton().vm.$emit('click', mockEvent);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findGlButton().attributes('title')).toBe(timelineEnabledTooltip);
expect(findGlButton().attributes('selected')).toBe('true');
expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
@@ -72,7 +72,7 @@ describe('Timeline toggle', () => {
it('should track Snowplow event', async () => {
store.state.isTimelineEnabled = true;
- await wrapper.vm.$nextTick();
+ await nextTick();
findGlButton().trigger('click');
@@ -97,7 +97,7 @@ describe('Timeline toggle', () => {
it('should set correct UI state', async () => {
store.state.isTimelineEnabled = false;
findGlButton().vm.$emit('click', mockEvent);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findGlButton().attributes('title')).toBe(timelineDisabledTooltip);
expect(findGlButton().attributes('selected')).toBe(undefined);
expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
@@ -105,7 +105,7 @@ describe('Timeline toggle', () => {
it('should track Snowplow event', async () => {
store.state.isTimelineEnabled = false;
- await wrapper.vm.$nextTick();
+ await nextTick();
findGlButton().trigger('click');
diff --git a/spec/frontend/notes/mixins/discussion_navigation_spec.js b/spec/frontend/notes/mixins/discussion_navigation_spec.js
index 3daf23c83cf..1f71947b3cd 100644
--- a/spec/frontend/notes/mixins/discussion_navigation_spec.js
+++ b/spec/frontend/notes/mixins/discussion_navigation_spec.js
@@ -93,14 +93,13 @@ describe('Discussion navigation mixin', () => {
expect(store.dispatch).toHaveBeenCalledWith('setCurrentDiscussionId', null);
});
- it('triggers the jumpToNextDiscussion action when the previous store action succeeds', () => {
+ it('triggers the jumpToNextDiscussion action when the previous store action succeeds', async () => {
store.dispatch.mockResolvedValue();
vm.jumpToFirstUnresolvedDiscussion();
- return vm.$nextTick().then(() => {
- expect(vm.jumpToNextDiscussion).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(vm.jumpToNextDiscussion).toHaveBeenCalled();
});
});
@@ -126,11 +125,11 @@ describe('Discussion navigation mixin', () => {
});
describe('on `show` active tab', () => {
- beforeEach(() => {
+ beforeEach(async () => {
window.mrTabs.currentAction = 'show';
wrapper.vm[fn](...args);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets current discussion', () => {
@@ -150,11 +149,11 @@ describe('Discussion navigation mixin', () => {
});
describe('on `diffs` active tab', () => {
- beforeEach(() => {
+ beforeEach(async () => {
window.mrTabs.currentAction = 'diffs';
wrapper.vm[fn](...args);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets current discussion', () => {
@@ -178,11 +177,11 @@ describe('Discussion navigation mixin', () => {
});
describe('on `other` active tab', () => {
- beforeEach(() => {
+ beforeEach(async () => {
window.mrTabs.currentAction = 'other';
wrapper.vm[fn](...args);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets current discussion', () => {
diff --git a/spec/frontend/notifications/components/custom_notifications_modal_spec.js b/spec/frontend/notifications/components/custom_notifications_modal_spec.js
index 7a036d25559..c5d201c3aec 100644
--- a/spec/frontend/notifications/components/custom_notifications_modal_spec.js
+++ b/spec/frontend/notifications/components/custom_notifications_modal_spec.js
@@ -2,6 +2,7 @@ import { GlSprintf, GlModal, GlFormGroup, GlFormCheckbox, GlLoadingIcon } from '
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import httpStatus from '~/lib/utils/http_status';
@@ -97,7 +98,7 @@ describe('CustomNotificationsModal', () => {
],
});
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it.each`
@@ -222,7 +223,7 @@ describe('CustomNotificationsModal', () => {
],
});
- await wrapper.vm.$nextTick();
+ await nextTick();
findCheckboxAt(1).vm.$emit('change', true);
@@ -252,7 +253,7 @@ describe('CustomNotificationsModal', () => {
],
});
- await wrapper.vm.$nextTick();
+ await nextTick();
findCheckboxAt(1).vm.$emit('change', true);
diff --git a/spec/frontend/operation_settings/components/metrics_settings_spec.js b/spec/frontend/operation_settings/components/metrics_settings_spec.js
index 258c6eae692..c1fa1d24a82 100644
--- a/spec/frontend/operation_settings/components/metrics_settings_spec.js
+++ b/spec/frontend/operation_settings/components/metrics_settings_spec.js
@@ -1,5 +1,6 @@
import { GlButton, GlLink, GlFormGroup, GlFormInput, GlFormSelect } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
@@ -181,17 +182,18 @@ describe('operation settings external dashboard component', () => {
expect(submit.text()).toBe('Save Changes');
});
- it('submits form on click', () => {
+ it('submits form on click', async () => {
mountComponent(false);
axios.patch.mockResolvedValue();
findSubmitButton().trigger('click');
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
- return wrapper.vm.$nextTick().then(() => expect(refreshCurrentPage).toHaveBeenCalled());
+ await nextTick();
+ expect(refreshCurrentPage).toHaveBeenCalled();
});
- it('creates flash banner on error', () => {
+ it('creates flash banner on error', async () => {
mountComponent(false);
const message = 'mockErrorMessage';
axios.patch.mockRejectedValue({ response: { data: { message } } });
@@ -199,14 +201,11 @@ describe('operation settings external dashboard component', () => {
expect(axios.patch).toHaveBeenCalledWith(...endpointRequest);
- return wrapper.vm
- .$nextTick()
- .then(jest.runAllTicks)
- .then(() =>
- expect(createFlash).toHaveBeenCalledWith({
- message: `There was an error saving your changes. ${message}`,
- }),
- );
+ await nextTick();
+ await jest.runAllTicks();
+ expect(createFlash).toHaveBeenCalledWith({
+ message: `There was an error saving your changes. ${message}`,
+ });
});
});
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
index 5278e730ec9..f4c22d9bfa7 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
@@ -1,6 +1,7 @@
import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
+import { nextTick } from 'vue';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -54,8 +55,8 @@ describe('Details Header', () => {
const waitForMetadataItems = async () => {
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
+ await nextTick();
+ await nextTick();
};
const mountComponent = ({
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
index 7d9f89518d5..ef6c4a1fa32 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
@@ -1,5 +1,5 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import { GlEmptyState } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -22,8 +22,6 @@ import {
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import { tagsMock, imageTagsMock, tagsPageInfo } from '../../mock_data';
-const localVue = createLocalVue();
-
describe('Tags List', () => {
let wrapper;
let apolloProvider;
@@ -50,13 +48,12 @@ describe('Tags List', () => {
};
const mountComponent = ({ propsData = { isMobile: false, id: 1 } } = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [[getContainerRepositoryTagsQuery, resolver]];
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
- localVue,
apolloProvider,
propsData,
stubs: { RegistryList },
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
index 92cfeb7633e..c91a9c0f0fb 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
@@ -1,5 +1,6 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Component from '~/packages_and_registries/container_registry/explorer/components/list_page/registry_header.vue';
import {
CONTAINER_REGISTRY_TITLE,
@@ -21,7 +22,7 @@ describe('registry_header', () => {
const findImagesCountSubHeader = () => wrapper.find('[data-testid="images-count"]');
const findExpirationPolicySubHeader = () => wrapper.find('[data-testid="expiration-policy"]');
- const mountComponent = (propsData, slots) => {
+ const mountComponent = async (propsData, slots) => {
wrapper = shallowMount(Component, {
stubs: {
GlSprintf,
@@ -30,7 +31,7 @@ describe('registry_header', () => {
propsData,
slots,
});
- return wrapper.vm.$nextTick();
+ await nextTick();
};
afterEach(() => {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
index 1f8cda55f39..c602b37c3b5 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
@@ -1,7 +1,8 @@
import { GlKeysetPagination, GlEmptyState } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
+
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
@@ -39,8 +40,6 @@ import {
} from '../mock_data';
import { DeleteModal } from '../stubs';
-const localVue = createLocalVue();
-
describe('Details Page', () => {
let wrapper;
let apolloProvider;
@@ -85,7 +84,7 @@ describe('Details Page', () => {
options,
config = defaultConfig,
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [
[getContainerRepositoryDetailsQuery, resolver],
@@ -96,7 +95,6 @@ describe('Details Page', () => {
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
- localVue,
apolloProvider,
stubs: {
DeleteModal,
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
index c4984d1b6ae..bda0f3616a4 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
@@ -1,6 +1,7 @@
import { GlSkeletonLoader, GlSprintf, GlAlert } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -38,8 +39,6 @@ import {
} from '../mock_data';
import { GlModal, GlEmptyState } from '../stubs';
-const localVue = createLocalVue();
-
describe('List Page', () => {
let wrapper;
let apolloProvider;
@@ -75,7 +74,7 @@ describe('List Page', () => {
config = { isGroupPage: false },
query = {},
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [
[getContainerRepositoriesQuery, resolver],
@@ -86,7 +85,6 @@ describe('List Page', () => {
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
- localVue,
apolloProvider,
stubs: {
GlModal,
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js b/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
index 842b63ac0d5..79894e25889 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
@@ -5,7 +5,7 @@ import {
GlSprintf,
GlEmptyState,
} from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -21,8 +21,6 @@ import getDependencyProxyDetailsQuery from '~/packages_and_registries/dependency
import { proxyDetailsQuery, proxyData, pagination, proxyManifests } from './mock_data';
-const localVue = createLocalVue();
-
describe('DependencyProxyApp', () => {
let wrapper;
let apolloProvider;
@@ -35,14 +33,13 @@ describe('DependencyProxyApp', () => {
};
function createComponent({ provide = provideDefaults } = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [[getDependencyProxyDetailsQuery, resolver]];
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMountExtended(DependencyProxyApp, {
- localVue,
apolloProvider,
provide,
stubs: {
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
index 95b70cb010d..b504f7489ab 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import component from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
@@ -11,7 +11,10 @@ describe('PackageTitle', () => {
let wrapper;
let store;
- function createComponent({ packageFiles = mavenFiles, packageEntity = terraformModule } = {}) {
+ async function createComponent({
+ packageFiles = mavenFiles,
+ packageEntity = terraformModule,
+ } = {}) {
store = new Vuex.Store({
state: {
packageEntity,
@@ -28,7 +31,7 @@ describe('PackageTitle', () => {
TitleArea,
},
});
- return wrapper.vm.$nextTick();
+ await nextTick();
}
const findTitleArea = () => wrapper.findComponent(TitleArea);
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
index 5efd23f8d7e..fed82653016 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
@@ -1,6 +1,6 @@
import { GlTable, GlPagination, GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { last } from 'lodash';
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children';
@@ -120,16 +120,15 @@ describe('packages_list', () => {
mountComponent();
});
- it('setItemToBeDeleted sets itemToBeDeleted and open the modal', () => {
+ it('setItemToBeDeleted sets itemToBeDeleted and open the modal', async () => {
const mockModalShow = jest.spyOn(wrapper.vm.$refs.packageListDeleteModal, 'show');
const item = last(wrapper.vm.list);
findPackagesListRow().vm.$emit('packageToDelete', item);
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm.itemToBeDeleted).toEqual(item);
- expect(mockModalShow).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(wrapper.vm.itemToBeDeleted).toEqual(item);
+ expect(mockModalShow).toHaveBeenCalled();
});
it('deleteItemConfirmation resets itemToBeDeleted', () => {
@@ -140,15 +139,14 @@ describe('packages_list', () => {
expect(wrapper.vm.itemToBeDeleted).toEqual(null);
});
- it('deleteItemConfirmation emit package:delete', () => {
+ it('deleteItemConfirmation emit package:delete', async () => {
const itemToBeDeleted = { id: 2 };
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted });
wrapper.vm.deleteItemConfirmation();
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]);
- });
+ await nextTick();
+ expect(wrapper.emitted('package:delete')[0]).toEqual([itemToBeDeleted]);
});
it('deleteItemCanceled resets itemToBeDeleted', () => {
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js
index 1052fdd1dda..79c1b18c9f9 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js
@@ -1,4 +1,5 @@
import { GlLink } from '@gitlab/ui';
+import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -126,7 +127,7 @@ describe('packages_list_row', () => {
findDeleteButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('packageToDelete')).toBeTruthy();
expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]);
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
index 6ad6007c9da..5da9cfffaae 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
+import { nextTick } from 'vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
@@ -24,7 +25,7 @@ const packageWithTags = {
describe('PackageTitle', () => {
let wrapper;
- function createComponent(packageEntity = packageWithTags) {
+ async function createComponent(packageEntity = packageWithTags) {
wrapper = shallowMountExtended(PackageTitle, {
propsData: { packageEntity },
stubs: {
@@ -35,7 +36,7 @@ describe('PackageTitle', () => {
GlResizeObserver: createMockDirective(),
},
});
- return wrapper.vm.$nextTick();
+ await nextTick();
}
const findTitleArea = () => wrapper.findComponent(TitleArea);
@@ -71,7 +72,7 @@ describe('PackageTitle', () => {
await createComponent();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length);
});
@@ -85,7 +86,7 @@ describe('PackageTitle', () => {
const { value } = getBinding(wrapper.element, 'gl-resize-observer');
value();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findPackageBadges()).toHaveLength(packageTags().length);
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js b/spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js
index 5de30829fa5..14a70def7d0 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js
@@ -1,4 +1,4 @@
-import { createLocalVue } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import waitForPromises from 'helpers/wait_for_promises';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -16,8 +16,6 @@ import {
jest.mock('~/flash');
-const localVue = createLocalVue();
-
describe('DeletePackage', () => {
let wrapper;
let apolloProvider;
@@ -27,7 +25,7 @@ describe('DeletePackage', () => {
const eventPayload = { id: '1' };
function createComponent(propsData = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [
[getPackagesQuery, resolver],
@@ -37,7 +35,6 @@ describe('DeletePackage', () => {
wrapper = shallowMountExtended(DeletePackage, {
propsData,
- localVue,
apolloProvider,
scopedSlots: {
default(props) {
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
index 05f20f8150b..12a3eaa3873 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
@@ -1,5 +1,5 @@
import { GlSprintf } from '@gitlab/ui';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueRouter from 'vue-router';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -119,7 +119,7 @@ describe('packages_list_row', () => {
findDeleteButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('packageToDelete')).toBeTruthy();
expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]);
});
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
index 637e2edf3be..b9fbaad7734 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
@@ -1,6 +1,6 @@
import { GlEmptyState, GlBadge, GlTabs, GlTab } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import Vue, { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
@@ -41,8 +41,6 @@ import {
jest.mock('~/flash');
useMockLocationHelper();
-const localVue = createLocalVue();
-
describe('PackagesApp', () => {
let wrapper;
let apolloProvider;
@@ -64,7 +62,7 @@ describe('PackagesApp', () => {
fileDeleteMutationResolver = jest.fn().mockResolvedValue(packageDestroyFileMutation()),
routeId = '1',
} = {}) {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [
[getPackageDetails, resolver],
@@ -73,7 +71,6 @@ describe('PackagesApp', () => {
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMountExtended(PackagesApp, {
- localVue,
apolloProvider,
provide,
stubs: {
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
index 8121d9c7dbd..0e74fbbc6d9 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
@@ -1,8 +1,8 @@
import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
+
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -27,8 +27,6 @@ import { packagesListQuery, packageData, pagination } from '../mock_data';
jest.mock('~/lib/utils/common_utils');
jest.mock('~/flash');
-const localVue = createLocalVue();
-
describe('PackagesListApp', () => {
let wrapper;
let apolloProvider;
@@ -61,13 +59,12 @@ describe('PackagesListApp', () => {
resolver = jest.fn().mockResolvedValue(packagesListQuery()),
provide = defaultProvide,
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [[getPackagesQuery, resolver]];
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMountExtended(ListPage, {
- localVue,
apolloProvider,
provide,
stubs: {
diff --git a/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js
index f6c1d212b51..94f56e5c979 100644
--- a/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js
+++ b/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js
@@ -1,5 +1,5 @@
import { GlSprintf, GlToggle } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -33,8 +33,6 @@ import {
jest.mock('~/flash');
jest.mock('~/packages_and_registries/settings/group/graphql/utils/optimistic_responses');
-const localVue = createLocalVue();
-
describe('DependencyProxySettings', () => {
let wrapper;
let apolloProvider;
@@ -47,7 +45,7 @@ describe('DependencyProxySettings', () => {
groupDependencyProxyPath: 'group_dependency_proxy_path',
};
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const mountComponent = ({
provide = defaultProvide,
@@ -63,7 +61,6 @@ describe('DependencyProxySettings', () => {
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMountExtended(component, {
- localVue,
apolloProvider,
provide,
propsData: {
diff --git a/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js b/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js
index 933dac7f5a8..5c30074a6af 100644
--- a/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js
+++ b/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js
@@ -1,7 +1,8 @@
import { GlAlert } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
+
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import PackagesSettings from '~/packages_and_registries/settings/group/components/packages_settings.vue';
@@ -19,8 +20,6 @@ import {
jest.mock('~/flash');
-const localVue = createLocalVue();
-
describe('Group Settings App', () => {
let wrapper;
let apolloProvider;
@@ -36,14 +35,13 @@ describe('Group Settings App', () => {
resolver = jest.fn().mockResolvedValue(groupPackageSettingsMock),
provide = defaultProvide,
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [[getGroupPackagesSettingsQuery, resolver]];
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
- localVue,
apolloProvider,
provide,
mocks: {
diff --git a/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
index 693af21e24a..d92d42e7834 100644
--- a/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
+++ b/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
@@ -1,5 +1,5 @@
import { GlSprintf, GlLink } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -28,8 +28,6 @@ import {
jest.mock('~/flash');
jest.mock('~/packages_and_registries/settings/group/graphql/utils/optimistic_responses');
-const localVue = createLocalVue();
-
describe('Packages Settings', () => {
let wrapper;
let apolloProvider;
@@ -42,14 +40,13 @@ describe('Packages Settings', () => {
const mountComponent = ({
mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock()),
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [[updateNamespacePackageSettings, mutationResolver]];
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMountExtended(component, {
- localVue,
apolloProvider,
provide: defaultProvide,
propsData: {
@@ -252,7 +249,7 @@ describe('Packages Settings', () => {
emitMavenSettingsUpdate();
- await wrapper.vm.$nextTick();
+ await nextTick();
// errors are reset on mutation call
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe('');
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js
index cad5d4db033..a6c929844b1 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -20,8 +21,6 @@ import {
containerExpirationPolicyData,
} from '../mock_data';
-const localVue = createLocalVue();
-
describe('Registry Settings App', () => {
let wrapper;
let fakeApollo;
@@ -56,13 +55,12 @@ describe('Registry Settings App', () => {
};
const mountComponentWithApollo = ({ provide = defaultProvidedValues, resolver } = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [[expirationPolicyQuery, resolver]];
fakeApollo = createMockApollo(requestHandlers);
mountComponent(provide, {
- localVue,
apolloProvider: fakeApollo,
});
};
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
index bc104a25ef9..625aa37fc0f 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
@@ -1,5 +1,6 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
+import { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { GlCard, GlLoadingIcon } from 'jest/packages_and_registries/shared/stubs';
@@ -201,7 +202,7 @@ describe('Settings Form', () => {
finder().vm.$emit('input', 'foo');
expect(finder().props('error')).toEqual('bar');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(finder().props('error')).toEqual('');
});
@@ -213,7 +214,7 @@ describe('Settings Form', () => {
finder().vm.$emit('validation', false);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findSaveButton().props('disabled')).toBe(true);
});
@@ -252,7 +253,7 @@ describe('Settings Form', () => {
findForm().trigger('reset');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findKeepRegexInput().props('error')).toBe('');
expect(findRemoveRegexInput().props('error')).toBe('');
@@ -319,7 +320,7 @@ describe('Settings Form', () => {
findForm().trigger('submit');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE);
});
@@ -335,7 +336,7 @@ describe('Settings Form', () => {
findForm().trigger('submit');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo');
});
@@ -349,7 +350,7 @@ describe('Settings Form', () => {
findForm().trigger('submit');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
});
@@ -368,7 +369,7 @@ describe('Settings Form', () => {
findForm().trigger('submit');
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findKeepRegexInput().props('error')).toEqual('baz');
});
diff --git a/spec/frontend/pages/admin/projects/components/namespace_select_spec.js b/spec/frontend/pages/admin/projects/components/namespace_select_spec.js
index 1fcc00489e3..f10b202f4d7 100644
--- a/spec/frontend/pages/admin/projects/components/namespace_select_spec.js
+++ b/spec/frontend/pages/admin/projects/components/namespace_select_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Api from '~/api';
import NamespaceSelect from '~/pages/admin/projects/components/namespace_select.vue';
@@ -55,14 +56,14 @@ describe('Dropdown select component', () => {
mountDropdown({ fieldName: 'namespace-input' });
// wait for dropdown options to populate
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDropdownOption('user: Administrator').exists()).toBe(true);
expect(findDropdownOption('group: GitLab Org').exists()).toBe(true);
expect(findDropdownOption('group: Foobar').exists()).toBe(false);
findDropdownOption('user: Administrator').trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findNamespaceInput().attributes('value')).toBe('10');
expect(findDropdownToggle().text()).toBe('user: Administrator');
@@ -72,7 +73,7 @@ describe('Dropdown select component', () => {
mountDropdown();
// wait for dropdown options to populate
- await wrapper.vm.$nextTick();
+ await nextTick();
findDropdownOption('group: GitLab Org').trigger('click');
diff --git a/spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js b/spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js
index b722ac1e97b..c30b996437d 100644
--- a/spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js
+++ b/spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js
@@ -1,4 +1,5 @@
import { GlModal } from '@gitlab/ui';
+import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
I18N_PASSWORD_PROMPT_CANCEL_BUTTON,
@@ -62,7 +63,7 @@ describe('Password prompt modal', () => {
setPassword(mockPassword);
submitModal();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(handleConfirmPasswordSpy).toHaveBeenCalledTimes(1);
expect(handleConfirmPasswordSpy).toHaveBeenCalledWith(mockPassword);
@@ -73,7 +74,7 @@ describe('Password prompt modal', () => {
expect(findConfirmBtnDisabledState()).toBe(true);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findConfirmBtnDisabledState()).toBe(false);
});
@@ -84,7 +85,7 @@ describe('Password prompt modal', () => {
expect(findConfirmBtnDisabledState()).toBe(true);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findConfirmBtnDisabledState()).toBe(true);
});
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
index dd617b1ffc2..dc5f1cb9e61 100644
--- a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
+++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
@@ -4,6 +4,7 @@ import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios';
import AxiosMockAdapter from 'axios-mock-adapter';
import { kebabCase } from 'lodash';
+import { nextTick } from 'vue';
import createFlash from '~/flash';
import httpStatus from '~/lib/utils/http_status';
import * as urlUtility from '~/lib/utils/url_utility';
@@ -217,7 +218,7 @@ describe('ForkForm component', () => {
it('changes to kebab case when project name changes', async () => {
const newInput = `${projectPath}1`;
findForkNameInput().vm.$emit('input', newInput);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForkSlugInput().attributes('value')).toBe(kebabCase(newInput));
});
@@ -225,7 +226,7 @@ describe('ForkForm component', () => {
it('does not change to kebab case when project slug is changed manually', async () => {
const newInput = `${projectPath}1`;
findForkSlugInput().vm.$emit('input', newInput);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findForkSlugInput().attributes('value')).toBe(newInput);
});
@@ -273,7 +274,7 @@ describe('ForkForm component', () => {
expect(wrapper.vm.form.fields.visibility.value).toBe('public');
await findFormSelectOptions().at(1).setSelected();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getByRole(wrapper.element, 'radio', { name: /private/i }).checked).toBe(true);
});
@@ -283,7 +284,7 @@ describe('ForkForm component', () => {
await findFormSelectOptions().at(1).setSelected();
- await wrapper.vm.$nextTick();
+ await nextTick();
const container = getByRole(wrapper.element, 'radiogroup', { name: /visibility/i });
const visibilityRadios = getAllByRole(container, 'radio');
@@ -419,7 +420,7 @@ describe('ForkForm component', () => {
const form = wrapper.find(GlForm);
await form.trigger('submit');
- await wrapper.vm.$nextTick();
+ await nextTick();
};
describe('with invalid form', () => {
diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
index 1f9029b40c7..0f763e3220a 100644
--- a/spec/frontend/pages/projects/graphs/code_coverage_spec.js
+++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
@@ -3,6 +3,7 @@ import { GlAreaChart } from '@gitlab/ui/dist/charts';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import httpStatusCodes from '~/lib/utils/http_status';
@@ -143,7 +144,7 @@ describe('Code Coverage', () => {
it('updates the selected dropdown option with an icon', async () => {
findSecondDropdownItem().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findFirstDropdownItem().attributes('ischecked')).toBeFalsy();
expect(findSecondDropdownItem().attributes('ischecked')).toBeTruthy();
@@ -155,7 +156,7 @@ describe('Code Coverage', () => {
findSecondDropdownItem().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.selectedDailyCoverage).not.toBe(originalSelectedData);
expect(wrapper.vm.selectedDailyCoverage).toBe(expectedData);
diff --git a/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js b/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
index f3d76ca2c1b..ae5404f2d13 100644
--- a/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
+++ b/spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
@@ -1,5 +1,6 @@
import { GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper';
import IntervalPatternInput from '~/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue';
@@ -98,7 +99,7 @@ describe('Interval Pattern Input Component', () => {
it('when a default option is selected', async () => {
selectEveryDayRadio();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCustomInput().attributes('disabled')).toBeUndefined();
});
@@ -106,7 +107,7 @@ describe('Interval Pattern Input Component', () => {
it('when the custom option is selected', async () => {
selectCustomRadio();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCustomInput().attributes('disabled')).toBeUndefined();
});
@@ -150,11 +151,11 @@ describe('Interval Pattern Input Component', () => {
it('when everyday is selected, update value', async () => {
selectEveryWeekRadio();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCustomInput().element.value).toBe(cronIntervalPresets.everyWeek);
selectEveryDayRadio();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCustomInput().element.value).toBe(cronIntervalPresets.everyDay);
});
});
@@ -170,7 +171,7 @@ describe('Interval Pattern Input Component', () => {
act();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCustomInput().element.value).toBe(expectedValue);
});
@@ -189,7 +190,7 @@ describe('Interval Pattern Input Component', () => {
findCustomInput().setValue(newValue);
- await wrapper.vm.$nextTick;
+ await nextTick;
expect(findSelectedRadioKey()).toBe(customKey);
});
diff --git a/spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js b/spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
index 5fed9fcaad2..2f61b5e9800 100644
--- a/spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
+++ b/spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
+import { nextTick } from 'vue';
import PipelineSchedulesCallout from '~/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue';
const cookieKey = 'pipeline_schedules_callout_dismissed';
@@ -27,7 +28,7 @@ describe('Pipeline Schedule Callout', () => {
Cookies.set(cookieKey, true);
createComponent();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
@@ -71,7 +72,7 @@ describe('Pipeline Schedule Callout', () => {
findDismissCalloutBtn().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findInnerContentOfCallout().exists()).toBe(false);
});
@@ -90,7 +91,7 @@ describe('Pipeline Schedule Callout', () => {
it('is hidden when close button is clicked', async () => {
findDismissCalloutBtn().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findInnerContentOfCallout().exists()).toBe(false);
});
diff --git a/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js b/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js
index 7cbcbdcdd1f..6230809a6aa 100644
--- a/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js
+++ b/spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import projectSettingRow from '~/pages/projects/shared/permissions/components/project_setting_row.vue';
describe('Project Setting Row', () => {
@@ -18,43 +19,39 @@ describe('Project Setting Row', () => {
wrapper.destroy();
});
- it('should show the label if it is set', () => {
+ it('should show the label if it is set', async () => {
wrapper.setProps({ label: 'Test label' });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('label').text()).toEqual('Test label');
- });
+ await nextTick();
+ expect(wrapper.find('label').text()).toEqual('Test label');
});
it('should hide the label if it is not set', () => {
expect(wrapper.find('label').exists()).toBe(false);
});
- it('should show the help icon with the correct help path if it is set', () => {
+ it('should show the help icon with the correct help path if it is set', async () => {
wrapper.setProps({ label: 'Test label', helpPath: '/123' });
- return wrapper.vm.$nextTick(() => {
- const link = wrapper.find('a');
+ await nextTick();
+ const link = wrapper.find('a');
- expect(link.exists()).toBe(true);
- expect(link.attributes().href).toEqual('/123');
- });
+ expect(link.exists()).toBe(true);
+ expect(link.attributes().href).toEqual('/123');
});
- it('should hide the help icon if no help path is set', () => {
+ it('should hide the help icon if no help path is set', async () => {
wrapper.setProps({ label: 'Test label' });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('a').exists()).toBe(false);
- });
+ await nextTick();
+ expect(wrapper.find('a').exists()).toBe(false);
});
- it('should show the help text if it is set', () => {
+ it('should show the help text if it is set', async () => {
wrapper.setProps({ helpText: 'Test text' });
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('span').text()).toEqual('Test text');
- });
+ await nextTick();
+ expect(wrapper.find('span').text()).toEqual('Test text');
});
it('should hide the help text if it is set', () => {
diff --git a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
index fd581eebd1e..1f964e8bae2 100644
--- a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
+++ b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
@@ -48,10 +48,10 @@ describe('WikiForm', () => {
return format.find(`option[value=${value}]`).setSelected();
};
- const triggerFormSubmit = () => {
+ const triggerFormSubmit = async () => {
findForm().element.dispatchEvent(new Event('submit'));
- return nextTick();
+ await nextTick();
};
const dispatchBeforeUnload = () => {
@@ -574,7 +574,7 @@ describe('WikiForm', () => {
wrapper.findComponent(GlModal).vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('switches to classic editor', () => {
diff --git a/spec/frontend/performance_bar/components/add_request_spec.js b/spec/frontend/performance_bar/components/add_request_spec.js
index c5247a43f27..5422481439e 100644
--- a/spec/frontend/performance_bar/components/add_request_spec.js
+++ b/spec/frontend/performance_bar/components/add_request_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import AddRequest from '~/performance_bar/components/add_request.vue';
describe('add request form', () => {
@@ -17,9 +18,9 @@ describe('add request form', () => {
});
describe('when clicking the button', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.find('button').trigger('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows the form', () => {
@@ -27,9 +28,9 @@ describe('add request form', () => {
});
describe('when pressing escape', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.find('input').trigger('keyup.esc');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('hides the input', () => {
@@ -38,12 +39,11 @@ describe('add request form', () => {
});
describe('when submitting the form', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper.find('input').setValue('http://gitlab.example.com/users/root/calendar.json');
- return wrapper.vm.$nextTick().then(() => {
- wrapper.find('input').trigger('keyup.enter');
- return wrapper.vm.$nextTick();
- });
+ await nextTick();
+ wrapper.find('input').trigger('keyup.enter');
+ await nextTick();
});
it('emits an event to add the request', () => {
@@ -57,11 +57,10 @@ describe('add request form', () => {
expect(wrapper.find('input').exists()).toBe(false);
});
- it('clears the value for next time', () => {
+ it('clears the value for next time', async () => {
wrapper.find('button').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('input').text()).toEqual('');
- });
+ await nextTick();
+ expect(wrapper.find('input').text()).toEqual('');
});
});
});
diff --git a/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js b/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js
index d813d67b94b..35315db39f8 100644
--- a/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js
+++ b/spec/frontend/pipeline_editor/components/header/pipeline_status_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -8,8 +9,7 @@ import getPipelineQuery from '~/pipeline_editor/graphql/queries/pipeline.query.g
import PipelineEditorMiniGraph from '~/pipeline_editor/components/header/pipeline_editor_mini_graph.vue';
import { mockCommitSha, mockProjectPipeline, mockProjectFullPath } from '../../mock_data';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Pipeline Status', () => {
let wrapper;
@@ -21,7 +21,6 @@ describe('Pipeline Status', () => {
mockApollo = createMockApollo(handlers);
wrapper = shallowMount(PipelineStatus, {
- localVue,
apolloProvider: mockApollo,
propsData: {
commitSha: mockCommitSha,
diff --git a/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js b/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
index 2f26b4d145c..aae8656b4ad 100644
--- a/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
+++ b/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
@@ -1,4 +1,5 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -8,8 +9,7 @@ import getLinkedPipelinesQuery from '~/projects/commit_box/info/graphql/queries/
import { PIPELINE_FAILURE } from '~/pipeline_editor/constants';
import { mockLinkedPipelines, mockProjectFullPath, mockProjectPipeline } from '../../mock_data';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Pipeline Status', () => {
let wrapper;
@@ -36,7 +36,6 @@ describe('Pipeline Status', () => {
createComponent({
hasStages,
options: {
- localVue,
apolloProvider: mockApollo,
},
});
diff --git a/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js b/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js
index 570323826d1..1ad621e6f45 100644
--- a/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js
+++ b/spec/frontend/pipeline_editor/components/header/validation_segment_spec.js
@@ -1,6 +1,7 @@
import VueApollo from 'vue-apollo';
import { GlIcon } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import { escape } from 'lodash';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -24,8 +25,7 @@ import {
mockYmlHelpPagePath,
} from '../../mock_data';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Validation segment component', () => {
let wrapper;
@@ -45,7 +45,6 @@ describe('Validation segment component', () => {
wrapper = extendedWrapper(
shallowMount(ValidationSegment, {
- localVue,
apolloProvider: mockApollo,
provide: {
ymlHelpPagePath: mockYmlHelpPagePath,
diff --git a/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js b/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js
index 9e2bf1bd367..eec55091efa 100644
--- a/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js
+++ b/spec/frontend/pipeline_new/components/pipeline_new_form_spec.js
@@ -1,6 +1,7 @@
import { GlForm, GlSprintf, GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import CreditCardValidationRequiredAlert from 'ee_component/billings/components/cc_validation_required_alert.vue';
import { TEST_HOST } from 'helpers/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
@@ -122,7 +123,7 @@ describe('Pipeline New Form', () => {
it('removes ci variable row on remove icon button click', async () => {
findRemoveIcons().at(1).trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findVariableRows()).toHaveLength(2);
});
@@ -132,7 +133,7 @@ describe('Pipeline New Form', () => {
input.element.value = 'test_var_2';
input.trigger('change');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findVariableRows()).toHaveLength(4);
expect(findKeyInputs().at(3).element.value).toBe('');
@@ -205,7 +206,7 @@ describe('Pipeline New Form', () => {
mainInput.element.value = 'build_var';
mainInput.trigger('change');
- await wrapper.vm.$nextTick();
+ await nextTick();
selectBranch('branch-1');
@@ -215,7 +216,7 @@ describe('Pipeline New Form', () => {
branchOneInput.element.value = 'deploy_var';
branchOneInput.trigger('change');
- await wrapper.vm.$nextTick();
+ await nextTick();
selectBranch('main');
@@ -309,7 +310,7 @@ describe('Pipeline New Form', () => {
findKeyInputs().at(0).element.value = 'yml_var_modified';
findKeyInputs().at(0).trigger('change');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findVariableRows().at(0).text()).not.toContain(mockYmlDesc);
});
@@ -418,7 +419,7 @@ describe('Pipeline New Form', () => {
findCCAlert().vm.$emit('dismiss');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCCAlert().exists()).toBe(false);
expect(wrapper.vm.$data.error).toBe(null);
diff --git a/spec/frontend/pipelines/components/dag/dag_annotations_spec.js b/spec/frontend/pipelines/components/dag/dag_annotations_spec.js
index 1941a7f2777..212f8e19a6d 100644
--- a/spec/frontend/pipelines/components/dag/dag_annotations_spec.js
+++ b/spec/frontend/pipelines/components/dag/dag_annotations_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import DagAnnotations from '~/pipelines/components/dag/dag_annotations.vue';
import { singleNote, multiNote } from './mock_data';
@@ -82,26 +83,24 @@ describe('The DAG annotations', () => {
});
describe('clicking hide', () => {
- it('hides listed items and changes text to show', () => {
+ it('hides listed items and changes text to show', async () => {
expect(getAllTextBlocks().length).toBe(Object.keys(multiNote).length);
expect(getToggleButton().text()).toBe('Hide list');
getToggleButton().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(getAllTextBlocks().length).toBe(0);
- expect(getToggleButton().text()).toBe('Show list');
- });
+ await nextTick();
+ expect(getAllTextBlocks().length).toBe(0);
+ expect(getToggleButton().text()).toBe('Show list');
});
});
describe('clicking show', () => {
- it('shows listed items and changes text to hide', () => {
+ it('shows listed items and changes text to hide', async () => {
getToggleButton().trigger('click');
getToggleButton().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(getAllTextBlocks().length).toBe(Object.keys(multiNote).length);
- expect(getToggleButton().text()).toBe('Hide list');
- });
+ await nextTick();
+ expect(getAllTextBlocks().length).toBe(Object.keys(multiNote).length);
+ expect(getToggleButton().text()).toBe('Hide list');
});
});
});
diff --git a/spec/frontend/pipelines/components/dag/dag_spec.js b/spec/frontend/pipelines/components/dag/dag_spec.js
index 14030930657..d78df3eb35e 100644
--- a/spec/frontend/pipelines/components/dag/dag_spec.js
+++ b/spec/frontend/pipelines/components/dag/dag_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlEmptyState } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { ADD_NOTE, REMOVE_NOTE, REPLACE_NOTES } from '~/pipelines/components/dag/constants';
import Dag from '~/pipelines/components/dag/dag.vue';
import DagAnnotations from '~/pipelines/components/dag/dag_annotations.vue';
@@ -153,11 +154,11 @@ describe('Pipeline DAG graph wrapper', () => {
expect(getNotes().exists()).toBe(false);
getGraph().vm.$emit('update-annotation', { type: ADD_NOTE, data: currentNote });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getNotes().exists()).toBe(true);
getGraph().vm.$emit('update-annotation', { type: REMOVE_NOTE, data: currentNote });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getNotes().exists()).toBe(false);
});
@@ -165,11 +166,11 @@ describe('Pipeline DAG graph wrapper', () => {
expect(getNotes().exists()).toBe(false);
getGraph().vm.$emit('update-annotation', { type: REPLACE_NOTES, data: multiNote });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getNotes().exists()).toBe(true);
getGraph().vm.$emit('update-annotation', { type: REPLACE_NOTES, data: {} });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getNotes().exists()).toBe(false);
});
});
diff --git a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
index 547c0cdda5e..65814ad9a7f 100644
--- a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
+++ b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
@@ -1,5 +1,6 @@
import { GlIntersectionObserver, GlSkeletonLoader } from '@gitlab/ui';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -9,8 +10,7 @@ import JobsTable from '~/jobs/components/table/jobs_table.vue';
import getPipelineJobsQuery from '~/pipelines/graphql/queries/get_pipeline_jobs.query.graphql';
import { mockPipelineJobsQueryResponse } from '../../mock_data';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
jest.mock('~/flash');
@@ -36,7 +36,6 @@ describe('Jobs app', () => {
fullPath: 'root/ci-project',
pipelineIid: 1,
},
- localVue,
apolloProvider: createMockApolloProvider(resolver),
});
};
diff --git a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
index 661c8d99477..97b59a09518 100644
--- a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
@@ -1,6 +1,7 @@
import { GlFilteredSearch } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import Api from '~/api';
import axios from '~/lib/utils/axios_utils';
import PipelinesFilteredSearch from '~/pipelines/components/pipelines_list/pipelines_filtered_search.vue';
@@ -103,46 +104,42 @@ describe('Pipelines filtered search', () => {
expect(wrapper.emitted('filterPipelines')[0]).toEqual([mockSearch]);
});
- it('disables tag name token when branch name token is active', () => {
+ it('disables tag name token when branch name token is active', async () => {
findFilteredSearch().vm.$emit('input', [
{ type: 'ref', value: { data: 'branch-1', operator: '=' } },
{ type: 'filtered-search-term', value: { data: '' } },
]);
- return wrapper.vm.$nextTick().then(() => {
- expect(findBranchToken().disabled).toBe(false);
- expect(findTagToken().disabled).toBe(true);
- });
+ await nextTick();
+ expect(findBranchToken().disabled).toBe(false);
+ expect(findTagToken().disabled).toBe(true);
});
- it('disables branch name token when tag name token is active', () => {
+ it('disables branch name token when tag name token is active', async () => {
findFilteredSearch().vm.$emit('input', [
{ type: 'tag', value: { data: 'tag-1', operator: '=' } },
{ type: 'filtered-search-term', value: { data: '' } },
]);
- return wrapper.vm.$nextTick().then(() => {
- expect(findBranchToken().disabled).toBe(true);
- expect(findTagToken().disabled).toBe(false);
- });
+ await nextTick();
+ expect(findBranchToken().disabled).toBe(true);
+ expect(findTagToken().disabled).toBe(false);
});
- it('resets tokens disabled state on clear', () => {
+ it('resets tokens disabled state on clear', async () => {
findFilteredSearch().vm.$emit('clearInput');
- return wrapper.vm.$nextTick().then(() => {
- expect(findBranchToken().disabled).toBe(false);
- expect(findTagToken().disabled).toBe(false);
- });
+ await nextTick();
+ expect(findBranchToken().disabled).toBe(false);
+ expect(findTagToken().disabled).toBe(false);
});
- it('resets tokens disabled state when clearing tokens by backspace', () => {
+ it('resets tokens disabled state when clearing tokens by backspace', async () => {
findFilteredSearch().vm.$emit('input', [{ type: 'filtered-search-term', value: { data: '' } }]);
- return wrapper.vm.$nextTick().then(() => {
- expect(findBranchToken().disabled).toBe(false);
- expect(findTagToken().disabled).toBe(false);
- });
+ await nextTick();
+ expect(findBranchToken().disabled).toBe(false);
+ expect(findTagToken().disabled).toBe(false);
});
describe('Url query params', () => {
diff --git a/spec/frontend/pipelines/graph/action_component_spec.js b/spec/frontend/pipelines/graph/action_component_spec.js
index 177b026491c..f3aae21163b 100644
--- a/spec/frontend/pipelines/graph/action_component_spec.js
+++ b/spec/frontend/pipelines/graph/action_component_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import ActionComponent from '~/pipelines/components/jobs_shared/action_component.vue';
@@ -33,16 +34,11 @@ describe('pipeline graph action component', () => {
expect(wrapper.attributes('title')).toBe('bar');
});
- it('should update bootstrap tooltip when title changes', (done) => {
+ it('should update bootstrap tooltip when title changes', async () => {
wrapper.setProps({ tooltipText: 'changed' });
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.attributes('title')).toBe('changed');
- })
- .then(done)
- .catch(done.fail);
+ await nextTick();
+ expect(wrapper.attributes('title')).toBe('changed');
});
it('should render an svg', () => {
@@ -64,13 +60,11 @@ describe('pipeline graph action component', () => {
.catch(done.fail);
});
- it('renders a loading icon while waiting for request', (done) => {
+ it('renders a loading icon while waiting for request', async () => {
findButton().trigger('click');
- wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.js-action-icon-loading').exists()).toBe(true);
- done();
- });
+ await nextTick();
+ expect(wrapper.find('.js-action-icon-loading').exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/pipelines/graph/job_item_spec.js b/spec/frontend/pipelines/graph/job_item_spec.js
index 06f1fa4c827..a6b3a96144a 100644
--- a/spec/frontend/pipelines/graph/job_item_spec.js
+++ b/spec/frontend/pipelines/graph/job_item_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import JobItem from '~/pipelines/components/graph/job_item.vue';
describe('pipeline graph job item', () => {
@@ -74,22 +75,19 @@ describe('pipeline graph job item', () => {
});
describe('name with link', () => {
- it('should render the job name and status with a link', (done) => {
+ it('should render the job name and status with a link', async () => {
createWrapper({ job: mockJob });
- wrapper.vm.$nextTick(() => {
- const link = wrapper.find('a');
+ await nextTick();
+ const link = wrapper.find('a');
- expect(link.attributes('href')).toBe(mockJob.status.detailsPath);
+ expect(link.attributes('href')).toBe(mockJob.status.detailsPath);
- expect(link.attributes('title')).toBe(`${mockJob.name} - ${mockJob.status.label}`);
+ expect(link.attributes('title')).toBe(`${mockJob.name} - ${mockJob.status.label}`);
- expect(wrapper.find('.ci-status-icon-success').exists()).toBe(true);
-
- expect(wrapper.text()).toBe(mockJob.name);
+ expect(wrapper.find('.ci-status-icon-success').exists()).toBe(true);
- done();
- });
+ expect(wrapper.text()).toBe(mockJob.name);
});
});
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
index 5897da4b8c2..ca283f3b4ce 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
+++ b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
@@ -1,4 +1,5 @@
-import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -41,13 +42,11 @@ describe('Linked Pipelines Column', () => {
const findPipelineGraph = () => wrapper.find(PipelineGraph);
const findExpandButton = () => wrapper.find('[data-testid="expand-pipeline-button"]');
- const localVue = createLocalVue();
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const createComponent = ({ apolloProvider, mountFn = shallowMount, props = {} } = {}) => {
wrapper = mountFn(LinkedPipelinesColumn, {
apolloProvider,
- localVue,
propsData: {
...defaultProps,
...props,
@@ -108,7 +107,7 @@ describe('Linked Pipelines Column', () => {
expect(layersFn).not.toHaveBeenCalled();
await clickExpandButtonAndAwaitTimers();
await wrapper.setProps({ viewType: LAYER_VIEW });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(layersFn).toHaveBeenCalledTimes(1);
await wrapper.setProps({ viewType: STAGE_VIEW });
await wrapper.setProps({ viewType: LAYER_VIEW });
diff --git a/spec/frontend/pipelines/pipeline_triggerer_spec.js b/spec/frontend/pipelines/pipeline_triggerer_spec.js
index ffb2721f159..701b1691c7b 100644
--- a/spec/frontend/pipelines/pipeline_triggerer_spec.js
+++ b/spec/frontend/pipelines/pipeline_triggerer_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import pipelineTriggerer from '~/pipelines/components/pipelines_list/pipeline_triggerer.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
@@ -47,15 +48,14 @@ describe('Pipelines Triggerer', () => {
});
});
- it('should render "API" when no triggerer is provided', () => {
+ it('should render "API" when no triggerer is provided', async () => {
wrapper.setProps({
pipeline: {
user: null,
},
});
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find('.js-pipeline-url-api').text()).toEqual('API');
- });
+ await nextTick();
+ expect(wrapper.find('.js-pipeline-url-api').text()).toEqual('API');
});
});
diff --git a/spec/frontend/pipelines/pipelines_actions_spec.js b/spec/frontend/pipelines/pipelines_actions_spec.js
index c4bfec8ae14..a8af30a5710 100644
--- a/spec/frontend/pipelines/pipelines_actions_spec.js
+++ b/spec/frontend/pipelines/pipelines_actions_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import { TEST_HOST } from 'spec/test_constants';
import createFlash from '~/flash';
@@ -68,7 +69,7 @@ describe('Pipelines Actions dropdown', () => {
findAllDropdownItems().at(0).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDropdown().props('loading')).toBe(true);
await waitForPromises();
@@ -80,7 +81,7 @@ describe('Pipelines Actions dropdown', () => {
findAllDropdownItems().at(0).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDropdown().props('loading')).toBe(true);
await waitForPromises();
diff --git a/spec/frontend/popovers/components/popovers_spec.js b/spec/frontend/popovers/components/popovers_spec.js
index 2751a878e51..6fdcd34ae83 100644
--- a/spec/frontend/popovers/components/popovers_spec.js
+++ b/spec/frontend/popovers/components/popovers_spec.js
@@ -1,5 +1,6 @@
import { GlPopover } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { useMockMutationObserver } from 'helpers/mock_dom_observer';
import Popovers from '~/popovers/components/popovers.vue';
@@ -7,10 +8,10 @@ describe('popovers/components/popovers.vue', () => {
const { trigger: triggerMutate } = useMockMutationObserver();
let wrapper;
- const buildWrapper = (...targets) => {
+ const buildWrapper = async (...targets) => {
wrapper = shallowMount(Popovers);
wrapper.vm.addPopovers(targets);
- return wrapper.vm.$nextTick();
+ await nextTick();
};
const createPopoverTarget = (options = {}) => {
@@ -49,7 +50,7 @@ describe('popovers/components/popovers.vue', () => {
buildWrapper(target);
wrapper.vm.addPopovers([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.findAll(GlPopover)).toHaveLength(1);
});
@@ -86,7 +87,7 @@ describe('popovers/components/popovers.vue', () => {
await buildWrapper(createPopoverTarget(), createPopoverTarget());
wrapper.vm.dispose();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(allPopovers()).toHaveLength(0);
});
@@ -97,7 +98,7 @@ describe('popovers/components/popovers.vue', () => {
await buildWrapper(target, createPopoverTarget());
wrapper.vm.dispose(target);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(allPopovers()).toHaveLength(1);
});
@@ -109,13 +110,13 @@ describe('popovers/components/popovers.vue', () => {
await buildWrapper(target);
wrapper.vm.addPopovers([target, createPopoverTarget()]);
- await wrapper.vm.$nextTick();
+ await nextTick();
triggerMutate(document.body, {
entry: { removedNodes: [target] },
options: { childList: true },
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(allPopovers()).toHaveLength(1);
});
diff --git a/spec/frontend/profile/account/components/update_username_spec.js b/spec/frontend/profile/account/components/update_username_spec.js
index bda07af4feb..e342b7c4ba1 100644
--- a/spec/frontend/profile/account/components/update_username_spec.js
+++ b/spec/frontend/profile/account/components/update_username_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
@@ -58,7 +59,7 @@ describe('UpdateUsername component', () => {
it('has a disabled button if the username was not changed', async () => {
const { openModalBtn } = findElements();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(openModalBtn.props('disabled')).toBe(true);
});
@@ -69,7 +70,7 @@ describe('UpdateUsername component', () => {
input.element.value = 'newUsername';
input.trigger('input');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(openModalBtn.props('disabled')).toBe(false);
});
@@ -83,7 +84,7 @@ describe('UpdateUsername component', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ newUsername });
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('confirmation modal contains proper header and body', async () => {
@@ -100,7 +101,7 @@ describe('UpdateUsername component', () => {
jest.spyOn(axios, 'put');
await wrapper.vm.onConfirm();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } });
});
@@ -117,7 +118,7 @@ describe('UpdateUsername component', () => {
});
await wrapper.vm.onConfirm();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(input.attributes('disabled')).toBe(undefined);
expect(openModalBtn.props('disabled')).toBe(true);
diff --git a/spec/frontend/projects/commit/components/branches_dropdown_spec.js b/spec/frontend/projects/commit/components/branches_dropdown_spec.js
index 30556cdeae1..e2848e615c3 100644
--- a/spec/frontend/projects/commit/components/branches_dropdown_spec.js
+++ b/spec/frontend/projects/commit/components/branches_dropdown_spec.js
@@ -1,6 +1,6 @@
import { GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
@@ -115,7 +115,7 @@ describe('BranchesDropdown', () => {
findSearchBoxByType().vm.$emit('input', '_anything_');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(spy).toHaveBeenCalledWith('_anything_');
expect(wrapper.vm.searchTerm).toBe('_anything_');
diff --git a/spec/frontend/projects/commit/components/form_modal_spec.js b/spec/frontend/projects/commit/components/form_modal_spec.js
index 93e2ae13628..79e9dab935d 100644
--- a/spec/frontend/projects/commit/components/form_modal_spec.js
+++ b/spec/frontend/projects/commit/components/form_modal_spec.js
@@ -2,6 +2,7 @@ import { GlModal, GlForm, GlFormCheckbox, GlSprintf } from '@gitlab/ui';
import { within } from '@testing-library/dom';
import { shallowMount, mount, createWrapper } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import api from '~/api';
import axios from '~/lib/utils/axios_utils';
@@ -156,7 +157,7 @@ describe('CommitFormModal', () => {
it('Changes the start_branch input value', async () => {
findBranchesDropdown().vm.$emit('selectBranch', '_changed_branch_value_');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findStartBranch().attributes('value')).toBe('_changed_branch_value_');
});
@@ -165,7 +166,7 @@ describe('CommitFormModal', () => {
createComponent(shallowMount, {}, {}, { isCherryPick: true });
findProjectsDropdown().vm.$emit('selectProject', '_changed_project_value_');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findTargetProject().attributes('value')).toBe('_changed_project_value_');
});
@@ -174,7 +175,7 @@ describe('CommitFormModal', () => {
it('action primary button triggers Redis HLL tracking api call', async () => {
createComponent(mount, {}, {}, { primaryActionEventName: 'test_event' });
- await wrapper.vm.$nextTick();
+ await nextTick();
jest.spyOn(findForm().element, 'submit');
diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js
index eda61758101..4e567ab030e 100644
--- a/spec/frontend/projects/commits/components/author_select_spec.js
+++ b/spec/frontend/projects/commits/components/author_select_spec.js
@@ -1,6 +1,6 @@
import { GlDropdown, GlDropdownSectionHeader, GlSearchBoxByType, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import * as urlUtility from '~/lib/utils/url_utility';
import AuthorSelect from '~/projects/commits/components/author_select.vue';
@@ -63,36 +63,33 @@ describe('Author Select', () => {
const findDropdownItems = () => wrapper.findAll(GlDropdownItem);
describe('user is searching via "filter by commit message"', () => {
- it('disables dropdown container', () => {
+ it('disables dropdown container', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasSearchParam: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdownContainer().attributes('disabled')).toBeFalsy();
- });
+ await nextTick();
+ expect(findDropdownContainer().attributes('disabled')).toBeFalsy();
});
- it('has correct tooltip message', () => {
+ it('has correct tooltip message', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasSearchParam: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdownContainer().attributes('title')).toBe(
- 'Searching by both author and message is currently not supported.',
- );
- });
+ await nextTick();
+ expect(findDropdownContainer().attributes('title')).toBe(
+ 'Searching by both author and message is currently not supported.',
+ );
});
- it('disables dropdown', () => {
+ it('disables dropdown', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ hasSearchParam: false });
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdown().attributes('disabled')).toBeFalsy();
- });
+ await nextTick();
+ expect(findDropdown().attributes('disabled')).toBeFalsy();
});
it('hasSearchParam if user types a truthy string', () => {
@@ -107,14 +104,13 @@ describe('Author Select', () => {
expect(findDropdown().attributes('text')).toBe('Author');
});
- it('displays the current selected author', () => {
+ it('displays the current selected author', async () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentAuthor });
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdown().attributes('text')).toBe(currentAuthor);
- });
+ await nextTick();
+ expect(findDropdown().attributes('text')).toBe(currentAuthor);
});
it('displays correct header text', () => {
@@ -149,13 +145,12 @@ describe('Author Select', () => {
expect(findDropdownItems().at(0).text()).toBe('Any Author');
});
- it('displays the project authors', () => {
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdownItems()).toHaveLength(authors.length + 1);
- });
+ it('displays the project authors', async () => {
+ await nextTick();
+ expect(findDropdownItems()).toHaveLength(authors.length + 1);
});
- it('has the correct props', () => {
+ it('has the correct props', async () => {
const [{ avatar_url, username }] = authors;
const result = {
avatarUrl: avatar_url,
@@ -167,15 +162,13 @@ describe('Author Select', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ currentAuthor });
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdownItems().at(1).props()).toEqual(expect.objectContaining(result));
- });
+ await nextTick();
+ expect(findDropdownItems().at(1).props()).toEqual(expect.objectContaining(result));
});
- it("display the author's name", () => {
- return wrapper.vm.$nextTick().then(() => {
- expect(findDropdownItems().at(1).text()).toBe(currentAuthor);
- });
+ it("display the author's name", async () => {
+ await nextTick();
+ expect(findDropdownItems().at(1).text()).toBe(currentAuthor);
});
it('passes selected author to redirectPath', () => {
diff --git a/spec/frontend/projects/compare/components/app_spec.js b/spec/frontend/projects/compare/components/app_spec.js
index 7989a6f3d74..18e7f2e0f6e 100644
--- a/spec/frontend/projects/compare/components/app_spec.js
+++ b/spec/frontend/projects/compare/components/app_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import CompareApp from '~/projects/compare/components/app.vue';
import RevisionCard from '~/projects/compare/components/revision_card.vue';
import { appDefaultProps as defaultProps } from './mock_data';
@@ -91,7 +92,7 @@ describe('CompareApp component', () => {
project,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findTargetRevisionCard().props('selectedProject')).toEqual(
expect.objectContaining(project),
@@ -106,7 +107,7 @@ describe('CompareApp component', () => {
revision,
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findSourceRevisionCard().props('paramsBranch')).toBe(revision);
});
@@ -125,7 +126,7 @@ describe('CompareApp component', () => {
it('swaps revisions when clicked', async () => {
findSwapRevisionsButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findTargetRevisionCard().props('paramsBranch')).toBe(defaultProps.paramsTo);
expect(findSourceRevisionCard().props('paramsBranch')).toBe(defaultProps.paramsFrom);
diff --git a/spec/frontend/projects/compare/components/repo_dropdown_spec.js b/spec/frontend/projects/compare/components/repo_dropdown_spec.js
index 27a7a32ebca..98aec347e4b 100644
--- a/spec/frontend/projects/compare/components/repo_dropdown_spec.js
+++ b/spec/frontend/projects/compare/components/repo_dropdown_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import RepoDropdown from '~/projects/compare/components/repo_dropdown.vue';
import { revisionCardDefaultProps as defaultProps } from './mock_data';
@@ -39,7 +40,7 @@ describe('RepoDropdown component', () => {
it('does not emit `changeTargetProject` event', async () => {
wrapper.vm.emitTargetProject('foo');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('changeTargetProject')).toBeUndefined();
});
});
@@ -67,13 +68,13 @@ describe('RepoDropdown component', () => {
it('updates the hidden input value when onClick method is triggered', async () => {
const repoId = '1';
wrapper.vm.onClick({ id: repoId });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findHiddenInput().attributes('value')).toBe(repoId);
});
it('emits `selectProject` event when another target project is selected', async () => {
findGlDropdown().findAll(GlDropdownItem).at(0).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('selectProject')[0][0]).toEqual({
direction: 'from',
diff --git a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
index eb80d57fb3c..102f95f65da 100644
--- a/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
+++ b/spec/frontend/projects/compare/components/revision_dropdown_legacy_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import RevisionDropdown from '~/projects/compare/components/revision_dropdown_legacy.vue';
@@ -105,7 +106,7 @@ describe('RevisionDropdown component', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ branches: ['some-branch'] });
- await wrapper.vm.$nextTick();
+ await nextTick();
findFirstGlDropdownItem().vm.$emit('click');
diff --git a/spec/frontend/projects/compare/components/revision_dropdown_spec.js b/spec/frontend/projects/compare/components/revision_dropdown_spec.js
index 118bb68585e..c8a90848492 100644
--- a/spec/frontend/projects/compare/components/revision_dropdown_spec.js
+++ b/spec/frontend/projects/compare/components/revision_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import RevisionDropdown from '~/projects/compare/components/revision_dropdown.vue';
@@ -141,7 +142,7 @@ describe('RevisionDropdown component', () => {
it('emits `selectRevision` event when another revision is selected', async () => {
createComponent();
wrapper.vm.branches = ['some-branch'];
- await wrapper.vm.$nextTick();
+ await nextTick();
findGlDropdown().findAll(GlDropdownItem).at(0).vm.$emit('click');
diff --git a/spec/frontend/projects/new/components/new_project_url_select_spec.js b/spec/frontend/projects/new/components/new_project_url_select_spec.js
index be6592530fc..921f5b74278 100644
--- a/spec/frontend/projects/new/components/new_project_url_select_spec.js
+++ b/spec/frontend/projects/new/components/new_project_url_select_spec.js
@@ -6,7 +6,7 @@ import {
GlSearchBoxByType,
} from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -95,7 +95,7 @@ describe('NewProjectUrlSelect component', () => {
const clickDropdownItem = async () => {
wrapper.findComponent(GlDropdownItem).vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
};
const showDropdown = async () => {
diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js
index 574756322c7..9c94925c817 100644
--- a/spec/frontend/projects/pipelines/charts/components/app_spec.js
+++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js
@@ -1,5 +1,6 @@
import { GlTabs, GlTab } from '@gitlab/ui';
import { merge } from 'lodash';
+import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'helpers/test_constants';
@@ -99,7 +100,7 @@ describe('ProjectsPipelinesChartsApp', () => {
tabs.vm.$emit('input', 1);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(tabs.attributes('value')).toBe('1');
});
@@ -115,7 +116,7 @@ describe('ProjectsPipelinesChartsApp', () => {
tabs.vm.$emit('input', 0);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(updateHistory).not.toHaveBeenCalled();
});
@@ -183,7 +184,7 @@ describe('ProjectsPipelinesChartsApp', () => {
popstateHandler();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findGlTabs().attributes('value')).toBe('1');
});
diff --git a/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js b/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js
index 2ee2ffdb96b..3c91b913e67 100644
--- a/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js
+++ b/spec/frontend/projects/pipelines/charts/components/pipeline_charts_spec.js
@@ -1,5 +1,6 @@
import { GlColumnChart } from '@gitlab/ui/dist/charts';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -11,8 +12,7 @@ import CiCdAnalyticsCharts from '~/vue_shared/components/ci_cd_analytics/ci_cd_a
import { mockPipelineCount, mockPipelineStatistics } from '../mock_data';
const projectPath = 'gitlab-org/gitlab';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('~/projects/pipelines/charts/components/pipeline_charts.vue', () => {
let wrapper;
@@ -31,7 +31,6 @@ describe('~/projects/pipelines/charts/components/pipeline_charts.vue', () => {
provide: {
projectPath,
},
- localVue,
apolloProvider: createMockApolloProvider(),
});
diff --git a/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js b/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js
index 0c5bbe2a115..0a05832ceb6 100644
--- a/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js
+++ b/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js
@@ -1,6 +1,7 @@
import { GlAlert, GlToggle, GlTooltip } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAxiosAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import SharedRunnersToggleComponent from '~/projects/settings/components/shared_runners_toggle.vue';
@@ -121,7 +122,7 @@ describe('projects/settings/components/shared_runners', () => {
expect(isToggleLoading()).toBe(false);
findSharedRunnersToggle().vm.$emit('change', true);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(isToggleLoading()).toBe(true);
await waitForPromises();
diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
index 875c58583df..57e515723e5 100644
--- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
+++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
@@ -139,7 +139,7 @@ describe('ServiceDeskSetting', () => {
input.setValue('abc_A.');
input.trigger('blur');
- await wrapper.vm.$nextTick();
+ await nextTick();
const errorText = wrapper.find('.invalid-feedback');
expect(errorText.exists()).toBe(true);
diff --git a/spec/frontend/ref/components/ref_selector_spec.js b/spec/frontend/ref/components/ref_selector_spec.js
index b4e50c8f634..e1fc60f0d92 100644
--- a/spec/frontend/ref/components/ref_selector_spec.js
+++ b/spec/frontend/ref/components/ref_selector_spec.js
@@ -137,19 +137,19 @@ describe('Ref selector component', () => {
findSearchBox().vm.$emit('input', newQuery);
};
- const selectFirstBranch = () => {
+ const selectFirstBranch = async () => {
findFirstBranchDropdownItem().vm.$emit('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
};
- const selectFirstTag = () => {
+ const selectFirstTag = async () => {
findFirstTagDropdownItem().vm.$emit('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
};
- const selectFirstCommit = () => {
+ const selectFirstCommit = async () => {
findFirstCommitDropdownItem().vm.$emit('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
};
const waitForRequests = ({ andClearMocks } = { andClearMocks: false }) =>
@@ -219,12 +219,11 @@ describe('Ref selector component', () => {
return waitForRequests();
});
- it('renders the updated ref name', () => {
+ it('renders the updated ref name', async () => {
wrapper.setProps({ value: updatedRef });
- return nextTick().then(() => {
- expect(findButtonContent().text()).toBe(updatedRef);
- });
+ await nextTick();
+ expect(findButtonContent().text()).toBe(updatedRef);
});
});
@@ -546,9 +545,8 @@ describe('Ref selector component', () => {
await selectFirstBranch();
- return nextTick().then(() => {
- expect(findButtonContent().text()).toBe(fixtures.branches[0].name);
- });
+ await nextTick();
+ expect(findButtonContent().text()).toBe(fixtures.branches[0].name);
});
it("updates the v-model binding with the branch's name", async () => {
@@ -566,9 +564,8 @@ describe('Ref selector component', () => {
await selectFirstTag();
- return nextTick().then(() => {
- expect(findButtonContent().text()).toBe(fixtures.tags[0].name);
- });
+ await nextTick();
+ expect(findButtonContent().text()).toBe(fixtures.tags[0].name);
});
it("updates the v-model binding with the tag's name", async () => {
@@ -586,9 +583,8 @@ describe('Ref selector component', () => {
await selectFirstCommit();
- return nextTick().then(() => {
- expect(findButtonContent().text()).toBe(fixtures.commit.id);
- });
+ await nextTick();
+ expect(findButtonContent().text()).toBe(fixtures.commit.id);
});
it("updates the v-model binding with the commit's full SHA", async () => {
diff --git a/spec/frontend/related_issues/components/related_issuable_input_spec.js b/spec/frontend/related_issues/components/related_issuable_input_spec.js
index 79b228454f4..7d11e3cffb0 100644
--- a/spec/frontend/related_issues/components/related_issuable_input_spec.js
+++ b/spec/frontend/related_issues/components/related_issuable_input_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import RelatedIssuableInput from '~/related_issues/components/related_issuable_input.vue';
import { issuableTypesMap, PathIdSeparator } from '~/related_issues/constants';
@@ -82,7 +83,7 @@ describe('RelatedIssuableInput', () => {
wrapper.find('li').trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(document.activeElement).toBe(wrapper.find({ ref: 'input' }).element);
});
diff --git a/spec/frontend/releases/components/app_edit_new_spec.js b/spec/frontend/releases/components/app_edit_new_spec.js
index 029d720f7b9..0a0a683b56d 100644
--- a/spec/frontend/releases/components/app_edit_new_spec.js
+++ b/spec/frontend/releases/components/app_edit_new_spec.js
@@ -3,6 +3,7 @@ import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { merge } from 'lodash';
import Vuex from 'vuex';
+import { nextTick } from 'vue';
import originalRelease from 'test_fixtures/api/releases/release.json';
import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'helpers/test_constants';
@@ -71,7 +72,7 @@ describe('Release edit/new component', () => {
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.element.querySelectorAll('input').forEach((input) => jest.spyOn(input, 'focus'));
};
diff --git a/spec/frontend/releases/components/app_index_apollo_client_spec.js b/spec/frontend/releases/components/app_index_apollo_client_spec.js
index 53ee5b223ad..9881ef9bc9f 100644
--- a/spec/frontend/releases/components/app_index_apollo_client_spec.js
+++ b/spec/frontend/releases/components/app_index_apollo_client_spec.js
@@ -1,5 +1,5 @@
import { cloneDeep } from 'lodash';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import originalAllReleasesQueryResponse from 'test_fixtures/graphql/releases/graphql/queries/all_releases.query.graphql.json';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -296,7 +296,7 @@ describe('app_index_apollo_client.vue', () => {
mockQueryParams = { after };
findPagination().vm.$emit('next', after);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(queryMock.mock.calls).toEqual([
[expect.objectContaining({ before })],
@@ -321,7 +321,7 @@ describe('app_index_apollo_client.vue', () => {
it('requeries the GraphQL endpoint and updates the URL when the sort is changed', async () => {
findSort().vm.$emit('input', CREATED_ASC);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(queryMock.mock.calls).toEqual([
[expect.objectContaining({ sort: DEFAULT_SORT })],
@@ -337,7 +337,7 @@ describe('app_index_apollo_client.vue', () => {
it('does not requery the GraphQL endpoint or update the URL if the sort is updated to the same value', async () => {
findSort().vm.$emit('input', DEFAULT_SORT);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(queryMock.mock.calls).toEqual([
[expect.objectContaining({ sort: DEFAULT_SORT })],
@@ -370,7 +370,7 @@ describe('app_index_apollo_client.vue', () => {
findSort().vm.$emit('input', CREATED_ASC);
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it(`resets the page's "${paramName}" pagination cursor when the sort is changed`, () => {
diff --git a/spec/frontend/releases/components/evidence_block_spec.js b/spec/frontend/releases/components/evidence_block_spec.js
index 973428257b7..f0d02884305 100644
--- a/spec/frontend/releases/components/evidence_block_spec.js
+++ b/spec/frontend/releases/components/evidence_block_spec.js
@@ -1,5 +1,6 @@
import { GlLink, GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import originalRelease from 'test_fixtures/api/releases/release.json';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { truncateSha } from '~/lib/utils/text_utility';
@@ -51,12 +52,11 @@ describe('Evidence Block', () => {
expect(wrapper.find('.js-short').text()).toBe(truncateSha(release.evidences[0].sha));
});
- it('renders the long sha after expansion', () => {
+ it('renders the long sha after expansion', async () => {
wrapper.find('.js-text-expander-prepend').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.find('.js-expanded').text()).toBe(release.evidences[0].sha);
- });
+ await nextTick();
+ expect(wrapper.find('.js-expanded').text()).toBe(release.evidences[0].sha);
});
});
diff --git a/spec/frontend/releases/components/release_block_footer_spec.js b/spec/frontend/releases/components/release_block_footer_spec.js
index f645dc309d7..b095e9e1d78 100644
--- a/spec/frontend/releases/components/release_block_footer_spec.js
+++ b/spec/frontend/releases/components/release_block_footer_spec.js
@@ -1,6 +1,7 @@
import { GlLink, GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
+import { nextTick } from 'vue';
import originalRelease from 'test_fixtures/api/releases/release.json';
import { trimText } from 'helpers/text_helper';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
@@ -14,7 +15,7 @@ describe('Release block footer', () => {
let wrapper;
let release;
- const factory = (props = {}) => {
+ const factory = async (props = {}) => {
wrapper = mount(ReleaseBlockFooter, {
propsData: {
...convertObjectPropsToCamelCase(release, { deep: true }),
@@ -22,7 +23,7 @@ describe('Release block footer', () => {
},
});
- return wrapper.vm.$nextTick();
+ await nextTick();
};
beforeEach(() => {
diff --git a/spec/frontend/releases/components/release_block_milestone_info_spec.js b/spec/frontend/releases/components/release_block_milestone_info_spec.js
index 146b2cc7490..84a0080965b 100644
--- a/spec/frontend/releases/components/release_block_milestone_info_spec.js
+++ b/spec/frontend/releases/components/release_block_milestone_info_spec.js
@@ -1,5 +1,6 @@
import { GlProgressBar, GlLink, GlBadge, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import originalRelease from 'test_fixtures/api/releases/release.json';
import { trimText } from 'helpers/text_helper';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
@@ -12,12 +13,12 @@ describe('Release block milestone info', () => {
let wrapper;
let milestones;
- const factory = (props) => {
+ const factory = async (props) => {
wrapper = mount(ReleaseBlockMilestoneInfo, {
propsData: props,
});
- return wrapper.vm.$nextTick();
+ await nextTick();
};
beforeEach(() => {
@@ -105,10 +106,10 @@ describe('Release block milestone info', () => {
return factory({ milestones: lotsOfMilestones });
});
- const clickShowMoreFewerButton = () => {
+ const clickShowMoreFewerButton = async () => {
milestoneListContainer().find(GlButton).trigger('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
};
const milestoneListText = () => trimText(milestoneListContainer().text());
@@ -117,19 +118,16 @@ describe('Release block milestone info', () => {
expect(milestoneListText()).toContain(`Milestones ${abbreviatedListString} • show 10 more`);
});
- it('renders all milestones when "show more" is clicked', () =>
- clickShowMoreFewerButton().then(() => {
- expect(milestoneListText()).toContain(`Milestones ${fullListString} • show fewer`);
- }));
+ it('renders all milestones when "show more" is clicked', async () => {
+ await clickShowMoreFewerButton();
+ expect(milestoneListText()).toContain(`Milestones ${fullListString} • show fewer`);
+ });
- it('returns to the original view when "show fewer" is clicked', () =>
- clickShowMoreFewerButton()
- .then(clickShowMoreFewerButton)
- .then(() => {
- expect(milestoneListText()).toContain(
- `Milestones ${abbreviatedListString} • show 10 more`,
- );
- }));
+ it('returns to the original view when "show fewer" is clicked', async () => {
+ await clickShowMoreFewerButton();
+ await clickShowMoreFewerButton();
+ expect(milestoneListText()).toContain(`Milestones ${abbreviatedListString} • show 10 more`);
+ });
});
const expectAllZeros = () => {
diff --git a/spec/frontend/releases/components/release_block_spec.js b/spec/frontend/releases/components/release_block_spec.js
index a847c32b8f1..c4910ae9b2f 100644
--- a/spec/frontend/releases/components/release_block_spec.js
+++ b/spec/frontend/releases/components/release_block_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import $ from 'jquery';
+import { nextTick } from 'vue';
import originalRelease from 'test_fixtures/api/releases/release.json';
import * as commonUtils from '~/lib/utils/common_utils';
import * as urlUtility from '~/lib/utils/url_utility';
@@ -13,7 +14,7 @@ describe('Release block', () => {
let wrapper;
let release;
- const factory = (releaseProp, featureFlags = {}) => {
+ const factory = async (releaseProp, featureFlags = {}) => {
wrapper = mount(ReleaseBlock, {
propsData: {
release: releaseProp,
@@ -25,7 +26,7 @@ describe('Release block', () => {
},
});
- return wrapper.vm.$nextTick();
+ await nextTick();
};
const milestoneListLabel = () => wrapper.find('.js-milestone-list-label');
diff --git a/spec/frontend/releases/components/tag_field_new_spec.js b/spec/frontend/releases/components/tag_field_new_spec.js
index 0f416e46dba..c13b513f87e 100644
--- a/spec/frontend/releases/components/tag_field_new_spec.js
+++ b/spec/frontend/releases/components/tag_field_new_spec.js
@@ -1,6 +1,6 @@
import { GlDropdownItem } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import { __ } from '~/locale';
import TagFieldNew from '~/releases/components/tag_field_new.vue';
import createStore from '~/releases/stores';
@@ -153,7 +153,7 @@ describe('releases/components/tag_field_new', () => {
* Should be passed either 'shown' or 'hidden'
*/
const expectValidationMessageToBe = async (state) => {
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findTagNameFormGroup().element).toHaveClass(
state === 'shown' ? 'is-invalid' : 'is-valid',
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 3384fd599b4..70808a3c7b1 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -1,8 +1,9 @@
import { GlLoadingIcon } from '@gitlab/ui';
-import { mount, shallowMount, createLocalVue } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
-import { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -36,11 +37,10 @@ jest.mock('~/lib/utils/common_utils');
let wrapper;
let mockResolver;
-const localVue = createLocalVue();
const mockAxios = new MockAdapter(axios);
const createComponent = async (mockData = {}, mountFn = shallowMount) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const {
blob = simpleViewerMock,
@@ -75,7 +75,6 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
wrapper = extendedWrapper(
mountFn(BlobContentViewer, {
- localVue,
apolloProvider: fakeApollo,
propsData: propsMock,
mixins: [{ data: () => ({ ref: refMock }) }],
diff --git a/spec/frontend/repository/components/blob_controls_spec.js b/spec/frontend/repository/components/blob_controls_spec.js
index 03e389ea5cb..6da1861ea7c 100644
--- a/spec/frontend/repository/components/blob_controls_spec.js
+++ b/spec/frontend/repository/components/blob_controls_spec.js
@@ -1,6 +1,6 @@
-import { createLocalVue } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
+
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import BlobControls from '~/repository/components/blob_controls.vue';
@@ -16,10 +16,8 @@ let router;
let wrapper;
let mockResolver;
-const localVue = createLocalVue();
-
const createComponent = async () => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const project = { ...blobControlsDataMock };
const projectPath = 'some/project';
@@ -31,7 +29,6 @@ const createComponent = async () => {
mockResolver = jest.fn().mockResolvedValue({ data: { project } });
wrapper = shallowMountExtended(BlobControls, {
- localVue,
router,
apolloProvider: createMockApollo([[blobControlsQuery, mockResolver]]),
propsData: { projectPath },
diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js
index ad2cbd70187..0e300291d05 100644
--- a/spec/frontend/repository/components/breadcrumbs_spec.js
+++ b/spec/frontend/repository/components/breadcrumbs_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown } from '@gitlab/ui';
import { shallowMount, RouterLinkStub } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Breadcrumbs from '~/repository/components/breadcrumbs.vue';
import UploadBlobModal from '~/repository/components/upload_blob_modal.vue';
import NewDirectoryModal from '~/repository/components/new_directory_modal.vue';
@@ -79,7 +80,7 @@ describe('Repository breadcrumbs component', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ userPermissions: { forkProject: false, createMergeRequestIn: false } });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlDropdown).exists()).toBe(false);
});
@@ -106,7 +107,7 @@ describe('Repository breadcrumbs component', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ userPermissions: { forkProject: true, createMergeRequestIn: true } });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlDropdown).exists()).toBe(true);
});
@@ -125,7 +126,7 @@ describe('Repository breadcrumbs component', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findUploadBlobModal().exists()).toBe(true);
});
@@ -149,7 +150,7 @@ describe('Repository breadcrumbs component', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ $apollo: { queries: { userPermissions: { loading: false } } } });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findNewDirectoryModal().exists()).toBe(true);
});
diff --git a/spec/frontend/repository/components/upload_blob_modal_spec.js b/spec/frontend/repository/components/upload_blob_modal_spec.js
index 6b8b0752485..bf024baa627 100644
--- a/spec/frontend/repository/components/upload_blob_modal_spec.js
+++ b/spec/frontend/repository/components/upload_blob_modal_spec.js
@@ -2,6 +2,7 @@ import { GlModal, GlFormInput, GlFormTextarea, GlToggle, GlAlert } from '@gitlab
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status';
@@ -113,7 +114,7 @@ describe('UploadBlobModal', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ target: 'Not main' });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findMrToggle().exists()).toBe(true);
});
@@ -202,7 +203,7 @@ describe('UploadBlobModal', () => {
wrapper.vm.uploadFile = jest.fn();
wrapper.vm.replaceFile = jest.fn();
wrapper.vm.submitForm();
- await wrapper.vm.$nextTick();
+ await nextTick();
};
const submitRequest = async () => {
diff --git a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
index 9a9438417ee..e694fbf86a3 100644
--- a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
+++ b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
@@ -1,4 +1,5 @@
-import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -18,8 +19,7 @@ jest.mock('~/runner/sentry_utils');
const mockRunnerGraphqlId = runnerData.data.runner.id;
const mockRunnerId = `${getIdFromGraphQLId(mockRunnerGraphqlId)}`;
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('AdminRunnerEditApp', () => {
let wrapper;
@@ -29,7 +29,6 @@ describe('AdminRunnerEditApp', () => {
const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => {
wrapper = mountFn(AdminRunnerEditApp, {
- localVue,
apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
propsData: {
runnerId: mockRunnerId,
diff --git a/spec/frontend/runner/components/registration/registration_dropdown_spec.js b/spec/frontend/runner/components/registration/registration_dropdown_spec.js
index 2685d387ef2..26d3f852a1e 100644
--- a/spec/frontend/runner/components/registration/registration_dropdown_spec.js
+++ b/spec/frontend/runner/components/registration/registration_dropdown_spec.js
@@ -1,8 +1,9 @@
import { GlDropdown, GlDropdownItem, GlDropdownForm } from '@gitlab/ui';
-import { createLocalVue, createWrapper } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { mount, shallowMount, createWrapper } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
-import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import RegistrationDropdown from '~/runner/components/registration/registration_dropdown.vue';
@@ -33,15 +34,17 @@ describe('RegistrationDropdown', () => {
const findToggleMaskButton = () => wrapper.findByTestId('toggle-masked');
- const createComponent = ({ props = {}, ...options } = {}, mountFn = shallowMountExtended) => {
- wrapper = mountFn(RegistrationDropdown, {
- propsData: {
- registrationToken: mockToken,
- type: INSTANCE_TYPE,
- ...props,
- },
- ...options,
- });
+ const createComponent = ({ props = {}, ...options } = {}, mountFn = shallowMount) => {
+ wrapper = extendedWrapper(
+ mountFn(RegistrationDropdown, {
+ propsData: {
+ registrationToken: mockToken,
+ type: INSTANCE_TYPE,
+ ...props,
+ },
+ ...options,
+ }),
+ );
};
it.each`
@@ -50,7 +53,7 @@ describe('RegistrationDropdown', () => {
${GROUP_TYPE} | ${'Register a group runner'}
${PROJECT_TYPE} | ${'Register a project runner'}
`('Dropdown text for type $type is "$text"', () => {
- createComponent({ props: { type: INSTANCE_TYPE } }, mountExtended);
+ createComponent({ props: { type: INSTANCE_TYPE } }, mount);
expect(wrapper.text()).toContain('Register an instance runner');
});
@@ -71,8 +74,7 @@ describe('RegistrationDropdown', () => {
});
describe('When the dropdown item is clicked', () => {
- const localVue = createLocalVue();
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [
[getRunnerPlatformsQuery, jest.fn().mockResolvedValue(mockGraphqlRunnerPlatforms)],
@@ -85,13 +87,12 @@ describe('RegistrationDropdown', () => {
beforeEach(async () => {
createComponent(
{
- localVue,
// Mock load modal contents from API
apolloProvider: createMockApollo(requestHandlers),
// Use `attachTo` to find the modal
attachTo: document.body,
},
- mountExtended,
+ mount,
);
await findRegistrationInstructionsDropdownItem().trigger('click');
@@ -129,7 +130,7 @@ describe('RegistrationDropdown', () => {
});
it('Displays masked value by default', () => {
- createComponent({}, mountExtended);
+ createComponent({}, mount);
expect(findTokenDropdownItem().text()).toMatchInterpolatedText(
`Registration token ${maskToken}`,
@@ -152,7 +153,7 @@ describe('RegistrationDropdown', () => {
});
it('Updates the token when it gets reset', async () => {
- createComponent({}, mountExtended);
+ createComponent({}, mount);
const newToken = 'mock1';
diff --git a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
index d8cdec0eafc..43b9aa9c413 100644
--- a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
+++ b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
@@ -1,7 +1,8 @@
-import Vue, { nextTick } from 'vue';
import { GlDropdownItem, GlLoadingIcon, GlToast, GlModal } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
@@ -32,7 +33,7 @@ describe('RegistrationTokenResetDropdownItem', () => {
const clickSubmit = () => findModal().vm.$emit('primary', mockEvent);
const createComponent = ({ props, provide = {} } = {}) => {
- wrapper = shallowMountExtended(RegistrationTokenResetDropdownItem, {
+ wrapper = shallowMount(RegistrationTokenResetDropdownItem, {
provide,
propsData: {
type: INSTANCE_TYPE,
diff --git a/spec/frontend/runner/group_runners/group_runners_app_spec.js b/spec/frontend/runner/group_runners/group_runners_app_spec.js
index 6becc1ba743..7872cfd6cf4 100644
--- a/spec/frontend/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js
@@ -1,6 +1,7 @@
import Vue, { nextTick } from 'vue';
import { GlLink } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
+
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
diff --git a/spec/frontend/serverless/survey_banner_spec.js b/spec/frontend/serverless/survey_banner_spec.js
index 4682c2328c3..022aa47c113 100644
--- a/spec/frontend/serverless/survey_banner_spec.js
+++ b/spec/frontend/serverless/survey_banner_spec.js
@@ -1,6 +1,7 @@
import { GlBanner } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
+import { nextTick } from 'vue';
import SurveyBanner from '~/serverless/survey_banner.vue';
describe('Knative survey banner', () => {
@@ -27,7 +28,7 @@ describe('Knative survey banner', () => {
expect(wrapper.find(GlBanner).exists()).toBe(true);
});
- it('should close the banner and set a cookie when close button is clicked', () => {
+ it('should close the banner and set a cookie when close button is clicked', async () => {
jest.spyOn(Cookies, 'get').mockReturnValue(undefined);
jest.spyOn(Cookies, 'set');
mountBanner();
@@ -35,10 +36,9 @@ describe('Knative survey banner', () => {
expect(wrapper.find(GlBanner).exists()).toBe(true);
wrapper.find(GlBanner).vm.$emit('close');
- return wrapper.vm.$nextTick().then(() => {
- expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', { expires: 3650 });
- expect(wrapper.find(GlBanner).exists()).toBe(false);
- });
+ await nextTick();
+ expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', { expires: 3650 });
+ expect(wrapper.find(GlBanner).exists()).toBe(false);
});
it('should not render the banner when the cookie is set', () => {
diff --git a/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js b/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
index 0c6ed998747..c105810e11c 100644
--- a/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
+++ b/spec/frontend/set_status_modal/set_status_modal_wrapper_spec.js
@@ -1,5 +1,6 @@
import { GlModal, GlFormCheckbox } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { initEmojiMock, clearEmojiMock } from 'helpers/emoji';
import * as UserApi from '~/api/user_api';
import EmojiPicker from '~/emoji/components/picker.vue';
@@ -48,7 +49,7 @@ describe('SetStatusModalWrapper', () => {
const findAvailabilityCheckbox = () => wrapper.find(GlFormCheckbox);
const findClearStatusAtMessage = () => wrapper.find('[data-testid="clear-status-at-message"]');
- const initModal = ({ mockOnUpdateSuccess = true, mockOnUpdateFailure = true } = {}) => {
+ const initModal = async ({ mockOnUpdateSuccess = true, mockOnUpdateFailure = true } = {}) => {
const modal = findModal();
// mock internal emoji methods
wrapper.vm.showEmojiMenu = jest.fn();
@@ -57,7 +58,7 @@ describe('SetStatusModalWrapper', () => {
if (mockOnUpdateFailure) wrapper.vm.onUpdateFail = jest.fn();
modal.vm.$emit('shown');
- return wrapper.vm.$nextTick();
+ await nextTick();
};
afterEach(() => {
@@ -207,7 +208,7 @@ describe('SetStatusModalWrapper', () => {
it('clicking "removeStatus" clears the emoji and message fields', async () => {
findModal().vm.$emit('secondary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findFormField('message').element.value).toBe('');
expect(findFormField('emoji').element.value).toBe('');
@@ -215,7 +216,7 @@ describe('SetStatusModalWrapper', () => {
it('clicking "setStatus" submits the user status', async () => {
findModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
// set the availability status
findAvailabilityCheckbox().vm.$emit('input', true);
@@ -224,7 +225,7 @@ describe('SetStatusModalWrapper', () => {
wrapper.find('[data-testid="thirtyMinutes"]').vm.$emit('click');
findModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
const commonParams = {
emoji: defaultEmoji,
@@ -246,7 +247,7 @@ describe('SetStatusModalWrapper', () => {
it('calls the "onUpdateSuccess" handler', async () => {
findModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.onUpdateSuccess).toHaveBeenCalled();
});
@@ -262,7 +263,7 @@ describe('SetStatusModalWrapper', () => {
it('displays a toast success message', async () => {
findModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect($toast.show).toHaveBeenCalledWith('Status updated');
});
@@ -279,7 +280,7 @@ describe('SetStatusModalWrapper', () => {
it('calls the "onUpdateFail" handler', async () => {
findModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.vm.onUpdateFail).toHaveBeenCalled();
});
@@ -295,7 +296,7 @@ describe('SetStatusModalWrapper', () => {
it('flashes an error message', async () => {
findModal().vm.$emit('primary');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(createFlash).toHaveBeenCalledWith({
message: "Sorry, we weren't able to set your status. Please try again later.",
diff --git a/spec/frontend/sidebar/assignees_realtime_spec.js b/spec/frontend/sidebar/assignees_realtime_spec.js
index ecf33d6de37..2249a1c08b8 100644
--- a/spec/frontend/sidebar/assignees_realtime_spec.js
+++ b/spec/frontend/sidebar/assignees_realtime_spec.js
@@ -1,4 +1,5 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import AssigneesRealtime from '~/sidebar/components/assignees/assignees_realtime.vue';
@@ -7,8 +8,7 @@ import SidebarMediator from '~/sidebar/sidebar_mediator';
import getIssueAssigneesQuery from '~/vue_shared/components/sidebar/queries/get_issue_assignees.query.graphql';
import Mock, { issuableQueryResponse, subscriptionNullResponse } from './mock_data';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Assignees Realtime', () => {
let wrapper;
@@ -38,7 +38,6 @@ describe('Assignees Realtime', () => {
mediator,
},
apolloProvider: fakeApollo,
- localVue,
});
};
diff --git a/spec/frontend/sidebar/assignees_spec.js b/spec/frontend/sidebar/assignees_spec.js
index b3a67f18f82..a4474ead956 100644
--- a/spec/frontend/sidebar/assignees_spec.js
+++ b/spec/frontend/sidebar/assignees_spec.js
@@ -1,5 +1,6 @@
import { GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper';
import UsersMockHelper from 'helpers/user_mock_data_helper';
import Assignee from '~/sidebar/components/assignees/assignees.vue';
@@ -59,7 +60,7 @@ describe('Assignee component', () => {
expect(componentTextNoUsers).toContain('assign yourself');
});
- it('emits the assign-self event when "assign yourself" is clicked', () => {
+ it('emits the assign-self event when "assign yourself" is clicked', async () => {
createWrapper({
...getDefaultProps(),
editable: true,
@@ -68,9 +69,8 @@ describe('Assignee component', () => {
jest.spyOn(wrapper.vm, '$emit');
wrapper.find('[data-testid="assign-yourself"]').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('assign-self')).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted('assign-self')).toBeTruthy();
});
});
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
index 76a00f5a826..3045b8c5842 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
@@ -1,6 +1,7 @@
import { GlSearchBoxByType, GlDropdown } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -23,8 +24,7 @@ const updateIssueAssigneesMutationSuccess = jest
.mockResolvedValue(updateIssueAssigneesMutationResponse);
const mockError = jest.fn().mockRejectedValue('Error!');
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
const initialAssignees = [
{
@@ -59,7 +59,6 @@ describe('Sidebar assignees widget', () => {
[updateIssueAssigneesMutation, updateIssueAssigneesMutationHandler],
]);
wrapper = shallowMount(SidebarAssigneesWidget, {
- localVue,
apolloProvider: fakeApollo,
propsData: {
iid: '1',
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js
index 84b192aaf41..c870bbecd76 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_editable_item_spec.js
@@ -1,5 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
describe('boards sidebar remove issue', () => {
@@ -71,7 +72,7 @@ describe('boards sidebar remove issue', () => {
createComponent({ canUpdate: true, slots });
findEditButton().vm.$emit('click');
- await wrapper.vm.$nextTick;
+ await nextTick;
expect(findCollapsed().isVisible()).toBe(false);
expect(findExpanded().isVisible()).toBe(true);
@@ -82,14 +83,14 @@ describe('boards sidebar remove issue', () => {
beforeEach(async () => {
createComponent({ canUpdate: true });
findEditButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('hides expanded section and displays collapsed section', async () => {
expect(findExpanded().isVisible()).toBe(true);
document.body.click();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findCollapsed().isVisible()).toBe(true);
expect(findExpanded().isVisible()).toBe(false);
@@ -101,7 +102,7 @@ describe('boards sidebar remove issue', () => {
findEditButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted().open.length).toBe(1);
});
@@ -111,7 +112,7 @@ describe('boards sidebar remove issue', () => {
findEditButton().vm.$emit('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.vm.collapse({ emitEvent: false });
diff --git a/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js b/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js
index c72c23a3a60..90aae85e1ca 100644
--- a/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js
+++ b/spec/frontend/sidebar/components/assignees/uncollapsed_assignee_list_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import UsersMockHelper from 'helpers/user_mock_data_helper';
import AssigneeAvatarLink from '~/sidebar/components/assignees/assignee_avatar_link.vue';
@@ -84,10 +85,10 @@ describe('UncollapsedAssigneeList component', () => {
});
describe('when more button is clicked', () => {
- beforeEach(() => {
+ beforeEach(async () => {
findMoreButton().trigger('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows "show less" label', () => {
diff --git a/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js b/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js
index 707215d0739..1de71e52264 100644
--- a/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js
+++ b/spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js
@@ -1,5 +1,6 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
+
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -15,8 +16,7 @@ import { issueConfidentialityResponse } from '../../mock_data';
jest.mock('~/flash');
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Sidebar Confidentiality Widget', () => {
let wrapper;
@@ -32,7 +32,6 @@ describe('Sidebar Confidentiality Widget', () => {
fakeApollo = createMockApollo([[issueConfidentialQuery, confidentialQueryHandler]]);
wrapper = shallowMount(SidebarConfidentialityWidget, {
- localVue,
apolloProvider: fakeApollo,
provide: {
canUpdate: true,
diff --git a/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js b/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js
index d7471d99477..3ddd41c0bd4 100644
--- a/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js
+++ b/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js
@@ -8,9 +8,9 @@ import {
GlLoadingIcon,
} from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
-import { createLocalVue, shallowMount, mount } from '@vue/test-utils';
+import { shallowMount, mount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
-
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
@@ -37,8 +37,6 @@ import {
jest.mock('~/flash');
-const localVue = createLocalVue();
-
describe('SidebarDropdownWidget', () => {
let wrapper;
let mockApollo;
@@ -78,7 +76,7 @@ describe('SidebarDropdownWidget', () => {
// It then emits `shown` event in a watcher for `visible`
// Hence we need both of these:
await waitForPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
};
const waitForApollo = async () => {
@@ -108,7 +106,7 @@ describe('SidebarDropdownWidget', () => {
projectMilestonesSpy = jest.fn().mockResolvedValue(mockProjectMilestonesResponse),
currentMilestoneSpy = jest.fn().mockResolvedValue(noCurrentMilestoneResponse),
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
mockApollo = createMockApollo([
[projectMilestonesQuery, projectMilestonesSpy],
[projectIssueMilestoneQuery, currentMilestoneSpy],
@@ -117,7 +115,6 @@ describe('SidebarDropdownWidget', () => {
wrapper = extendedWrapper(
mount(SidebarDropdownWidget, {
- localVue,
provide: { canUpdate: true },
apolloProvider: mockApollo,
propsData: {
@@ -354,7 +351,7 @@ describe('SidebarDropdownWidget', () => {
});
it(`calls createFlash with "${expectedMsg}"`, async () => {
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(createFlash).toHaveBeenCalledWith({
message: expectedMsg,
captureError: true,
@@ -377,7 +374,7 @@ describe('SidebarDropdownWidget', () => {
findSearchBox().vm.$emit('input', 'non existing milestones');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDropdownText().text()).toBe('No milestone found');
});
@@ -482,7 +479,7 @@ describe('SidebarDropdownWidget', () => {
it('sends a projectMilestones query with the entered search term "foo"', async () => {
findSearchBox().vm.$emit('input', mockSearchTerm);
- await wrapper.vm.$nextTick();
+ await nextTick();
// Account for debouncing
jest.runAllTimers();
diff --git a/spec/frontend/sidebar/components/time_tracking/report_spec.js b/spec/frontend/sidebar/components/time_tracking/report_spec.js
index 64d143615a0..2b17e6dd6c3 100644
--- a/spec/frontend/sidebar/components/time_tracking/report_spec.js
+++ b/spec/frontend/sidebar/components/time_tracking/report_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { getAllByRole, getByRole } from '@testing-library/dom';
-import { shallowMount, createLocalVue, mount } from '@vue/test-utils';
+import { shallowMount, mount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -13,8 +14,7 @@ import { getIssueTimelogsQueryResponse, getMrTimelogsQueryResponse } from './moc
jest.mock('~/flash');
describe('Issuable Time Tracking Report', () => {
- const localVue = createLocalVue();
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
let wrapper;
let fakeApollo;
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
@@ -37,7 +37,6 @@ describe('Issuable Time Tracking Report', () => {
issuableType,
},
propsData: { limitToHours, issuableId: '1' },
- localVue,
apolloProvider: fakeApollo,
});
};
diff --git a/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js b/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js
index eb202a8cfcc..835e700e63c 100644
--- a/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js
+++ b/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { stubTransition } from 'helpers/stub_transition';
import { createMockDirective } from 'helpers/vue_mock_directive';
import TimeTracker from '~/sidebar/components/time_tracking/time_tracker.vue';
@@ -161,7 +162,7 @@ describe('Issuable Time Tracker', () => {
it('should show the correct tooltip text', async () => {
expect(findByTestId('timeTrackingComparisonPane').exists()).toBe(true);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findComparisonMeter()).toBe('Time remaining: 26h 23m');
});
@@ -179,7 +180,7 @@ describe('Issuable Time Tracker', () => {
},
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('should display the human readable version of time estimated', () => {
@@ -282,7 +283,7 @@ describe('Issuable Time Tracker', () => {
},
},
});
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('should not show the "Help" pane by default', () => {
@@ -292,19 +293,19 @@ describe('Issuable Time Tracker', () => {
it('should show the "Help" pane when help button is clicked', async () => {
findHelpButton().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findByTestId('helpPane').exists()).toBe(true);
});
it('should not show the "Help" pane when help button is clicked and then closed', async () => {
findHelpButton().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findByTestId('helpPane').exists()).toBe(true);
findCloseHelpButton().trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findByTestId('helpPane').exists()).toBe(false);
});
@@ -315,7 +316,7 @@ describe('Issuable Time Tracker', () => {
it('refetches issuableTimeTracking query when eventHub emits `timeTracker:refresh` event', async () => {
SidebarEventHub.$emit('timeTracker:refresh');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(issuableTimeTrackingRefetchSpy).toHaveBeenCalled();
});
diff --git a/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js b/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
index 2fef3ab9293..ea931782d1e 100644
--- a/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
+++ b/spec/frontend/sidebar/components/todo_toggle/sidebar_todo_widget_spec.js
@@ -1,6 +1,6 @@
import { GlIcon, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -119,7 +119,7 @@ describe('Sidebar Todo Widget', () => {
it('emits `todoUpdated` event on click on icon', async () => {
wrapper.find(GlIcon).vm.$emit('click', event);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.emitted('todoUpdated')).toEqual([[false]]);
});
});
diff --git a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js b/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
index 1673425947e..971744edb0f 100644
--- a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
+++ b/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import createFlash from '~/flash';
import { createStore as createMrStore } from '~/mr_notes/stores';
import createStore from '~/notes/stores';
@@ -118,15 +119,13 @@ describe('EditFormButtons', () => {
});
it('resets loading', async () => {
- await wrapper.vm.$nextTick().then(() => {
- expect(findLockToggle().props('loading')).toBe(false);
- });
+ await nextTick();
+ expect(findLockToggle().props('loading')).toBe(false);
});
- it('emits close form', () => {
- return wrapper.vm.$nextTick().then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('closeLockForm');
- });
+ it('emits close form', async () => {
+ await nextTick();
+ expect(eventHub.$emit).toHaveBeenCalledWith('closeLockForm');
});
it('does not flash an error message', () => {
@@ -153,15 +152,13 @@ describe('EditFormButtons', () => {
});
it('resets loading', async () => {
- await wrapper.vm.$nextTick().then(() => {
- expect(findLockToggle().props('loading')).toBe(false);
- });
+ await nextTick();
+ expect(findLockToggle().props('loading')).toBe(false);
});
- it('emits close form', () => {
- return wrapper.vm.$nextTick().then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('closeLockForm');
- });
+ it('emits close form', async () => {
+ await nextTick();
+ expect(eventHub.$emit).toHaveBeenCalledWith('closeLockForm');
});
it('calls flash with the correct message', () => {
diff --git a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js b/spec/frontend/sidebar/lock/issuable_lock_form_spec.js
index 1743e114bb0..7bf7e563a01 100644
--- a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js
+++ b/spec/frontend/sidebar/lock/issuable_lock_form_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { createStore as createMrStore } from '~/mr_notes/stores';
@@ -80,13 +81,12 @@ describe('IssuableLockForm', () => {
});
describe('when not editable', () => {
- it('does not display the edit form when opened if not editable', () => {
+ it('does not display the edit form when opened if not editable', async () => {
expect(findEditForm().exists()).toBe(false);
findSidebarCollapseIcon().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findEditForm().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findEditForm().exists()).toBe(false);
});
});
@@ -102,13 +102,12 @@ describe('IssuableLockForm', () => {
});
describe("when 'Edit' is clicked", () => {
- it('displays the edit form when editable', () => {
+ it('displays the edit form when editable', async () => {
expect(findEditForm().exists()).toBe(false);
findEditLink().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findEditForm().exists()).toBe(true);
- });
+ await nextTick();
+ expect(findEditForm().exists()).toBe(true);
});
it('tracks the event ', () => {
@@ -123,13 +122,12 @@ describe('IssuableLockForm', () => {
});
describe('When sidebar is collapsed', () => {
- it('displays the edit form when opened', () => {
+ it('displays the edit form when opened', async () => {
expect(findEditForm().exists()).toBe(false);
findSidebarCollapseIcon().trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(findEditForm().exists()).toBe(true);
- });
+ await nextTick();
+ expect(findEditForm().exists()).toBe(true);
});
it('renders a tooltip with the lock status text', () => {
diff --git a/spec/frontend/sidebar/sidebar_assignees_spec.js b/spec/frontend/sidebar/sidebar_assignees_spec.js
index dc121dcb897..5f77e21c1f8 100644
--- a/spec/frontend/sidebar/sidebar_assignees_spec.js
+++ b/spec/frontend/sidebar/sidebar_assignees_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import axios from 'axios';
import AxiosMockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import Assigness from '~/sidebar/components/assignees/assignees.vue';
import AssigneesRealtime from '~/sidebar/components/assignees/assignees_realtime.vue';
import SidebarAssignees from '~/sidebar/components/assignees/sidebar_assignees.vue';
@@ -74,16 +75,15 @@ describe('sidebar assignees', () => {
expect(mediator.store.assignees.length).toBe(1);
});
- it('hides assignees until fetched', () => {
+ it('hides assignees until fetched', async () => {
createComponent();
expect(wrapper.find(Assigness).exists()).toBe(false);
wrapper.vm.store.isFetching.assignees = false;
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.find(Assigness).exists()).toBe(true);
- });
+ await nextTick();
+ expect(wrapper.find(Assigness).exists()).toBe(true);
});
describe('when realTimeIssueSidebar is turned on', () => {
diff --git a/spec/frontend/sidebar/todo_spec.js b/spec/frontend/sidebar/todo_spec.js
index 6829e688c65..9316268d2ad 100644
--- a/spec/frontend/sidebar/todo_spec.js
+++ b/spec/frontend/sidebar/todo_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import SidebarTodos from '~/sidebar/components/todo_toggle/todo.vue';
const defaultProps = {
@@ -49,13 +50,12 @@ describe('SidebarTodo', () => {
);
describe('template', () => {
- it('emits `toggleTodo` event when clicked on button', () => {
+ it('emits `toggleTodo` event when clicked on button', async () => {
createComponent();
wrapper.find('button').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted().toggleTodo).toBeTruthy();
- });
+ await nextTick();
+ expect(wrapper.emitted().toggleTodo).toBeTruthy();
});
it('renders component container element with proper data attributes', () => {
diff --git a/spec/frontend/snippets/components/edit_spec.js b/spec/frontend/snippets/components/edit_spec.js
index 80a8b8ec489..9f608765183 100644
--- a/spec/frontend/snippets/components/edit_spec.js
+++ b/spec/frontend/snippets/components/edit_spec.js
@@ -1,7 +1,8 @@
import { GlLoadingIcon } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import { merge } from 'lodash';
-import { nextTick } from 'vue';
+
import VueApollo, { ApolloMutation } from 'vue-apollo';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -78,8 +79,7 @@ const getApiData = ({
blobActions: [],
});
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('Snippet Edit app', () => {
useFakeDate();
@@ -141,7 +141,6 @@ describe('Snippet Edit app', () => {
wrapper = shallowMount(SnippetEditApp, {
apolloProvider,
- localVue,
stubs: {
ApolloMutation,
FormFooterActions,
diff --git a/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js b/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
index 2693b26aeae..8174ba5c693 100644
--- a/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
+++ b/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import { times } from 'lodash';
+import { nextTick } from 'vue';
import SnippetBlobActionsEdit from '~/snippets/components/snippet_blob_actions_edit.vue';
import SnippetBlobEdit from '~/snippets/components/snippet_blob_edit.vue';
import {
@@ -193,7 +194,7 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
it('emits an action when content changes again', async () => {
triggerBlobUpdate(0, { content });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getLastActions()).toEqual([testEntries.updated.diff]);
});
diff --git a/spec/frontend/snippets/components/snippet_header_spec.js b/spec/frontend/snippets/components/snippet_header_spec.js
index daa9d6345b0..1b9d170556b 100644
--- a/spec/frontend/snippets/components/snippet_header_spec.js
+++ b/spec/frontend/snippets/components/snippet_header_spec.js
@@ -2,6 +2,7 @@ import { GlButton, GlModal, GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { Blob, BinaryBlob } from 'jest/blob/components/mock_data';
@@ -245,7 +246,7 @@ describe('Snippet header component', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({ canCreateSnippet: true });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findButtonsAsModel()).toEqual(
expect.arrayContaining([
@@ -348,33 +349,31 @@ describe('Snippet header component', () => {
describe('in case of successful mutation, closes modal and redirects to correct listing', () => {
useMockLocationHelper();
- const createDeleteSnippet = (snippetProps = {}) => {
+ const createDeleteSnippet = async (snippetProps = {}) => {
createComponent({
snippetProps,
});
wrapper.vm.closeDeleteModal = jest.fn();
wrapper.vm.deleteSnippet();
- return wrapper.vm.$nextTick();
+ await nextTick();
};
- it('redirects to dashboard/snippets for personal snippet', () => {
- return createDeleteSnippet().then(() => {
- expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled();
- expect(window.location.pathname).toBe(`${gon.relative_url_root}dashboard/snippets`);
- });
+ it('redirects to dashboard/snippets for personal snippet', async () => {
+ await createDeleteSnippet();
+ expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled();
+ expect(window.location.pathname).toBe(`${gon.relative_url_root}dashboard/snippets`);
});
- it('redirects to project snippets for project snippet', () => {
+ it('redirects to project snippets for project snippet', async () => {
const fullPath = 'foo/bar';
- return createDeleteSnippet({
+ await createDeleteSnippet({
project: {
fullPath,
},
- }).then(() => {
- expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled();
- expect(window.location.pathname).toBe(`${fullPath}/-/snippets`);
});
+ expect(wrapper.vm.closeDeleteModal).toHaveBeenCalled();
+ expect(window.location.pathname).toBe(`${fullPath}/-/snippets`);
});
});
});
diff --git a/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js b/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js
index 7a8834933e0..f6b29e98e5f 100644
--- a/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_meta_controls_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlDropdownItem, GlFormInput, GlFormTextarea } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import EditMetaControls from '~/static_site_editor/components/edit_meta_controls.vue';
import { mergeRequestMeta, mergeRequestTemplates } from '../mock_data';
@@ -38,11 +39,11 @@ describe('~/static_site_editor/components/edit_meta_controls.vue', () => {
const findGlFormTextAreaDescription = () => wrapper.find(GlFormTextarea);
- beforeEach(() => {
+ beforeEach(async () => {
buildWrapper();
buildMocks();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
diff --git a/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js b/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js
index 3a336f6a230..bf3f8b7f571 100644
--- a/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_meta_modal_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import axios from '~/lib/utils/axios_utils';
import EditMetaControls from '~/static_site_editor/components/edit_meta_controls.vue';
@@ -50,14 +51,14 @@ describe('~/static_site_editor/components/edit_meta_modal.vue', () => {
const findEditMetaControls = () => wrapper.find(EditMetaControls);
const findLocalStorageSync = () => wrapper.find(LocalStorageSync);
- beforeEach(() => {
+ beforeEach(async () => {
localStorage.setItem(MR_META_LOCAL_STORAGE_KEY);
buildMockAxios();
buildWrapper();
buildMockRefs();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
@@ -77,7 +78,7 @@ describe('~/static_site_editor/components/edit_meta_modal.vue', () => {
findLocalStorageSync().vm.$emit('input', localStorageMeta);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findEditMetaControls().props()).toEqual(localStorageMeta);
});
@@ -134,13 +135,13 @@ describe('~/static_site_editor/components/edit_meta_modal.vue', () => {
it('sets the currentTemplate on the changeTemplate event', async () => {
findEditMetaControls().vm.$emit('changeTemplate', template1);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findEditMetaControls().props().currentTemplate).toBe(template1);
findEditMetaControls().vm.$emit('changeTemplate', null);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findEditMetaControls().props().currentTemplate).toBe(null);
});
@@ -148,7 +149,7 @@ describe('~/static_site_editor/components/edit_meta_modal.vue', () => {
it('updates the description on the changeTemplate event', async () => {
findEditMetaControls().vm.$emit('changeTemplate', template1);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findEditMetaControls().props().description).toEqual(template1.content);
});
@@ -164,7 +165,7 @@ describe('~/static_site_editor/components/edit_meta_modal.vue', () => {
findEditMetaControls().vm.$emit('updateSettings', newMeta);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findLocalStorageSync().props('value')).toEqual(newMeta);
});
diff --git a/spec/frontend/static_site_editor/pages/home_spec.js b/spec/frontend/static_site_editor/pages/home_spec.js
index 4f6f2bb3c76..6571d295c36 100644
--- a/spec/frontend/static_site_editor/pages/home_spec.js
+++ b/spec/frontend/static_site_editor/pages/home_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import EditArea from '~/static_site_editor/components/edit_area.vue';
import EditMetaModal from '~/static_site_editor/components/edit_meta_modal.vue';
@@ -179,7 +180,7 @@ describe('static_site_editor/pages/home', () => {
});
describe('when preparing submission', () => {
- it('calls the show method when the edit-area submit event is emitted', () => {
+ it('calls the show method when the edit-area submit event is emitted', async () => {
buildWrapper();
const mockInstance = { show: jest.fn() };
@@ -187,9 +188,8 @@ describe('static_site_editor/pages/home', () => {
findEditArea().vm.$emit('submit', { content });
- return wrapper.vm.$nextTick().then(() => {
- expect(mockInstance.show).toHaveBeenCalled();
- });
+ await nextTick();
+ expect(mockInstance.show).toHaveBeenCalled();
});
});
@@ -200,13 +200,13 @@ describe('static_site_editor/pages/home', () => {
.mockRejectedValueOnce(new Error(submitChangesError));
};
- beforeEach(() => {
+ beforeEach(async () => {
setupMutateMock();
buildWrapper({ content });
findEditMetaModal().vm.$emit('primary', mergeRequestMeta);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays submit changes error message', () => {
@@ -221,12 +221,11 @@ describe('static_site_editor/pages/home', () => {
expect(mutateMock).toHaveBeenCalled();
});
- it('hides submit changes error message when dismiss button is clicked', () => {
+ it('hides submit changes error message when dismiss button is clicked', async () => {
findSubmitChangesError().vm.$emit('dismiss');
- return wrapper.vm.$nextTick().then(() => {
- expect(findSubmitChangesError().exists()).toBe(false);
- });
+ await nextTick();
+ expect(findSubmitChangesError().exists()).toBe(false);
});
});
@@ -234,7 +233,7 @@ describe('static_site_editor/pages/home', () => {
const newContent = `new ${content}`;
const formattedMarkdown = `formatted ${content}`;
- beforeEach(() => {
+ beforeEach(async () => {
mutateMock.mockResolvedValueOnce(hasSubmittedChangesMutationPayload).mockResolvedValueOnce({
data: {
submitContentChanges: savedContentMeta,
@@ -249,7 +248,7 @@ describe('static_site_editor/pages/home', () => {
findEditMetaModal().vm.$emit('primary', mergeRequestMeta);
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('dispatches hasSubmittedChanges mutation', () => {
diff --git a/spec/frontend/terraform/components/states_table_actions_spec.js b/spec/frontend/terraform/components/states_table_actions_spec.js
index fbe55306f37..a6c80b95af4 100644
--- a/spec/frontend/terraform/components/states_table_actions_spec.js
+++ b/spec/frontend/terraform/components/states_table_actions_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlModal, GlSprintf } from '@gitlab/ui';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -9,8 +10,7 @@ import lockStateMutation from '~/terraform/graphql/mutations/lock_state.mutation
import removeStateMutation from '~/terraform/graphql/mutations/remove_state.mutation.graphql';
import unlockStateMutation from '~/terraform/graphql/mutations/unlock_state.mutation.graphql';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('StatesTableActions', () => {
let lockResponse;
@@ -58,20 +58,19 @@ describe('StatesTableActions', () => {
);
};
- const createComponent = (propsData = defaultProps) => {
+ const createComponent = async (propsData = defaultProps) => {
const apolloProvider = createMockApolloProvider();
toast = jest.fn();
wrapper = shallowMount(StateActions, {
apolloProvider,
- localVue,
propsData,
mocks: { $toast: { show: toast } },
stubs: { GlDropdown, GlModal, GlSprintf },
});
- return wrapper.vm.$nextTick();
+ await nextTick();
};
const findActionsDropdown = () => wrapper.findComponent(GlDropdown);
diff --git a/spec/frontend/terraform/components/states_table_spec.js b/spec/frontend/terraform/components/states_table_spec.js
index 100e577f514..9dbc8335851 100644
--- a/spec/frontend/terraform/components/states_table_spec.js
+++ b/spec/frontend/terraform/components/states_table_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { useFakeDate } from 'helpers/fake_date';
import StatesTable from '~/terraform/components/states_table.vue';
import StateActions from '~/terraform/components/states_table_actions.vue';
@@ -106,9 +107,9 @@ describe('StatesTable', () => {
],
};
- const createComponent = (propsData = defaultProps) => {
+ const createComponent = async (propsData = defaultProps) => {
wrapper = mount(StatesTable, { propsData });
- return wrapper.vm.$nextTick();
+ await nextTick();
};
const findActions = () => wrapper.findAll(StateActions);
diff --git a/spec/frontend/terraform/components/terraform_list_spec.js b/spec/frontend/terraform/components/terraform_list_spec.js
index 8e565df81ae..803f1723645 100644
--- a/spec/frontend/terraform/components/terraform_list_spec.js
+++ b/spec/frontend/terraform/components/terraform_list_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlBadge, GlKeysetPagination, GlLoadingIcon, GlTab } from '@gitlab/ui';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -8,8 +9,7 @@ import StatesTable from '~/terraform/components/states_table.vue';
import TerraformList from '~/terraform/components/terraform_list.vue';
import getStatesQuery from '~/terraform/graphql/queries/get_states.query.graphql';
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
describe('TerraformList', () => {
let wrapper;
@@ -45,7 +45,6 @@ describe('TerraformList', () => {
const apolloProvider = createMockApollo([[getStatesQuery, statsQueryResponse]], mockResolvers);
wrapper = shallowMount(TerraformList, {
- localVue,
apolloProvider,
propsData,
stubs: {
diff --git a/spec/frontend/token_access/token_access_spec.js b/spec/frontend/token_access/token_access_spec.js
index c4e29a52f1c..5aaeebd5af4 100644
--- a/spec/frontend/token_access/token_access_spec.js
+++ b/spec/frontend/token_access/token_access_spec.js
@@ -1,5 +1,5 @@
import { GlToggle, GlLoadingIcon } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -22,9 +22,8 @@ import {
const projectPath = 'root/my-repo';
const error = new Error('Error');
-const localVue = createLocalVue();
-localVue.use(VueApollo);
+Vue.use(VueApollo);
jest.mock('~/flash');
@@ -52,7 +51,6 @@ describe('TokenAccess component', () => {
const createComponent = (requestHandlers, mountFn = shallowMountExtended) => {
wrapper = mountFn(TokenAccess, {
- localVue,
provide: {
fullPath: projectPath,
},
diff --git a/spec/frontend/tooltips/components/tooltips_spec.js b/spec/frontend/tooltips/components/tooltips_spec.js
index 9b703b74a1a..eef352a72ff 100644
--- a/spec/frontend/tooltips/components/tooltips_spec.js
+++ b/spec/frontend/tooltips/components/tooltips_spec.js
@@ -1,5 +1,6 @@
import { GlTooltip } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { useMockMutationObserver } from 'helpers/mock_dom_observer';
import Tooltips from '~/tooltips/components/tooltips.vue';
@@ -46,7 +47,7 @@ describe('tooltips/components/tooltips.vue', () => {
it('attaches tooltips to the targets specified', async () => {
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).props('target')).toBe(target);
});
@@ -56,7 +57,7 @@ describe('tooltips/components/tooltips.vue', () => {
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).exists()).toBe(false);
});
@@ -65,7 +66,7 @@ describe('tooltips/components/tooltips.vue', () => {
wrapper.vm.addTooltips([target]);
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.findAll(GlTooltip)).toHaveLength(1);
});
@@ -73,7 +74,7 @@ describe('tooltips/components/tooltips.vue', () => {
it('sets tooltip content from title attribute', async () => {
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).text()).toBe(target.getAttribute('title'));
});
@@ -85,7 +86,7 @@ describe('tooltips/components/tooltips.vue', () => {
});
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).html()).toContain(target.getAttribute('title'));
});
@@ -94,7 +95,7 @@ describe('tooltips/components/tooltips.vue', () => {
const config = { show: true };
target = createTooltipTarget();
wrapper.vm.addTooltips([target], config);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).props()).toMatchObject(config);
});
@@ -110,7 +111,7 @@ describe('tooltips/components/tooltips.vue', () => {
target = createTooltipTarget({ [attribute]: value });
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).props(prop)).toBe(value);
},
@@ -124,10 +125,10 @@ describe('tooltips/components/tooltips.vue', () => {
it('removes all tooltips when elements is nil', async () => {
wrapper.vm.addTooltips([createTooltipTarget(), createTooltipTarget()]);
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.vm.dispose();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(allTooltips()).toHaveLength(0);
});
@@ -136,10 +137,10 @@ describe('tooltips/components/tooltips.vue', () => {
const target = createTooltipTarget();
wrapper.vm.addTooltips([target, createTooltipTarget()]);
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.vm.dispose(target);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(allTooltips()).toHaveLength(1);
});
@@ -154,13 +155,13 @@ describe('tooltips/components/tooltips.vue', () => {
const target = createTooltipTarget();
wrapper.vm.addTooltips([target, createTooltipTarget()]);
- await wrapper.vm.$nextTick();
+ await nextTick();
triggerMutate(document.body, {
entry: { removedNodes: [target] },
options: { childList: true },
});
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(allTooltips()).toHaveLength(1);
});
@@ -175,7 +176,7 @@ describe('tooltips/components/tooltips.vue', () => {
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.vm.triggerEvent(target, event);
@@ -195,14 +196,14 @@ describe('tooltips/components/tooltips.vue', () => {
wrapper.vm.addTooltips([target]);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).text()).toBe(currentTitle);
target.setAttribute('title', newTitle);
wrapper.vm.fixTitle(target);
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find(GlTooltip).text()).toBe(newTitle);
});
@@ -225,7 +226,7 @@ describe('tooltips/components/tooltips.vue', () => {
buildWrapper();
wrapper.vm.addTooltips([createTooltipTarget()]);
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.findComponent(GlTooltip).vm.$emit('hidden');
expect(wrapper.emitted('hidden')).toHaveLength(1);
diff --git a/spec/frontend/user_lists/components/add_user_modal_spec.js b/spec/frontend/user_lists/components/add_user_modal_spec.js
index c9ad40ed228..cd04836a8c4 100644
--- a/spec/frontend/user_lists/components/add_user_modal_spec.js
+++ b/spec/frontend/user_lists/components/add_user_modal_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import AddUserModal from '~/user_lists/components/add_user_modal.vue';
describe('Add User Modal', () => {
@@ -30,7 +31,7 @@ describe('Add User Modal', () => {
it('should clear the input after emitting', async () => {
click('confirm-add-user-ids');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find('#add-user-ids').element.value).toBe('');
});
@@ -42,7 +43,7 @@ describe('Add User Modal', () => {
it('should clear the input after cancelling', async () => {
click('cancel-add-user-ids');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.find('#add-user-ids').element.value).toBe('');
});
diff --git a/spec/frontend/user_lists/components/edit_user_list_spec.js b/spec/frontend/user_lists/components/edit_user_list_spec.js
index 4731f4b9c02..7cafe5e1f56 100644
--- a/spec/frontend/user_lists/components/edit_user_list_spec.js
+++ b/spec/frontend/user_lists/components/edit_user_list_spec.js
@@ -1,6 +1,6 @@
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
@@ -77,11 +77,11 @@ describe('user_lists/components/edit_user_list', () => {
});
describe('update', () => {
- beforeEach(() => {
+ beforeEach(async () => {
Api.fetchFeatureFlagUserList.mockResolvedValue({ data: userList });
factory();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('should link to the documentation', () => {
@@ -99,11 +99,11 @@ describe('user_lists/components/edit_user_list', () => {
});
describe('success', () => {
- beforeEach(() => {
+ beforeEach(async () => {
Api.updateFeatureFlagUserList.mockResolvedValue({ data: userList });
setInputValue('test');
clickSave();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('should create a user list with the entered name', () => {
@@ -139,7 +139,7 @@ describe('user_lists/components/edit_user_list', () => {
it('should dismiss the error if dismiss is clicked', async () => {
alert.find('button').trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(alert.exists()).toBe(false);
});
diff --git a/spec/frontend/user_lists/components/new_user_list_spec.js b/spec/frontend/user_lists/components/new_user_list_spec.js
index 1cce53c7963..5eb44970fe4 100644
--- a/spec/frontend/user_lists/components/new_user_list_spec.js
+++ b/spec/frontend/user_lists/components/new_user_list_spec.js
@@ -1,6 +1,6 @@
import { GlAlert } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
@@ -43,11 +43,11 @@ describe('user_lists/components/new_user_list', () => {
describe('create', () => {
describe('success', () => {
- beforeEach(() => {
+ beforeEach(async () => {
Api.createFeatureFlagUserList.mockResolvedValue({ data: userList });
setInputValue('test');
click('save-user-list');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('should create a user list with the entered name', () => {
@@ -82,7 +82,7 @@ describe('user_lists/components/new_user_list', () => {
it('should dismiss the error when the dismiss button is clicked', async () => {
alert.find('button').trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(alert.exists()).toBe(false);
});
diff --git a/spec/frontend/user_lists/components/user_list_spec.js b/spec/frontend/user_lists/components/user_list_spec.js
index f016b5091d9..88dad06938b 100644
--- a/spec/frontend/user_lists/components/user_list_spec.js
+++ b/spec/frontend/user_lists/components/user_list_spec.js
@@ -1,7 +1,7 @@
import { GlAlert, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { uniq } from 'lodash';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import Api from '~/api';
import UserList from '~/user_lists/components/user_list.vue';
@@ -57,12 +57,12 @@ describe('User List', () => {
describe('success', () => {
let userIds;
- beforeEach(() => {
+ beforeEach(async () => {
userIds = parseUserIds(userList.user_xids);
Api.fetchFeatureFlagUserList.mockResolvedValueOnce({ data: userList });
factory();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('requests the user list on mount', () => {
@@ -101,10 +101,10 @@ describe('User List', () => {
beforeEach(async () => {
Api.updateFeatureFlagUserList.mockResolvedValue(userList);
click('add-users');
- await wrapper.vm.$nextTick();
+ await nextTick();
wrapper.find('#add-user-ids').setValue(`${stringifyUserIds(newIds)},`);
click('confirm-add-user-ids');
- await wrapper.vm.$nextTick();
+ await nextTick();
[[, { user_xids: receivedUserIds }]] = Api.updateFeatureFlagUserList.mock.calls;
parsedReceivedUserIds = parseUserIds(receivedUserIds);
});
@@ -140,7 +140,7 @@ describe('User List', () => {
beforeEach(async () => {
Api.updateFeatureFlagUserList.mockResolvedValue(userList);
click('delete-user-id');
- await wrapper.vm.$nextTick();
+ await nextTick();
[[, { user_xids: receivedUserIds }]] = Api.updateFeatureFlagUserList.mock.calls;
});
@@ -159,11 +159,11 @@ describe('User List', () => {
describe('error', () => {
const findAlert = () => wrapper.find(GlAlert);
- beforeEach(() => {
+ beforeEach(async () => {
Api.fetchFeatureFlagUserList.mockRejectedValue();
factory();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays the alert message', () => {
@@ -175,18 +175,18 @@ describe('User List', () => {
const alert = findAlert();
alert.find('button').trigger('click');
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(alert.exists()).toBe(false);
});
});
describe('empty list', () => {
- beforeEach(() => {
+ beforeEach(async () => {
Api.fetchFeatureFlagUserList.mockResolvedValueOnce({ data: { ...userList, user_xids: '' } });
factory();
- return wrapper.vm.$nextTick();
+ await nextTick();
});
it('displays an empty state', () => {
diff --git a/spec/frontend/user_lists/components/user_lists_table_spec.js b/spec/frontend/user_lists/components/user_lists_table_spec.js
index 7f4d510a39c..63587703392 100644
--- a/spec/frontend/user_lists/components/user_lists_table_spec.js
+++ b/spec/frontend/user_lists/components/user_lists_table_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import * as timeago from 'timeago.js';
+import { nextTick } from 'vue';
import UserListsTable from '~/user_lists/components/user_lists_table.vue';
import { userList } from '../../feature_flags/mock_data';
@@ -56,43 +57,40 @@ describe('User Lists Table', () => {
});
describe('delete button', () => {
- it('should display the confirmation modal', () => {
+ it('should display the confirmation modal', async () => {
const modal = wrapper.find(GlModal);
wrapper.find('[data-testid="delete-user-list"]').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(modal.text()).toContain(`Delete ${userList.name}?`);
- expect(modal.text()).toContain(`User list ${userList.name} will be removed.`);
- });
+ await nextTick();
+ expect(modal.text()).toContain(`Delete ${userList.name}?`);
+ expect(modal.text()).toContain(`User list ${userList.name} will be removed.`);
});
});
describe('confirmation modal', () => {
let modal;
- beforeEach(() => {
+ beforeEach(async () => {
modal = wrapper.find(GlModal);
wrapper.find('button').trigger('click');
- return wrapper.vm.$nextTick();
+ await nextTick();
});
- it('should emit delete with list on confirmation', () => {
+ it('should emit delete with list on confirmation', async () => {
modal.find('[data-testid="modal-confirm"]').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('delete')).toEqual([[userLists[0]]]);
- });
+ await nextTick();
+ expect(wrapper.emitted('delete')).toEqual([[userLists[0]]]);
});
- it('should not emit delete with list when not confirmed', () => {
+ it('should not emit delete with list when not confirmed', async () => {
modal.find('button').trigger('click');
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.emitted('delete')).toBeUndefined();
- });
+ await nextTick();
+ expect(wrapper.emitted('delete')).toBeUndefined();
});
});
});
diff --git a/spec/frontend/whats_new/components/app_spec.js b/spec/frontend/whats_new/components/app_spec.js
index 45f28c2c51b..945727cd664 100644
--- a/spec/frontend/whats_new/components/app_spec.js
+++ b/spec/frontend/whats_new/components/app_spec.js
@@ -1,6 +1,6 @@
import { GlDrawer, GlInfiniteScroll } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { mockTracking, unmockTracking, triggerEvent } from 'helpers/tracking_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -67,7 +67,7 @@ describe('App', () => {
{ title: 'Whats New Drawer', url: 'www.url.com', release: 3.11 },
];
wrapper.vm.$store.state.drawerBodyHeight = MOCK_DRAWER_BODY_HEIGHT;
- await wrapper.vm.$nextTick();
+ await nextTick();
};
afterEach(() => {
@@ -108,7 +108,7 @@ describe('App', () => {
it.each([true, false])('passes open property', async (openState) => {
wrapper.vm.$store.state.open = openState;
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(getDrawer().props('open')).toBe(openState);
});
diff --git a/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb
index ab584f92716..1f70fbd440c 100644
--- a/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb
+++ b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb
@@ -38,7 +38,6 @@ RSpec.describe 'cross-database foreign keys' do
ci_stages.project_id
ci_subscriptions_projects.downstream_project_id
ci_subscriptions_projects.upstream_project_id
- ci_triggers.project_id
ci_unit_tests.project_id
ci_variables.project_id
dast_site_profiles_pipelines.ci_pipeline_id
diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb
index b9f7e44f3e8..c9ae8519c63 100644
--- a/spec/models/ci/trigger_spec.rb
+++ b/spec/models/ci/trigger_spec.rb
@@ -68,4 +68,11 @@ RSpec.describe Ci::Trigger do
let!(:model) { create(:ci_trigger, owner: parent) }
end
end
+
+ context 'loose foreign key on ci_triggers.project_id' do
+ it_behaves_like 'cleanup by a loose foreign key' do
+ let!(:parent) { create(:project) }
+ let!(:model) { create(:ci_trigger, project: parent) }
+ end
+ end
end