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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
Diffstat (limited to 'qa')
-rw-r--r--qa/Dockerfile2
-rw-r--r--qa/Gemfile12
-rw-r--r--qa/Gemfile.lock25
-rw-r--r--qa/README.md23
-rw-r--r--qa/allure/categories.json57
-rw-r--r--qa/gdk/gdk.yml1
-rw-r--r--qa/lib/gitlab/page/admin/dashboard.rb1
-rw-r--r--qa/lib/gitlab/page/admin/dashboard.stub.rb24
-rw-r--r--qa/lib/gitlab/page/admin/subscription.rb12
-rw-r--r--qa/lib/gitlab/page/admin/subscription.stub.rb186
-rw-r--r--qa/lib/gitlab/page/group/settings/usage_quotas.rb7
-rw-r--r--qa/lib/gitlab/page/trials/new.rb4
-rw-r--r--qa/lib/gitlab/page/trials/new.stub.rb241
-rw-r--r--qa/lib/gitlab/page/trials/select.rb1
-rw-r--r--qa/lib/gitlab/page/trials/select.stub.rb129
-rw-r--r--qa/qa.rb2
-rw-r--r--qa/qa/factories/_shared.rb7
-rw-r--r--qa/qa/factories/groups.rb18
-rw-r--r--qa/qa/factories/issues.rb17
-rw-r--r--qa/qa/factories/projects.rb20
-rw-r--r--qa/qa/fixtures/package_managers/composer/composer_upload_package.yaml.erb2
-rw-r--r--qa/qa/fixtures/package_managers/npm/npm_install_package_group.yaml.erb2
-rw-r--r--qa/qa/fixtures/package_managers/npm/npm_install_package_instance.yaml.erb2
-rw-r--r--qa/qa/fixtures/package_managers/npm/npm_upload_install_package_project.yaml.erb6
-rw-r--r--qa/qa/fixtures/package_managers/npm/npm_upload_package_group.yaml.erb2
-rw-r--r--qa/qa/fixtures/package_managers/npm/npm_upload_package_instance.yaml.erb2
-rw-r--r--qa/qa/fixtures/package_managers/npm/package.json.erb2
-rw-r--r--qa/qa/flow/trial.rb8
-rw-r--r--qa/qa/page/admin/menu.rb6
-rw-r--r--qa/qa/page/admin/overview/users/index.rb6
-rw-r--r--qa/qa/page/base.rb19
-rw-r--r--qa/qa/page/component/access_tokens.rb20
-rw-r--r--qa/qa/page/component/badges.rb12
-rw-r--r--qa/qa/page/component/confirm_modal.rb10
-rw-r--r--qa/qa/page/component/delete_modal.rb2
-rw-r--r--qa/qa/page/component/issuable/common.rb2
-rw-r--r--qa/qa/page/component/issuable/sidebar.rb12
-rw-r--r--qa/qa/page/component/listbox_filter.rb16
-rw-r--r--qa/qa/page/component/members/invite_members_modal.rb4
-rw-r--r--qa/qa/page/component/note.rb2
-rw-r--r--qa/qa/page/component/project/templates.rb4
-rw-r--r--qa/qa/page/component/rich_text_popover.rb9
-rw-r--r--qa/qa/page/dashboard/groups.rb4
-rw-r--r--qa/qa/page/element.rb38
-rw-r--r--qa/qa/page/file/form.rb19
-rw-r--r--qa/qa/page/file/show.rb2
-rw-r--r--qa/qa/page/group/bulk_import.rb6
-rw-r--r--qa/qa/page/group/dependency_proxy.rb4
-rw-r--r--qa/qa/page/group/menu.rb2
-rw-r--r--qa/qa/page/group/new.rb32
-rw-r--r--qa/qa/page/group/sub_menus/common.rb30
-rw-r--r--qa/qa/page/issuable/new.rb2
-rw-r--r--qa/qa/page/main/login.rb14
-rw-r--r--qa/qa/page/main/menu.rb50
-rw-r--r--qa/qa/page/merge_request/show.rb18
-rw-r--r--qa/qa/page/profile/emails.rb7
-rw-r--r--qa/qa/page/profile/ssh_keys.rb2
-rw-r--r--qa/qa/page/project/import/github.rb4
-rw-r--r--qa/qa/page/project/import/repo_by_url.rb12
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/add_existing.rb46
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/index.rb25
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/show.rb30
-rw-r--r--qa/qa/page/project/issue/show.rb38
-rw-r--r--qa/qa/page/project/new.rb46
-rw-r--r--qa/qa/page/project/packages/index.rb12
-rw-r--r--qa/qa/page/project/packages/show.rb14
-rw-r--r--qa/qa/page/project/registry/show.rb20
-rw-r--r--qa/qa/page/project/secure/configuration_form.rb30
-rw-r--r--qa/qa/page/project/settings/ci_variables.rb6
-rw-r--r--qa/qa/page/project/settings/deploy_keys.rb45
-rw-r--r--qa/qa/page/project/settings/mirroring_repositories.rb2
-rw-r--r--qa/qa/page/project/settings/protected_branches.rb5
-rw-r--r--qa/qa/page/project/settings/protected_tags.rb2
-rw-r--r--qa/qa/page/project/settings/repository.rb4
-rw-r--r--qa/qa/page/project/show.rb8
-rw-r--r--qa/qa/page/project/sub_menus/common.rb9
-rw-r--r--qa/qa/page/sub_menus/common.rb18
-rw-r--r--qa/qa/page/sub_menus/super_sidebar/context_switcher.rb9
-rw-r--r--qa/qa/resource/api_fabricator.rb21
-rw-r--r--qa/qa/resource/badge_base.rb1
-rw-r--r--qa/qa/resource/clusters/agent.rb4
-rw-r--r--qa/qa/resource/clusters/agent_token.rb4
-rw-r--r--qa/qa/resource/deploy_key.rb1
-rw-r--r--qa/qa/resource/group_access_token.rb1
-rw-r--r--qa/qa/resource/impersonation_token.rb1
-rw-r--r--qa/qa/resource/issue.rb7
-rw-r--r--qa/qa/resource/merge_request.rb17
-rw-r--r--qa/qa/resource/personal_access_token.rb1
-rw-r--r--qa/qa/resource/project_access_token.rb1
-rw-r--r--qa/qa/runtime/allure_report.rb3
-rw-r--r--qa/qa/runtime/env.rb54
-rw-r--r--qa/qa/runtime/fixtures.rb4
-rw-r--r--qa/qa/service/cluster_provider/gcloud.rb81
-rw-r--r--qa/qa/service/docker_run/base.rb8
-rw-r--r--qa/qa/service/docker_run/gitlab_runner.rb2
-rw-r--r--qa/qa/service/docker_run/smocker.rb8
-rw-r--r--qa/qa/service/kubernetes_cluster.rb29
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb28
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb9
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb17
-rw-r--r--qa/qa/specs/features/api/1_manage/project_access_token_spec.rb4
-rw-r--r--qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb16
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb8
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb16
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb10
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb9
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb9
-rw-r--r--qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb7
-rw-r--r--qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb7
-rw-r--r--qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb7
-rw-r--r--qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb7
-rw-r--r--qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb7
-rw-r--r--qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb4
-rw-r--r--qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb6
-rw-r--r--qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb6
-rw-r--r--qa/qa/specs/features/api/4_verify/file_variable_downstream_pipeline_spec.rb231
-rw-r--r--qa/qa/specs/features/api/4_verify/file_variable_spec.rb7
-rw-r--r--qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb6
-rw-r--r--qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb23
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/slash_commands_spec.rb15
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_content_creation_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_from_push_notification_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/source_editor/source_editor_toolbar_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb28
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_multiple_projects_spec.rb22
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb18
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_with_manual_jobs_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/saas/container_registry_spec.rb89
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/saas/pull_container_registry_image_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/self_managed/container_registry_spec.rb57
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb26
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb15
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb20
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_group_level_spec.rb258
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb254
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb225
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb22
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb26
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/alert_settings_create_new_alerts_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/automatically_creates_incident_for_alert_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/create_alert_using_authorization_key_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb24
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb33
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb16
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb28
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb9
-rw-r--r--qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb5
-rw-r--r--qa/qa/specs/features/shared_contexts/packages_registry_shared_context.rb3
-rw-r--r--qa/qa/specs/features/shared_contexts/variable_inheritance_shared_context.rb7
-rw-r--r--qa/qa/specs/features/shared_examples/create_and_terminate_workspace_shared_examples.rb38
-rw-r--r--qa/qa/specs/spec_helper.rb14
-rw-r--r--qa/qa/support/api.rb9
-rw-r--r--qa/qa/support/formatters/test_metrics_formatter.rb9
-rw-r--r--qa/qa/support/gitlab_address.rb30
-rw-r--r--qa/qa/support/helpers/masker.rb76
-rw-r--r--qa/qa/support/helpers/plan.rb8
-rw-r--r--qa/qa/support/matchers/have_matcher.rb1
-rw-r--r--qa/qa/support/wait_for_requests.rb5
-rw-r--r--qa/qa/tools/ci/helpers.rb27
-rw-r--r--qa/qa/vendor/saml_idp/page/login.rb6
-rw-r--r--qa/spec/page/element_spec.rb45
-rw-r--r--qa/spec/support/api_spec.rb29
-rw-r--r--qa/spec/support/formatters/test_metrics_formatter_spec.rb3
-rw-r--r--qa/spec/support/gitlab_address_spec.rb61
-rw-r--r--qa/spec/support/helpers/masker_spec.rb169
254 files changed, 2645 insertions, 2087 deletions
diff --git a/qa/Dockerfile b/qa/Dockerfile
index 213ec3450cb..92866ec66cc 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -49,6 +49,8 @@ COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/co
COPY ./config/feature_flags /home/gitlab/config/feature_flags
COPY ./config/bundler_setup.rb /home/gitlab/config/
COPY ./lib/gitlab_edition.rb /home/gitlab/lib/
+COPY ./spec/support/fast_quarantine.rb /home/gitlab/spec/support/
+COPY ./tooling/lib/tooling/fast_quarantine.rb /home/gitlab/tooling/lib/tooling/
COPY ./INSTALLATION_TYPE ./VERSION /home/gitlab/
COPY ./qa /home/gitlab/qa
diff --git a/qa/Gemfile b/qa/Gemfile
index e9616f29731..8ad40ec12c2 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,8 +2,8 @@
source 'https://rubygems.org'
-gem 'gitlab-qa', '~> 12', '>= 12.1.0', require: 'gitlab/qa'
-gem 'gitlab_quality-test_tooling', '~> 0.8.3', require: false
+gem 'gitlab-qa', '~> 12', '>= 12.2.1', require: 'gitlab/qa'
+gem 'gitlab_quality-test_tooling', '~> 0.9.3', require: false
gem 'gitlab-utils', path: '../gems/gitlab-utils'
gem 'activesupport', '~> 7.0.5.1' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.20.0'
@@ -24,7 +24,7 @@ gem 'rotp', '~> 6.2.2'
gem 'parallel', '~> 1.23'
gem 'rainbow', '~> 3.1.1'
gem 'rspec-parameterized', '~> 1.0.0'
-gem 'octokit', '~> 6.1.1'
+gem 'octokit', '~> 7.0.0'
gem "faraday-retry", "~> 2.2"
gem 'zeitwerk', '~> 2.6', '>= 2.6.8'
gem 'influxdb-client', '~> 2.9'
@@ -36,14 +36,16 @@ gem "warning", "~> 1.3"
gem 'confiner', '~> 0.4'
-gem 'chemlab', '~> 0.10'
+gem 'chemlab', '~> 0.11', '>= 0.11.1'
gem 'chemlab-library-www-gitlab-com', '~> 0.1', '>= 0.1.1'
# dependencies for jenkins client
-gem 'nokogiri', '~> 1.15', '>= 1.15.3'
+gem 'nokogiri', '~> 1.15', '>= 1.15.4'
gem 'deprecation_toolkit', '~> 2.0.3', require: false
+gem 'factory_bot', '~> 6.2.1'
+
group :development do
gem 'pry-byebug', '~> 3.10.1', platform: :mri
gem "ruby-debug-ide", "~> 0.7.3"
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 521f101ee4d..67d64684aa1 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -56,7 +56,7 @@ GEM
capybara-screenshot (1.0.26)
capybara (>= 1.0, < 4)
launchy
- chemlab (0.10.0)
+ chemlab (0.11.1)
colorize (~> 0.8)
i18n (~> 1.8)
rake (>= 12, < 14)
@@ -80,6 +80,8 @@ GEM
unf (>= 0.0.5, < 1.0.0)
erubi (1.12.0)
excon (0.92.4)
+ factory_bot (6.2.1)
+ activesupport (>= 5.0.0)
faker (3.2.0)
i18n (>= 1.8.11, < 2)
faraday (2.5.2)
@@ -119,7 +121,7 @@ GEM
gitlab (4.19.0)
httparty (~> 0.20)
terminal-table (>= 1.5.1)
- gitlab-qa (12.1.0)
+ gitlab-qa (12.2.1)
activesupport (>= 6.1, < 7.1)
gitlab (~> 4.19)
http (~> 5.0)
@@ -128,7 +130,7 @@ GEM
rainbow (>= 3, < 4)
table_print (= 1.5.7)
zeitwerk (>= 2, < 3)
- gitlab_quality-test_tooling (0.8.3)
+ gitlab_quality-test_tooling (0.9.3)
activesupport (>= 6.1, < 7.1)
gitlab (~> 4.19)
http (~> 5.0)
@@ -210,10 +212,10 @@ GEM
multi_json (1.15.0)
multi_xml (0.6.0)
netrc (0.11.0)
- nokogiri (1.15.3)
+ nokogiri (1.15.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
- octokit (6.1.1)
+ octokit (7.0.0)
faraday (>= 1, < 3)
sawyer (~> 0.9)
oj (3.13.23)
@@ -340,21 +342,22 @@ DEPENDENCIES
allure-rspec (~> 2.20.0)
capybara (~> 3.39.2)
capybara-screenshot (~> 1.0.26)
- chemlab (~> 0.10)
+ chemlab (~> 0.11, >= 0.11.1)
chemlab-library-www-gitlab-com (~> 0.1, >= 0.1.1)
confiner (~> 0.4)
deprecation_toolkit (~> 2.0.3)
+ factory_bot (~> 6.2.1)
faker (~> 3.2)
faraday-retry (~> 2.2)
fog-core (= 2.1.0)
fog-google (~> 1.19)
- gitlab-qa (~> 12, >= 12.1.0)
+ gitlab-qa (~> 12, >= 12.2.1)
gitlab-utils!
- gitlab_quality-test_tooling (~> 0.8.3)
+ gitlab_quality-test_tooling (~> 0.9.3)
influxdb-client (~> 2.9)
knapsack (~> 4.0)
- nokogiri (~> 1.15, >= 1.15.3)
- octokit (~> 6.1.1)
+ nokogiri (~> 1.15, >= 1.15.4)
+ octokit (~> 7.0.0)
parallel (~> 1.23)
parallel_tests (~> 4.2, >= 4.2.1)
pry-byebug (~> 3.10.1)
@@ -374,4 +377,4 @@ DEPENDENCIES
zeitwerk (~> 2.6, >= 2.6.8)
BUNDLED WITH
- 2.4.15
+ 2.4.18
diff --git a/qa/README.md b/qa/README.md
index d8670d4da02..c1b6794ca60 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -93,9 +93,9 @@ By default tests on CI use `info` log level. `debug` level is still available in
### Run the end-to-end tests in a local development environment
-1. Follow the instructions to [install GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/index.md), your local GitLab development environment.
+First, follow the instructions to [install GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/index.md) as your local GitLab development environment.
-1. Navigate to the QA folder and run the following commands.
+Then, navigate to the QA folder and run the following commands:
```bash
cd gitlab-development-kit/gitlab/qa
@@ -104,13 +104,13 @@ export WEBDRIVER_HEADLESS=false
export GITLAB_INITIAL_ROOT_PASSWORD={your current root user's password}
```
-1. Most tests that do not require special setup could simply be run with the following command. However, tests that are tagged with `:orchestrated` tag require special setup. These tests can only be run with [bin/qa](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/README.md#running-tests-with-a-custom-binqa-test-runner) script.
+Finally, most tests that do not require special setup (or have the `:orchestrated` tag) can be run with the following command:
```bash
bundle exec rspec <path/to/spec.rb>
```
-1. For test that are tagged with `:orchestrated`, [re-configure IP address in GDK](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/run_qa_against_gdk.md#run-qa-tests-against-your-gdk-setup) to run QA tests. Once you have reconfigured GDK, ensure GitLab is running successfully on the IP address configured, then run the following command:
+However, tests that are tagged with the `:orchestrated` tag require special setup. To run these tests, first [re-configure the IP address in GDK](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/run_qa_against_gdk.md#run-qa-tests-against-your-gdk-setup), and then run the following command:
```bash
bundle exec bin/qa Test::Instance::All {GDK IP ADDRESS}
@@ -119,6 +119,21 @@ bundle exec bin/qa Test::Instance::All {GDK IP ADDRESS}
- Note: If you want to run tests requiring SSH against GDK, you will need to [modify your GDK setup](https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md).
- Note: If this is your first time running GDK, you can use the password pre-set for `root`. [See supported GitLab environment variables](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#supported-gitlab-environment-variables). If you have changed your `root` password, use that when exporting `GITLAB_INITIAL_ROOT_PASSWORD`.
+#### Generic command for a typical GDK installation
+
+The following is an example command you can use if you have configured GDK to run on a specific IP address and port, with a username, password, and personal access token that aren't the defaults, and you would like the test framework to show debug logs:
+
+```bash
+GITLAB_QA_ACCESS_TOKEN={GDK API PAT} \
+GITLAB_USERNAME={GDK USERNAME} \
+GITLAB_PASSWORD={GDK PASSWORD} \
+QA_LOG_LEVEL=DEBUG \
+QA_GITLAB_URL="http://{GDK IP ADDRESS}:{GDK PORT}" \
+bundle exec rspec <path/to/spec.rb>
+```
+
+For an explanation of the variables see the [additional examples below](#overriding-gitlab-address) and the [list of supported environment variables](https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/what_tests_can_be_run.md#supported-environment-variables).
+
#### Run the end-to-end tests on GitLab in Docker
GitLab can be [installed in Docker](https://docs.gitlab.com/ee/install/docker.html).
diff --git a/qa/allure/categories.json b/qa/allure/categories.json
new file mode 100644
index 00000000000..828dc02bddc
--- /dev/null
+++ b/qa/allure/categories.json
@@ -0,0 +1,57 @@
+[
+ {
+ "name": "Fabrication 404 failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Fabrication of \\S+ .* failed \\\\(404\\\\).*"
+ },
+ {
+ "name": "Fabrication 401 failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Fabrication of \\S+ .* failed \\\\(401\\\\)*"
+ },
+ {
+ "name": "Fabrication failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Fabrication of \\S+ .* failed \\\\(\\d+\\\\).*"
+ },
+ {
+ "name": "Element not found",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^(Unable to find css|\\S+ did not appear on).*"
+ },
+ {
+ "name": "Runner did not start failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Wait for runner '\\S+' to register in (group|project) '\\S+' failed.*"
+ },
+ {
+ "name": "Click intercepted failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": ".*element click intercepted.*"
+ },
+ {
+ "name": "Page did not fully load failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Page did not fully load.*"
+ },
+ {
+ "name": "Waiter failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Wait failed after \\d+ seconds.*"
+ },
+ {
+ "name": "Timeout failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "^Timed out reading data from server.*"
+ },
+ {
+ "name": "Ambiguous match failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "Ambiguous match, found \\d+ elements.*"
+ },
+ {
+ "name": "Page validation failure",
+ "matchedStatuses": ["broken"],
+ "messageRegex": "\\S+ did not appear on \\S+ as expected.*"
+ }
+]
diff --git a/qa/gdk/gdk.yml b/qa/gdk/gdk.yml
index 649ac9a60c6..36bf901033c 100644
--- a/qa/gdk/gdk.yml
+++ b/qa/gdk/gdk.yml
@@ -18,6 +18,7 @@ gitlab:
rails:
bootsnap: false
hostname: gdk.test
+ application_settings_cache_seconds: 0
gitlab_k8s_agent:
enabled: false
gitlab_pages:
diff --git a/qa/lib/gitlab/page/admin/dashboard.rb b/qa/lib/gitlab/page/admin/dashboard.rb
index f1a732f8fac..b6ae49a0e3b 100644
--- a/qa/lib/gitlab/page/admin/dashboard.rb
+++ b/qa/lib/gitlab/page/admin/dashboard.rb
@@ -8,7 +8,6 @@ module Gitlab
h2 :users_in_license
h2 :billable_users
- h3 :number_of_users
end
end
end
diff --git a/qa/lib/gitlab/page/admin/dashboard.stub.rb b/qa/lib/gitlab/page/admin/dashboard.stub.rb
index 820acf79b9b..da717558133 100644
--- a/qa/lib/gitlab/page/admin/dashboard.stub.rb
+++ b/qa/lib/gitlab/page/admin/dashboard.stub.rb
@@ -51,30 +51,6 @@ module Gitlab
def billable_users?
# This is a stub, used for indexing. The method is dynamically generated.
end
-
- # @note Defined as +h3 :number_of_users+
- # @return [String] The text content or value of +number_of_users+
- def number_of_users
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @example
- # Gitlab::Page::Admin::Dashboard.perform do |dashboard|
- # expect(dashboard.number_of_users_element).to exist
- # end
- # @return [Watir::H3] The raw +H3+ element
- def number_of_users_element
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @example
- # Gitlab::Page::Admin::Dashboard.perform do |dashboard|
- # expect(dashboard).to be_number_of_users
- # end
- # @return [Boolean] true if the +number_of_users+ element is present on the page
- def number_of_users?
- # This is a stub, used for indexing. The method is dynamically generated.
- end
end
end
end
diff --git a/qa/lib/gitlab/page/admin/subscription.rb b/qa/lib/gitlab/page/admin/subscription.rb
index 058cf8d281e..e19f0580007 100644
--- a/qa/lib/gitlab/page/admin/subscription.rb
+++ b/qa/lib/gitlab/page/admin/subscription.rb
@@ -12,15 +12,11 @@ module Gitlab
label :terms_of_services, text: /I agree that/
button :remove_license
button :confirm_remove_license
- p :plan
- p :started
- p :name
- p :company
- p :email
- h2 :billable_users
- h2 :maximum_users
+ td :plan
+ td :name
+ td :company
+ td :email
h2 :users_in_subscription
- h2 :users_over_subscription
table :subscription_history
div :no_valid_license_alert, text: /no longer has a valid license/
diff --git a/qa/lib/gitlab/page/admin/subscription.stub.rb b/qa/lib/gitlab/page/admin/subscription.stub.rb
index 56a063e8978..9ed127f9281 100644
--- a/qa/lib/gitlab/page/admin/subscription.stub.rb
+++ b/qa/lib/gitlab/page/admin/subscription.stub.rb
@@ -4,7 +4,7 @@ module Gitlab
module Page
module Admin
module Subscription
- # @note Defined as +h6 :subscription_details+
+ # @note Defined as +div :subscription_details+
# @return [String] The text content or value of +subscription_details+
def subscription_details
# This is a stub, used for indexing. The method is dynamically generated.
@@ -14,7 +14,7 @@ module Gitlab
# Gitlab::Page::Admin::Subscription.perform do |subscription|
# expect(subscription.subscription_details_element).to exist
# end
- # @return [Watir::H6] The raw +H6+ element
+ # @return [Watir::Div] The raw +Div+ element
def subscription_details_element
# This is a stub, used for indexing. The method is dynamically generated.
end
@@ -62,6 +62,30 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
+ # @note Defined as +button :activate+
+ # Clicks +activate+
+ def activate
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Admin::Subscription.perform do |subscription|
+ # expect(subscription.activate_element).to exist
+ # end
+ # @return [Watir::Button] The raw +Button+ element
+ def activate_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Admin::Subscription.perform do |subscription|
+ # expect(subscription).to be_activate
+ # end
+ # @return [Boolean] true if the +activate+ element is present on the page
+ def activate?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
# @note Defined as +label :terms_of_services+
# @return [String] The text content or value of +terms_of_services+
def terms_of_services
@@ -86,79 +110,79 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +button :activate+
- # Clicks +activate+
- def activate
+ # @note Defined as +button :remove_license+
+ # Clicks +remove_license+
+ def remove_license
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.activate_element).to exist
+ # expect(subscription.remove_license_element).to exist
# end
# @return [Watir::Button] The raw +Button+ element
- def activate_element
+ def remove_license_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_activate
+ # expect(subscription).to be_remove_license
# end
- # @return [Boolean] true if the +activate+ element is present on the page
- def activate?
+ # @return [Boolean] true if the +remove_license+ element is present on the page
+ def remove_license?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +p :plan+
- # @return [String] The text content or value of +plan+
- def plan
+ # @note Defined as +button :confirm_remove_license+
+ # Clicks +confirm_remove_license+
+ def confirm_remove_license
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.plan_element).to exist
+ # expect(subscription.confirm_remove_license_element).to exist
# end
- # @return [Watir::P] The raw +P+ element
- def plan_element
+ # @return [Watir::Button] The raw +Button+ element
+ def confirm_remove_license_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_plan
+ # expect(subscription).to be_confirm_remove_license
# end
- # @return [Boolean] true if the +plan+ element is present on the page
- def plan?
+ # @return [Boolean] true if the +confirm_remove_license+ element is present on the page
+ def confirm_remove_license?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +p :started+
- # @return [String] The text content or value of +started+
- def started
+ # @note Defined as +td :plan+
+ # @return [String] The text content or value of +plan+
+ def plan
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.started_element).to exist
+ # expect(subscription.plan_element).to exist
# end
- # @return [Watir::P] The raw +P+ element
- def started_element
+ # @return [Watir::Td] The raw +Td+ element
+ def plan_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_started
+ # expect(subscription).to be_plan
# end
- # @return [Boolean] true if the +started+ element is present on the page
- def started?
+ # @return [Boolean] true if the +plan+ element is present on the page
+ def plan?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +p :name+
+ # @note Defined as +td :name+
# @return [String] The text content or value of +name+
def name
# This is a stub, used for indexing. The method is dynamically generated.
@@ -168,7 +192,7 @@ module Gitlab
# Gitlab::Page::Admin::Subscription.perform do |subscription|
# expect(subscription.name_element).to exist
# end
- # @return [Watir::P] The raw +P+ element
+ # @return [Watir::Td] The raw +Td+ element
def name_element
# This is a stub, used for indexing. The method is dynamically generated.
end
@@ -182,7 +206,7 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +p :company+
+ # @note Defined as +td :company+
# @return [String] The text content or value of +company+
def company
# This is a stub, used for indexing. The method is dynamically generated.
@@ -192,7 +216,7 @@ module Gitlab
# Gitlab::Page::Admin::Subscription.perform do |subscription|
# expect(subscription.company_element).to exist
# end
- # @return [Watir::P] The raw +P+ element
+ # @return [Watir::Td] The raw +Td+ element
def company_element
# This is a stub, used for indexing. The method is dynamically generated.
end
@@ -206,7 +230,7 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +p :email+
+ # @note Defined as +td :email+
# @return [String] The text content or value of +email+
def email
# This is a stub, used for indexing. The method is dynamically generated.
@@ -216,7 +240,7 @@ module Gitlab
# Gitlab::Page::Admin::Subscription.perform do |subscription|
# expect(subscription.email_element).to exist
# end
- # @return [Watir::P] The raw +P+ element
+ # @return [Watir::Td] The raw +Td+ element
def email_element
# This is a stub, used for indexing. The method is dynamically generated.
end
@@ -230,123 +254,99 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +h2 :billable_users+
- # @return [String] The text content or value of +billable_users+
- def billable_users
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @example
- # Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.billable_users_element).to exist
- # end
- # @return [Watir::H2] The raw +H2+ element
- def billable_users_element
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @example
- # Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_billable_users
- # end
- # @return [Boolean] true if the +billable_users+ element is present on the page
- def billable_users?
- # This is a stub, used for indexing. The method is dynamically generated.
- end
-
- # @note Defined as +h2 :maximum_users+
- # @return [String] The text content or value of +maximum_users+
- def maximum_users
+ # @note Defined as +h2 :users_in_subscription+
+ # @return [String] The text content or value of +users_in_subscription+
+ def users_in_subscription
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.maximum_users_element).to exist
+ # expect(subscription.users_in_subscription_element).to exist
# end
# @return [Watir::H2] The raw +H2+ element
- def maximum_users_element
+ def users_in_subscription_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_maximum_users
+ # expect(subscription).to be_users_in_subscription
# end
- # @return [Boolean] true if the +maximum_users+ element is present on the page
- def maximum_users?
+ # @return [Boolean] true if the +users_in_subscription+ element is present on the page
+ def users_in_subscription?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +h2 :users_in_subscription+
- # @return [String] The text content or value of +users_in_subscription+
- def users_in_subscription
+ # @note Defined as +table :subscription_history+
+ # @return [String] The text content or value of +subscription_history+
+ def subscription_history
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.users_in_subscription_element).to exist
+ # expect(subscription.subscription_history_element).to exist
# end
- # @return [Watir::H2] The raw +H2+ element
- def users_in_subscription_element
+ # @return [Watir::Table] The raw +Table+ element
+ def subscription_history_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_users_in_subscription
+ # expect(subscription).to be_subscription_history
# end
- # @return [Boolean] true if the +users_in_subscription+ element is present on the page
- def users_in_subscription?
+ # @return [Boolean] true if the +subscription_history+ element is present on the page
+ def subscription_history?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +h2 :users_over_subscription+
- # @return [String] The text content or value of +users_over_subscription+
- def users_over_subscription
+ # @note Defined as +div :no_valid_license_alert+
+ # @return [String] The text content or value of +no_valid_license_alert+
+ def no_valid_license_alert
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.users_over_subscription_element).to exist
+ # expect(subscription.no_valid_license_alert_element).to exist
# end
- # @return [Watir::H2] The raw +H2+ element
- def users_over_subscription_element
+ # @return [Watir::Div] The raw +Div+ element
+ def no_valid_license_alert_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_users_over_subscription
+ # expect(subscription).to be_no_valid_license_alert
# end
- # @return [Boolean] true if the +users_over_subscription+ element is present on the page
- def users_over_subscription?
+ # @return [Boolean] true if the +no_valid_license_alert+ element is present on the page
+ def no_valid_license_alert?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +table :subscription_history+
- # @return [String] The text content or value of +subscription_history+
- def subscription_history
+ # @note Defined as +h3 :no_active_subscription_title+
+ # @return [String] The text content or value of +no_active_subscription_title+
+ def no_active_subscription_title
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription.subscription_history_element).to exist
+ # expect(subscription.no_active_subscription_title_element).to exist
# end
- # @return [Watir::Table] The raw +Table+ element
- def subscription_history_element
+ # @return [Watir::H3] The raw +H3+ element
+ def no_active_subscription_title_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Admin::Subscription.perform do |subscription|
- # expect(subscription).to be_subscription_history
+ # expect(subscription).to be_no_active_subscription_title
# end
- # @return [Boolean] true if the +subscription_history+ element is present on the page
- def subscription_history?
+ # @return [Boolean] true if the +no_active_subscription_title+ element is present on the page
+ def no_active_subscription_title?
# This is a stub, used for indexing. The method is dynamically generated.
end
end
diff --git a/qa/lib/gitlab/page/group/settings/usage_quotas.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.rb
index 11d1dd78dbe..cdb0760ad9c 100644
--- a/qa/lib/gitlab/page/group/settings/usage_quotas.rb
+++ b/qa/lib/gitlab/page/group/settings/usage_quotas.rb
@@ -35,6 +35,13 @@ module Gitlab
span :container_registry_size
div :storage_purchased, 'data-testid': 'storage-purchased'
div :storage_purchase_successful_alert, text: /You have successfully purchased a storage/
+ span :project_repository_size
+ span :project_lfs_object_size
+ span :project_build_artifact_size
+ span :project_packages_size
+ span :project_wiki_size
+ span :project_snippets_size
+ span :project_containers_registry_size
# Pending members
div :pending_members
diff --git a/qa/lib/gitlab/page/trials/new.rb b/qa/lib/gitlab/page/trials/new.rb
index b2e6cbdb682..f7aa168e6bf 100644
--- a/qa/lib/gitlab/page/trials/new.rb
+++ b/qa/lib/gitlab/page/trials/new.rb
@@ -9,8 +9,8 @@ module Gitlab
text_field :first_name
text_field :last_name
text_field :company_name
- select :number_of_employees
- text_field :telephone_number
+ select :company_size
+ text_field :phone_number
select :country
select :state
button :continue
diff --git a/qa/lib/gitlab/page/trials/new.stub.rb b/qa/lib/gitlab/page/trials/new.stub.rb
new file mode 100644
index 00000000000..0b3dbaafacc
--- /dev/null
+++ b/qa/lib/gitlab/page/trials/new.stub.rb
@@ -0,0 +1,241 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Page
+ module Trials
+ module New
+ # @note Defined as +text_field :first_name+
+ # @return [String] The text content or value of +first_name+
+ def first_name
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # Set the value of first_name
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # new.first_name = 'value'
+ # end
+ # @param value [String] The value to set.
+ def first_name=(value)
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.first_name_element).to exist
+ # end
+ # @return [Watir::TextField] The raw +TextField+ element
+ def first_name_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_first_name
+ # end
+ # @return [Boolean] true if the +first_name+ element is present on the page
+ def first_name?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +text_field :last_name+
+ # @return [String] The text content or value of +last_name+
+ def last_name
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # Set the value of last_name
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # new.last_name = 'value'
+ # end
+ # @param value [String] The value to set.
+ def last_name=(value)
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.last_name_element).to exist
+ # end
+ # @return [Watir::TextField] The raw +TextField+ element
+ def last_name_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_last_name
+ # end
+ # @return [Boolean] true if the +last_name+ element is present on the page
+ def last_name?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +text_field :company_name+
+ # @return [String] The text content or value of +company_name+
+ def company_name
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # Set the value of company_name
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # new.company_name = 'value'
+ # end
+ # @param value [String] The value to set.
+ def company_name=(value)
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.company_name_element).to exist
+ # end
+ # @return [Watir::TextField] The raw +TextField+ element
+ def company_name_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_company_name
+ # end
+ # @return [Boolean] true if the +company_name+ element is present on the page
+ def company_name?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +select :company_size+
+ # @return [String] The text content or value of +company_size+
+ def company_size
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.company_size_element).to exist
+ # end
+ # @return [Watir::Select] The raw +Select+ element
+ def company_size_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_company_size
+ # end
+ # @return [Boolean] true if the +company_size+ element is present on the page
+ def company_size?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +text_field :phone_number+
+ # @return [String] The text content or value of +phone_number+
+ def phone_number
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # Set the value of phone_number
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # new.phone_number = 'value'
+ # end
+ # @param value [String] The value to set.
+ def phone_number=(value)
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.phone_number_element).to exist
+ # end
+ # @return [Watir::TextField] The raw +TextField+ element
+ def phone_number_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_phone_number
+ # end
+ # @return [Boolean] true if the +phone_number+ element is present on the page
+ def phone_number?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +select :country+
+ # @return [String] The text content or value of +country+
+ def country
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.country_element).to exist
+ # end
+ # @return [Watir::Select] The raw +Select+ element
+ def country_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_country
+ # end
+ # @return [Boolean] true if the +country+ element is present on the page
+ def country?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +select :state+
+ # @return [String] The text content or value of +state+
+ def state
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.state_element).to exist
+ # end
+ # @return [Watir::Select] The raw +Select+ element
+ def state_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_state
+ # end
+ # @return [Boolean] true if the +state+ element is present on the page
+ def state?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +button :continue+
+ # Clicks +continue+
+ def continue
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new.continue_element).to exist
+ # end
+ # @return [Watir::Button] The raw +Button+ element
+ def continue_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::New.perform do |new|
+ # expect(new).to be_continue
+ # end
+ # @return [Boolean] true if the +continue+ element is present on the page
+ def continue?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+ end
+ end
+ end
+end
diff --git a/qa/lib/gitlab/page/trials/select.rb b/qa/lib/gitlab/page/trials/select.rb
index d4cf54805ea..ae807f99c25 100644
--- a/qa/lib/gitlab/page/trials/select.rb
+++ b/qa/lib/gitlab/page/trials/select.rb
@@ -8,7 +8,6 @@ module Gitlab
button :select_group, 'data-testid': 'base-dropdown-toggle'
div :group_dropdown, 'data-testid': 'base-dropdown-menu'
- text_field :new_group_name
button :start_your_free_trial
radio :trial_company
radio :trial_individual
diff --git a/qa/lib/gitlab/page/trials/select.stub.rb b/qa/lib/gitlab/page/trials/select.stub.rb
new file mode 100644
index 00000000000..0c61a58d35c
--- /dev/null
+++ b/qa/lib/gitlab/page/trials/select.stub.rb
@@ -0,0 +1,129 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Page
+ module Trials
+ module Select
+ # @note Defined as +button :select_group+
+ # Clicks +select_group+
+ def select_group
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select.select_group_element).to exist
+ # end
+ # @return [Watir::Button] The raw +Button+ element
+ def select_group_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select).to be_select_group
+ # end
+ # @return [Boolean] true if the +select_group+ element is present on the page
+ def select_group?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :group_dropdown+
+ # @return [String] The text content or value of +group_dropdown+
+ def group_dropdown
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select.group_dropdown_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def group_dropdown_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select).to be_group_dropdown
+ # end
+ # @return [Boolean] true if the +group_dropdown+ element is present on the page
+ def group_dropdown?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +button :start_your_free_trial+
+ # Clicks +start_your_free_trial+
+ def start_your_free_trial
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select.start_your_free_trial_element).to exist
+ # end
+ # @return [Watir::Button] The raw +Button+ element
+ def start_your_free_trial_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select).to be_start_your_free_trial
+ # end
+ # @return [Boolean] true if the +start_your_free_trial+ element is present on the page
+ def start_your_free_trial?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +radio :trial_company+
+ # Clicks +trial_company+
+ def trial_company
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select.trial_company_element).to exist
+ # end
+ # @return [Watir::Radio] The raw +Radio+ element
+ def trial_company_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select).to be_trial_company
+ # end
+ # @return [Boolean] true if the +trial_company+ element is present on the page
+ def trial_company?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +radio :trial_individual+
+ # Clicks +trial_individual+
+ def trial_individual
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select.trial_individual_element).to exist
+ # end
+ # @return [Watir::Radio] The raw +Radio+ element
+ def trial_individual_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Trials::Select.perform do |select|
+ # expect(select).to be_trial_individual
+ # end
+ # @return [Boolean] true if the +trial_individual+ element is present on the page
+ def trial_individual?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa.rb b/qa/qa.rb
index 0e3d343b861..f0eb7deb205 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -18,6 +18,7 @@ require 'rainbow/refinement'
require 'active_support/core_ext/hash'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/module/delegation'
+require 'active_support/parameter_filter'
module QA
root = "#{__dir__}/qa"
@@ -29,6 +30,7 @@ module QA
loader.push_dir(root, namespace: QA)
+ loader.ignore("#{root}/factories")
loader.ignore("#{root}/specs/features")
loader.ignore("#{root}/specs/spec_helper.rb")
diff --git a/qa/qa/factories/_shared.rb b/qa/qa/factories/_shared.rb
new file mode 100644
index 00000000000..0fd38faa7dd
--- /dev/null
+++ b/qa/qa/factories/_shared.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module QA
+ FactoryBot.define do
+ to_create(&:fabricate_via_api!)
+ end
+end
diff --git a/qa/qa/factories/groups.rb b/qa/qa/factories/groups.rb
new file mode 100644
index 00000000000..7daa365bfca
--- /dev/null
+++ b/qa/qa/factories/groups.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module QA
+ FactoryBot.define do
+ factory :group_base, class: 'QA::Resource::GroupBase' do
+ trait :private do
+ visibility { :private }
+ end
+
+ trait :require_2fa do
+ require_two_factor_authentication { true }
+ end
+
+ factory :sandbox, class: 'QA::Resource::Sandbox'
+ factory :group, class: 'QA::Resource::Group'
+ end
+ end
+end
diff --git a/qa/qa/factories/issues.rb b/qa/qa/factories/issues.rb
new file mode 100644
index 00000000000..2931a41e347
--- /dev/null
+++ b/qa/qa/factories/issues.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module QA
+ FactoryBot.define do
+ # https://docs.gitlab.com/ee/api/issues.html
+ factory :issue, class: 'QA::Resource::Issue' do
+ title { Faker::Lorem.sentence }
+ description { Faker::Lorem.paragraph }
+
+ confidential { false }
+
+ trait :confidential do
+ confidential { true }
+ end
+ end
+ end
+end
diff --git a/qa/qa/factories/projects.rb b/qa/qa/factories/projects.rb
new file mode 100644
index 00000000000..69eefe12129
--- /dev/null
+++ b/qa/qa/factories/projects.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module QA
+ FactoryBot.define do
+ # https://docs.gitlab.com/ee/api/projects.html
+ factory :project, class: 'QA::Resource::Project' do
+ trait :private do
+ visibility { 'private' }
+ end
+
+ trait :with_readme do
+ initialize_with_readme { true }
+ end
+
+ trait :auto_devops do
+ auto_devops_enabled { true }
+ end
+ end
+ end
+end
diff --git a/qa/qa/fixtures/package_managers/composer/composer_upload_package.yaml.erb b/qa/qa/fixtures/package_managers/composer/composer_upload_package.yaml.erb
index b6bcfafffee..5ebb2a0d8f3 100644
--- a/qa/qa/fixtures/package_managers/composer/composer_upload_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/composer/composer_upload_package.yaml.erb
@@ -2,7 +2,7 @@ publish:
image: curlimages/curl:latest
stage: build
variables:
- URL: "$CI_SERVER_PROTOCOL://$CI_SERVER_HOST:$CI_SERVER_PORT/api/v4/projects/$CI_PROJECT_ID/packages/composer?job_token=$CI_JOB_TOKEN"
+ URL: "<%= gitlab_host_with_port %>/api/v4/projects/$CI_PROJECT_ID/packages/composer?job_token=$CI_JOB_TOKEN"
script:
- version=$([[ -z "$CI_COMMIT_TAG" ]] && echo "branch=$CI_COMMIT_REF_NAME" || echo "tag=$CI_COMMIT_TAG")
- insecure=$([ "$CI_SERVER_PROTOCOL" = "http" ] && echo "--insecure" || echo "")
diff --git a/qa/qa/fixtures/package_managers/npm/npm_install_package_group.yaml.erb b/qa/qa/fixtures/package_managers/npm/npm_install_package_group.yaml.erb
index a5ec4f298e2..2b6cb60df21 100644
--- a/qa/qa/fixtures/package_managers/npm/npm_install_package_group.yaml.erb
+++ b/qa/qa/fixtures/package_managers/npm/npm_install_package_group.yaml.erb
@@ -6,7 +6,7 @@ stages:
install:
stage: install
script:
- - "npm config set @<%= registry_scope %>:registry <%= gitlab_address_with_port %>/api/v4/groups/<%= another_project.group.id %>/-/packages/npm/"
+ - "npm config set @<%= registry_scope %>:registry <%= gitlab_address_without_port %>/api/v4/groups/<%= another_project.group.id %>/-/packages/npm/"
- "npm install <%= package.name %>"
cache:
key: ${CI_COMMIT_REF_NAME}
diff --git a/qa/qa/fixtures/package_managers/npm/npm_install_package_instance.yaml.erb b/qa/qa/fixtures/package_managers/npm/npm_install_package_instance.yaml.erb
index 07f426c3bfa..92411593620 100644
--- a/qa/qa/fixtures/package_managers/npm/npm_install_package_instance.yaml.erb
+++ b/qa/qa/fixtures/package_managers/npm/npm_install_package_instance.yaml.erb
@@ -6,7 +6,7 @@ stages:
install:
stage: install
script:
- - "npm config set @<%= registry_scope %>:registry <%= gitlab_address_with_port %>/api/v4/packages/npm/"
+ - "npm config set @<%= registry_scope %>:registry <%= gitlab_address_without_port %>/api/v4/packages/npm/"
- "npm install <%= package.name %>"
cache:
key: ${CI_COMMIT_REF_NAME}
diff --git a/qa/qa/fixtures/package_managers/npm/npm_upload_install_package_project.yaml.erb b/qa/qa/fixtures/package_managers/npm/npm_upload_install_package_project.yaml.erb
index b5277a2c315..6fb86845bb5 100644
--- a/qa/qa/fixtures/package_managers/npm/npm_upload_install_package_project.yaml.erb
+++ b/qa/qa/fixtures/package_managers/npm/npm_upload_install_package_project.yaml.erb
@@ -7,7 +7,7 @@ stages:
deploy:
stage: deploy
script:
- - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
+ - echo "//<%= gitlab_host_without_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
- npm publish
only:
- "<%= project.default_branch %>"
@@ -16,8 +16,8 @@ deploy:
install:
stage: install
script:
- - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
- - "npm config set @<%= registry_scope %>:registry <%= gitlab_address_with_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/npm/"
+ - echo "//<%= gitlab_host_without_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
+ - "npm config set @<%= registry_scope %>:registry <%= gitlab_address_without_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/npm/"
- "npm install <%= package.name %>"
cache:
key: ${CI_COMMIT_REF_NAME}
diff --git a/qa/qa/fixtures/package_managers/npm/npm_upload_package_group.yaml.erb b/qa/qa/fixtures/package_managers/npm/npm_upload_package_group.yaml.erb
index 13c00cd17c4..8e81953ad19 100644
--- a/qa/qa/fixtures/package_managers/npm/npm_upload_package_group.yaml.erb
+++ b/qa/qa/fixtures/package_managers/npm/npm_upload_package_group.yaml.erb
@@ -6,7 +6,7 @@ stages:
deploy:
stage: deploy
script:
- - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
+ - echo "//<%= gitlab_host_without_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
- npm publish
only:
- "<%= project.default_branch %>"
diff --git a/qa/qa/fixtures/package_managers/npm/npm_upload_package_instance.yaml.erb b/qa/qa/fixtures/package_managers/npm/npm_upload_package_instance.yaml.erb
index 13c00cd17c4..8e81953ad19 100644
--- a/qa/qa/fixtures/package_managers/npm/npm_upload_package_instance.yaml.erb
+++ b/qa/qa/fixtures/package_managers/npm/npm_upload_package_instance.yaml.erb
@@ -6,7 +6,7 @@ stages:
deploy:
stage: deploy
script:
- - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
+ - echo "//<%= gitlab_host_without_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=<%= auth_token %>">.npmrc
- npm publish
only:
- "<%= project.default_branch %>"
diff --git a/qa/qa/fixtures/package_managers/npm/package.json.erb b/qa/qa/fixtures/package_managers/npm/package.json.erb
index 46fecf97e2c..68539da02bc 100644
--- a/qa/qa/fixtures/package_managers/npm/package.json.erb
+++ b/qa/qa/fixtures/package_managers/npm/package.json.erb
@@ -3,6 +3,6 @@
"version": "1.0.0",
"description": "Example package for GitLab npm registry",
"publishConfig": {
- "@<%= registry_scope %>:registry": "<%= gitlab_address_with_port %>/api/v4/projects/<%= project.id %>/packages/npm/"
+ "@<%= registry_scope %>:registry": "<%= gitlab_address_without_port %>/api/v4/projects/<%= project.id %>/packages/npm/"
}
} \ No newline at end of file
diff --git a/qa/qa/flow/trial.rb b/qa/qa/flow/trial.rb
index 109afeffaa3..9bab98bf027 100644
--- a/qa/qa/flow/trial.rb
+++ b/qa/qa/flow/trial.rb
@@ -7,8 +7,8 @@ module QA
CUSTOMER_TRIAL_INFO = {
company_name: 'QA Test Company',
- number_of_employees: '500 - 1,999',
- telephone_number: '555-555-5555',
+ company_size: '500 - 1,999',
+ phone_number: '555-555-5555',
country: 'United States of America',
state: 'CA'
}.freeze
@@ -16,9 +16,9 @@ module QA
def register_for_trial(group: nil)
Gitlab::Page::Trials::New.perform do |new|
new.company_name = CUSTOMER_TRIAL_INFO[:company_name]
- new.number_of_employees = CUSTOMER_TRIAL_INFO[:number_of_employees]
+ new.company_size = CUSTOMER_TRIAL_INFO[:company_size]
new.country = CUSTOMER_TRIAL_INFO[:country]
- new.telephone_number = CUSTOMER_TRIAL_INFO[:telephone_number]
+ new.phone_number = CUSTOMER_TRIAL_INFO[:phone_number]
new.state = CUSTOMER_TRIAL_INFO[:state]
new.continue
diff --git a/qa/qa/page/admin/menu.rb b/qa/qa/page/admin/menu.rb
index f58d672efe8..3b044f8a051 100644
--- a/qa/qa/page/admin/menu.rb
+++ b/qa/qa/page/admin/menu.rb
@@ -67,6 +67,12 @@ module QA
click_element :admin_overview_groups_link
end
+ def go_to_security_and_compliance
+ hover_element(:admin_settings_menu_link) do
+ click_element :admin_security_and_compliance_link
+ end
+ end
+
def go_to_applications
return click_element(:nav_item_link, submenu_item: 'Applications') if Runtime::Env.super_sidebar_enabled?
diff --git a/qa/qa/page/admin/overview/users/index.rb b/qa/qa/page/admin/overview/users/index.rb
index f46ae30498c..6f1134b751a 100644
--- a/qa/qa/page/admin/overview/users/index.rb
+++ b/qa/qa/page/admin/overview/users/index.rb
@@ -12,7 +12,7 @@ module QA
end
view 'app/assets/javascripts/admin/users/components/users_table.vue' do
- element :user_row_content
+ element 'user-row-content'
end
def search_user(username)
@@ -24,13 +24,13 @@ module QA
end
def click_user(username)
- within_element(:user_row_content, text: username) do
+ within_element('user-row-content', text: username) do
click_link(username)
end
end
def has_username?(username)
- has_element?(:user_row_content, text: username, wait: 1)
+ has_element?('user-row-content', text: username, wait: 1)
end
end
end
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 92b4fd39759..1961e522b89 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -165,7 +165,7 @@ module QA
raise ArgumentError, "Please use :minimum, :maximum, :count, or :between so that all is more reliable"
end
- wait_for_requests
+ wait_for_requests(skip_finished_loading_check: !!kwargs.delete(:skip_finished_loading_check))
all(element_selector_css(name), **kwargs)
end
@@ -243,7 +243,20 @@ module QA
wait = kwargs.delete(:wait) || Capybara.default_max_wait_time
text = kwargs.delete(:text)
- find(element_selector_css(name, kwargs), text: text, wait: wait).click
+ begin
+ find(element_selector_css(name, kwargs), text: text, wait: wait).click
+ rescue Net::ReadTimeout => error
+ # In some situations due to perhaps a slow environment we can encounter errors
+ # where clicks are registered, but the calls to selenium-webdriver result in
+ # timeout errors. In these cases rescue from the error and attempt to continue in
+ # the test to avoid a flaky test failure. This should be safe as assertions in the
+ # tests will catch any case where the click wasn't actually registered.
+ QA::Runtime::Logger.warn "click_element -- #{error} -- #{error.backtrace.inspect}"
+ # There may be a 5xx error -- lets refresh the page like the warning page suggests
+ # and it if resolves itself we can avoid a flaky failure
+ refresh
+ end
+
page.validate_elements_present! if page
end
@@ -381,7 +394,7 @@ module QA
end
def within_element(name, **kwargs, &block)
- wait_for_requests(skip_finished_loading_check: kwargs.delete(:skip_finished_loading_check))
+ wait_for_requests(skip_finished_loading_check: !!kwargs.delete(:skip_finished_loading_check))
text = kwargs.delete(:text)
page.within(element_selector_css(name, kwargs), text: text, &block)
diff --git a/qa/qa/page/component/access_tokens.rb b/qa/qa/page/component/access_tokens.rb
index 586f69b8a64..6d7c36065ef 100644
--- a/qa/qa/page/component/access_tokens.rb
+++ b/qa/qa/page/component/access_tokens.rb
@@ -39,6 +39,26 @@ module QA
base.view 'app/assets/javascripts/access_tokens/components/access_token_table_app.vue' do
element :revoke_button
end
+
+ base.view 'app/views/profiles/personal_access_tokens/index.html.haml' do
+ element 'add-new-token-button'
+ end
+
+ base.view 'app/views/projects/settings/access_tokens/index.html.haml' do
+ element 'add-new-token-button'
+ end
+
+ base.view 'app/views/groups/settings/access_tokens/index.html.haml' do
+ element 'add-new-token-button'
+ end
+
+ base.view 'app/views/admin/impersonation_tokens/index.html.haml' do
+ element 'add-new-token-button'
+ end
+ end
+
+ def click_add_new_token_button
+ click_element('add-new-token-button')
end
def fill_token_name(name)
diff --git a/qa/qa/page/component/badges.rb b/qa/qa/page/component/badges.rb
index f2c5f809d8d..9d2959c010e 100644
--- a/qa/qa/page/component/badges.rb
+++ b/qa/qa/page/component/badges.rb
@@ -4,6 +4,10 @@ module QA
module Page
module Component
class Badges < Page::Base
+ view 'app/assets/javascripts/badges/components/badge_settings.vue' do
+ element 'show-badge-add-form'
+ end
+
view 'app/assets/javascripts/badges/components/badge_form.vue' do
element :badge_name_field
element :badge_link_url_field
@@ -13,13 +17,17 @@ module QA
view 'app/assets/javascripts/badges/components/badge_list.vue' do
element :badge_list_content
- element :badge_list_row
+ element :badge_list
end
view 'app/assets/javascripts/badges/components/badge.vue' do
element :badge_image_link
end
+ def show_badge_add_form
+ click_element 'show-badge-add-form'
+ end
+
def fill_name(name)
fill_element :badge_name_field, name
end
@@ -38,7 +46,7 @@ module QA
def has_badge?(badge_name)
within_element(:badge_list_content) do
- has_element?(:badge_list_row, badge_name: badge_name)
+ has_element?(:badge_list, text: badge_name)
end
end
diff --git a/qa/qa/page/component/confirm_modal.rb b/qa/qa/page/component/confirm_modal.rb
index f72ca4f068e..26d06ecaa22 100644
--- a/qa/qa/page/component/confirm_modal.rb
+++ b/qa/qa/page/component/confirm_modal.rb
@@ -10,8 +10,8 @@ module QA
super
base.view 'app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue' do
- element :confirm_ok_button
- element :confirmation_modal
+ element 'confirm-ok-button'
+ element 'confirmation-modal'
end
base.view 'app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue' do
@@ -36,7 +36,7 @@ module QA
end
def click_confirmation_ok_button
- click_element(:confirm_ok_button)
+ click_element('confirm-ok-button')
end
# Click the confirmation button if the confirmation modal is present
@@ -48,9 +48,9 @@ module QA
# to skip the loading check otherwise it will time out.
#
# [1]: https://gitlab.com/gitlab-org/gitlab/-/blob/4a99af809b86047ce3c8985e6582748bbd23fc84/qa/qa/page/component/members/members_table.rb#L54
- return unless has_element?(:confirmation_modal, skip_finished_loading_check: true)
+ return unless has_element?('confirmation-modal', skip_finished_loading_check: true)
- click_element(:confirm_ok_button, skip_finished_loading_check: true)
+ click_element('confirm-ok-button', skip_finished_loading_check: true)
end
end
end
diff --git a/qa/qa/page/component/delete_modal.rb b/qa/qa/page/component/delete_modal.rb
index 18bb2b1bb1b..9fbbd9930a9 100644
--- a/qa/qa/page/component/delete_modal.rb
+++ b/qa/qa/page/component/delete_modal.rb
@@ -9,7 +9,7 @@ module QA
def self.included(base)
super
- base.view 'app/assets/javascripts/projects/components/shared/delete_button.vue' do
+ base.view 'app/assets/javascripts/projects/components/shared/delete_modal.vue' do
element :confirm_name_field
element :confirm_delete_button
end
diff --git a/qa/qa/page/component/issuable/common.rb b/qa/qa/page/component/issuable/common.rb
index 2f116822a12..526f8763488 100644
--- a/qa/qa/page/component/issuable/common.rb
+++ b/qa/qa/page/component/issuable/common.rb
@@ -11,7 +11,7 @@ module QA
super
base.view 'app/assets/javascripts/issues/show/components/title.vue' do
- element :issue_title, required: true
+ element 'issue-title', required: true
end
end
end
diff --git a/qa/qa/page/component/issuable/sidebar.rb b/qa/qa/page/component/issuable/sidebar.rb
index 15155fd9f44..680f1d41a5e 100644
--- a/qa/qa/page/component/issuable/sidebar.rb
+++ b/qa/qa/page/component/issuable/sidebar.rb
@@ -31,7 +31,7 @@ module QA
end
base.view 'app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents.vue' do
- element :labels_select_dropdown_contents
+ element 'labels-select-dropdown-contents'
end
base.view 'app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_value.vue' do
@@ -49,7 +49,7 @@ module QA
end
base.view 'app/assets/javascripts/sidebar/components/sidebar_editable_item.vue' do
- element :edit_button
+ element 'edit-button'
end
base.view 'app/helpers/dropdowns_helper.rb' do
@@ -59,7 +59,7 @@ module QA
def assign_milestone(milestone)
wait_milestone_block_finish_loading do
- click_element(:edit_button)
+ click_element('edit-button')
click_on(milestone.title)
end
@@ -134,17 +134,17 @@ module QA
def select_labels(labels)
within_element(:labels_block) do
- click_element(:edit_button)
+ click_element('edit-button')
labels.each do |label|
- within_element(:labels_select_dropdown_contents) do
+ within_element('labels-select-dropdown-contents') do
fill_element(:dropdown_input_field, label)
click_button(text: label)
end
end
end
- click_element(:issue_title) # to blur dropdown
+ click_element('issue-title') # to blur dropdown
end
def toggle_more_assignees_link
diff --git a/qa/qa/page/component/listbox_filter.rb b/qa/qa/page/component/listbox_filter.rb
new file mode 100644
index 00000000000..b8ddab23819
--- /dev/null
+++ b/qa/qa/page/component/listbox_filter.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Component
+ module ListboxFilter
+ def filter_and_select(item)
+ page.has_css?('.gl-listbox-search-input', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
+
+ find('.gl-listbox-search-input').set(item)
+ find('.gl-new-dropdown-item', text: item, exact_text: true).click
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/component/members/invite_members_modal.rb b/qa/qa/page/component/members/invite_members_modal.rb
index ae51213b3e2..876c5ba65b6 100644
--- a/qa/qa/page/component/members/invite_members_modal.rb
+++ b/qa/qa/page/component/members/invite_members_modal.rb
@@ -59,6 +59,10 @@ module QA
Support::WaitForRequests.wait_for_requests
+ # Needed as a workaround to help avoid race condition with initial search request
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/349379
+ sleep 2
+
search_and_select(group_name)
set_access_level(access_level)
diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb
index 638c46f228f..6bb83d8b7e8 100644
--- a/qa/qa/page/component/note.rb
+++ b/qa/qa/page/component/note.rb
@@ -171,7 +171,7 @@ module QA
def select_filter_with_text(text)
retry_on_exception do
- click_element(:issue_title)
+ click_element('issue-title')
click_element :discussion_preferences_dropdown
find_element(:filter_menu_item, text: text).click
diff --git a/qa/qa/page/component/project/templates.rb b/qa/qa/page/component/project/templates.rb
index 6e86455fc52..0812c162914 100644
--- a/qa/qa/page/component/project/templates.rb
+++ b/qa/qa/page/component/project/templates.rb
@@ -5,8 +5,8 @@ module QA
module Project
module Templates
def use_template_for_project(project_name)
- within find_element(:template_option_container, text: project_name) do
- click_element :use_template_button
+ within find_element('template-option-container', text: project_name) do
+ click_element 'use-template-button'
end
end
end
diff --git a/qa/qa/page/component/rich_text_popover.rb b/qa/qa/page/component/rich_text_popover.rb
index 6a187dcedc5..f5b0c668fb1 100644
--- a/qa/qa/page/component/rich_text_popover.rb
+++ b/qa/qa/page/component/rich_text_popover.rb
@@ -10,7 +10,7 @@ module QA
super
base.view 'app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue' do
- element :rich_text_promo_popover
+ element 'rich-text-promo-popover'
end
base.view 'app/views/shared/_broadcast_message.html.haml' do
@@ -19,11 +19,12 @@ module QA
end
def close_rich_text_promo_popover_if_present
- return unless has_element?(:rich_text_promo_popover, wait: 0)
+ return unless has_element?('rich-text-promo-popover', wait: 0)
- within_element(:rich_text_promo_popover) do
- click_element(:close_button)
+ within_element('rich-text-promo-popover') do
+ click_element('close-button')
end
+ has_no_element?('rich-text-promo-popover')
end
end
end
diff --git a/qa/qa/page/dashboard/groups.rb b/qa/qa/page/dashboard/groups.rb
index 644d19d6bcb..5fa27f453ea 100644
--- a/qa/qa/page/dashboard/groups.rb
+++ b/qa/qa/page/dashboard/groups.rb
@@ -7,7 +7,7 @@ module QA
include Page::Component::GroupsFilter
view 'app/views/dashboard/_groups_head.html.haml' do
- element :new_group_button
+ element 'new-group-button'
end
def has_group?(name)
@@ -21,7 +21,7 @@ module QA
end
def click_new_group
- click_element(:new_group_button)
+ click_element('new-group-button')
end
end
end
diff --git a/qa/qa/page/element.rb b/qa/qa/page/element.rb
index f0e67627dca..ec8aca76250 100644
--- a/qa/qa/page/element.rb
+++ b/qa/qa/page/element.rb
@@ -12,49 +12,39 @@ module QA
def initialize(name, *options)
@name = name
@attributes = options.extract_options!
- @attributes[:pattern] ||= selector
options.each do |option|
@attributes[:pattern] = option if option.is_a?(String) || option.is_a?(Regexp)
end
end
- def selector
- "qa-#{@name.to_s.tr('_', '-')}"
- end
-
def required?
!!@attributes[:required]
end
def selector_css
- %(#{qa_selector}#{additional_selectors},.#{selector})
+ [
+ %([data-testid="#{name}"]#{additional_selectors}),
+ %([data-qa-selector="#{name}"]#{additional_selectors})
+ ].join(',')
end
- def expression
- if @attributes[:pattern].is_a?(String)
- @_regexp ||= Regexp.new(Regexp.escape(@attributes[:pattern]))
+ def matches?(line)
+ if expression
+ !!(line =~ /["']#{name}['"]|#{expression}/)
else
- @attributes[:pattern]
+ !!(line =~ /["']#{name}['"]/)
end
end
- def matches?(line)
- !!(line =~ /["']#{name}['"]|["']#{convert_to_kebabcase(name)}['"]|#{expression}/)
- end
-
private
- def convert_to_kebabcase(text)
- text.to_s.tr('_', '-')
- end
-
- def qa_selector
- [
- %([data-testid="#{name}"]#{additional_selectors}),
- %([data-testid="#{convert_to_kebabcase(name)}"]#{additional_selectors}),
- %([data-qa-selector="#{name}"]#{additional_selectors})
- ].join(',')
+ def expression
+ if @attributes[:pattern].is_a?(String)
+ @_regexp ||= Regexp.new(Regexp.escape(@attributes[:pattern]))
+ else
+ @attributes[:pattern]
+ end
end
def additional_selectors
diff --git a/qa/qa/page/file/form.rb b/qa/qa/page/file/form.rb
index 06b75f42e4d..cfc689daa32 100644
--- a/qa/qa/page/file/form.rb
+++ b/qa/qa/page/file/form.rb
@@ -4,7 +4,7 @@ module QA
module Page
module File
class Form < Page::Base
- include Page::Component::DropdownFilter
+ include Page::Component::ListboxFilter
include Page::Component::BlobContent
include Shared::CommitMessage
include Shared::CommitButton
@@ -14,11 +14,8 @@ module QA
element :file_name_field
end
- view 'app/views/projects/blob/_template_selectors.html.haml' do
- element :gitignore_dropdown
- element :gitlab_ci_yml_dropdown
- element :dockerfile_dropdown
- element :license_dropdown
+ view 'app/assets/javascripts/blob/filepath_form/components/template_selector.vue' do
+ element :template_selector
end
def add_name(name)
@@ -37,14 +34,8 @@ module QA
def select_template(template_type, template)
case template_type
- when '.gitignore'
- click_element :gitignore_dropdown
- when '.gitlab-ci.yml'
- click_element :gitlab_ci_yml_dropdown
- when 'Dockerfile'
- click_element :dockerfile_dropdown
- when 'LICENSE'
- click_element :license_dropdown
+ when '.gitignore', '.gitlab-ci.yml', 'Dockerfile', 'LICENSE'
+ click_element :template_selector
else
raise %(Unsupported template_type "#{template_type}". Please confirm that it is a valid option.)
end
diff --git a/qa/qa/page/file/show.rb b/qa/qa/page/file/show.rb
index 173baa21160..284fab58d5d 100644
--- a/qa/qa/page/file/show.rb
+++ b/qa/qa/page/file/show.rb
@@ -12,7 +12,7 @@ module QA
element :lock_button
end
- view 'app/assets/javascripts/vue_shared/components/actions_button.vue' do
+ view 'app/assets/javascripts/vue_shared/components/web_ide_link.vue' do
element :action_dropdown
element :edit_menu_item, ':data-qa-selector="`${action.key}_menu_item`"' # rubocop:disable QA/ElementWithPattern
element :webide_menu_item, ':data-qa-selector="`${action.key}_menu_item`"' # rubocop:disable QA/ElementWithPattern
diff --git a/qa/qa/page/group/bulk_import.rb b/qa/qa/page/group/bulk_import.rb
index f57b76b11a9..9fb262c27c3 100644
--- a/qa/qa/page/group/bulk_import.rb
+++ b/qa/qa/page/group/bulk_import.rb
@@ -8,7 +8,7 @@ module QA
element :import_table
element :import_item
element :import_status_indicator
- element :filter_groups
+ element 'filter-groups'
end
view "app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue" do
@@ -20,7 +20,7 @@ module QA
end
view "app/assets/javascripts/import_entities/import_groups/components/import_actions_cell.vue" do
- element :import_group_button
+ element 'import-group-button'
end
def filter_group(source_group_name)
@@ -44,7 +44,7 @@ module QA
click_element(:target_group_dropdown_item, group_name: target_group_name)
retry_until(message: "Triggering import") do
- click_element(:import_group_button)
+ click_element('import-group-button')
# Make sure import started before waiting for completion
has_no_element?(:import_status_indicator, text: "Not started", wait: 1)
end
diff --git a/qa/qa/page/group/dependency_proxy.rb b/qa/qa/page/group/dependency_proxy.rb
index fa37e8eac83..70dfa78069c 100644
--- a/qa/qa/page/group/dependency_proxy.rb
+++ b/qa/qa/page/group/dependency_proxy.rb
@@ -5,11 +5,11 @@ module QA
module Group
class DependencyProxy < QA::Page::Base
view 'app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue' do
- element :dependency_proxy_count
+ element 'proxy-count'
end
def has_blob_count?(blob_text)
- has_element?(:dependency_proxy_count, text: blob_text)
+ has_element?('proxy-count', text: blob_text)
end
end
end
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index c166023a620..c8f826b20e7 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -4,7 +4,7 @@ module QA
module Page
module Group
class Menu < Page::Base
- include SubMenus::Common
+ include QA::Page::SubMenus::Common
if Runtime::Env.super_sidebar_enabled?
prepend Page::SubMenus::SuperSidebar::Manage
diff --git a/qa/qa/page/group/new.rb b/qa/qa/page/group/new.rb
index 47fda787085..5b86dea2b8f 100644
--- a/qa/qa/page/group/new.rb
+++ b/qa/qa/page/group/new.rb
@@ -7,31 +7,31 @@ module QA
include Page::Component::VisibilitySetting
view 'app/assets/javascripts/groups/components/group_name_and_path.vue' do
- element :group_path_field
- element :group_name_field
+ element 'group-path-field'
+ element 'group-name-field'
end
view 'app/views/groups/_new_group_fields.html.haml' do
- element :create_group_button
+ element 'create-group-button'
end
view 'app/views/groups/_import_group_from_another_instance_panel.html.haml' do
- element :import_gitlab_url
- element :import_gitlab_token
- element :connect_instance_button
+ element 'import-gitlab-url'
+ element 'import-gitlab-token'
+ element 'connect-instance-button'
end
view 'app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue' do
- element :panel_link
+ element 'panel-link'
end
def set_path(path)
- fill_element(:group_path_field, path)
- fill_element(:group_name_field, path)
+ fill_element('group-path-field', path)
+ fill_element('group-name-field', path)
end
def create
- click_element(:create_group_button)
+ click_element('create-group-button')
end
def create_subgroup
@@ -39,11 +39,11 @@ module QA
end
def set_gitlab_url(url)
- fill_element(:import_gitlab_url, url)
+ fill_element('import-gitlab-url', url)
end
def set_gitlab_token(token)
- fill_element(:import_gitlab_token, token)
+ fill_element('import-gitlab-token', token)
end
def click_import_group
@@ -51,7 +51,7 @@ module QA
end
def click_create_group
- click_on 'Create group'
+ click_element('panel-link', panel_name: 'create-group-pane')
end
# Connect gitlab instance
@@ -61,16 +61,16 @@ module QA
# @return [void]
def connect_gitlab_instance(gitlab_url, gitlab_token)
# Wait until element is present and refresh if not in case feature flag did not kick in
- wait_until(max_duration: 10) { has_element?(:import_gitlab_url, wait: 1) }
+ wait_until(max_duration: 10) { has_element?('import-gitlab-url', wait: 1) }
set_gitlab_url(gitlab_url)
set_gitlab_token(gitlab_token)
- click_element(:connect_instance_button)
+ click_element('connect-instance-button')
end
def switch_to_import_tab
- click_element(:panel_link, panel_name: 'import-group-pane')
+ click_element('panel-link', panel_name: 'import-group-pane')
end
end
end
diff --git a/qa/qa/page/group/sub_menus/common.rb b/qa/qa/page/group/sub_menus/common.rb
deleted file mode 100644
index 6369306da3f..00000000000
--- a/qa/qa/page/group/sub_menus/common.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Group
- module SubMenus
- module Common
- extend QA::Page::PageConcern
- include QA::Page::SubMenus::Common
-
- def self.included(base)
- super
-
- base.class_eval do
- view 'app/views/shared/nav/_sidebar.html.haml' do
- element :group_sidebar, 'testid: sidebar_qa_selector(sidebar.container)' # rubocop:disable QA/ElementWithPattern
- end
- end
- end
-
- private
-
- def sidebar_element
- QA::Runtime::Env.super_sidebar_enabled? ? :navbar : :group_sidebar
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/issuable/new.rb b/qa/qa/page/issuable/new.rb
index 0a8be750752..8004875dedb 100644
--- a/qa/qa/page/issuable/new.rb
+++ b/qa/qa/page/issuable/new.rb
@@ -23,7 +23,7 @@ module QA
end
view 'app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents.vue' do
- element :labels_select_dropdown_contents
+ element 'labels-select-dropdown-contents'
end
view 'app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml' do
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 8812c792554..47e50c4a8a3 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -103,12 +103,6 @@ module QA
click_element :sign_in_button
end
- if Runtime::Env.super_sidebar_enabled?
- Page::Main::Menu.perform(&:enable_new_navigation)
- else
- Page::Main::Menu.perform(&:disable_new_navigation)
- end
-
Page::Main::Menu.perform(&:signed_in?)
end
@@ -269,14 +263,6 @@ module QA
wait_for_gitlab_to_respond
- if Runtime::Env.super_sidebar_enabled?
- Page::Main::Menu.perform(&:enable_new_navigation)
- else
- Page::Main::Menu.perform(&:disable_new_navigation)
- end
-
- wait_for_gitlab_to_respond
-
Page::Main::Menu.validate_elements_present! unless skip_page_validation
end
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index 29c4360f814..f5bfeecec10 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -20,7 +20,7 @@ module QA
end
view 'app/assets/javascripts/super_sidebar/components/user_menu.vue' do
- element :user_dropdown, required: !Runtime::Env.phone_layout?
+ element 'user-dropdown', required: !Runtime::Env.phone_layout?
element :user_avatar_content, required: !Runtime::Env.phone_layout?
element :sign_out_link
element :edit_profile_link
@@ -31,26 +31,26 @@ module QA
end
view 'app/assets/javascripts/super_sidebar/components/user_bar.vue' do
- element :super_sidebar_search_button
- element :stop_impersonation_btn
- element :issues_shortcut_button, required: !Runtime::Env.phone_layout?
- element :merge_requests_shortcut_button, required: !Runtime::Env.phone_layout?
- element :todos_shortcut_button, required: !Runtime::Env.phone_layout?
+ element 'super-sidebar-search-button'
+ element 'stop-impersonation-btn'
+ element 'issues-shortcut-button', required: !Runtime::Env.phone_layout?
+ element 'merge-requests-shortcut-button', required: !Runtime::Env.phone_layout?
+ element 'todos-shortcut-button', required: !Runtime::Env.phone_layout?
end
view 'app/assets/javascripts/super_sidebar/components/global_search/components/global_search.vue' do
- element :global_search_input
+ element 'global-search-input'
end
else
view 'app/views/layouts/header/_default.html.haml' do
element :navbar, required: true
element :canary_badge_link
element :user_avatar_content, required: !Runtime::Env.phone_layout?
- element :user_dropdown, required: !Runtime::Env.phone_layout?
- element :stop_impersonation_btn
- element :issues_shortcut_button, required: !Runtime::Env.phone_layout?
- element :merge_requests_shortcut_button, required: !Runtime::Env.phone_layout?
- element :todos_shortcut_button, required: !Runtime::Env.phone_layout?
+ element 'user-dropdown', required: !Runtime::Env.phone_layout?
+ element 'stop-impersonation-btn'
+ element 'issues-shortcut-button', required: !Runtime::Env.phone_layout?
+ element 'merge-requests-shortcut-button', required: !Runtime::Env.phone_layout?
+ element 'todos-shortcut-button', required: !Runtime::Env.phone_layout?
end
view 'app/views/layouts/header/_current_user_dropdown.html.haml' do
@@ -65,7 +65,7 @@ module QA
end
view 'app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue' do
- element :menu_subview
+ element 'menu-subview'
end
view 'lib/gitlab/nav/top_nav_menu_item.rb' do
@@ -84,11 +84,11 @@ module QA
end
view 'app/assets/javascripts/header_search/components/app.vue' do
- element :global_search_input
+ element 'global-search-input'
end
view 'app/views/layouts/header/_new_dropdown.html.haml' do
- element :new_menu_toggle
+ element 'new-menu-toggle'
end
view 'app/helpers/nav/new_dropdown_helper.rb' do
@@ -140,17 +140,17 @@ module QA
end
def go_to_create_project
- click_element(:new_menu_toggle)
+ click_element('new-menu-toggle')
click_element(:global_new_project_link)
end
def go_to_create_group
- click_element(:new_menu_toggle)
+ click_element('new-menu-toggle')
click_element(:global_new_group_link)
end
def go_to_create_snippet
- click_element(:new_menu_toggle)
+ click_element('new-menu-toggle')
click_element(:global_new_snippet_link)
end
@@ -167,7 +167,7 @@ module QA
# @param [Symbol] the name of the element (e.g: `:issues_shortcut button`)
# @example:
# Menu.perform do |menu|
- # menu.go_to_page_by_shortcut(:issues_shortcut_button) #=> Go to Issues page using shortcut button
+ # menu.go_to_page_by_shortcut('issues-shortcut-button') #=> Go to Issues page using shortcut button
# end
def go_to_page_by_shortcut(button)
within_top_menu do
@@ -243,8 +243,8 @@ module QA
end
def search_for(term)
- click_element(Runtime::Env.super_sidebar_enabled? ? :super_sidebar_search_button : :search_box)
- fill_element(:global_search_input, "#{term}\n")
+ click_element(Runtime::Env.super_sidebar_enabled? ? 'super-sidebar-search-button' : :search_box)
+ fill_element('global-search-input', "#{term}\n")
end
def has_personal_area?(wait: Capybara.default_max_wait_time)
@@ -265,7 +265,7 @@ module QA
end
def click_stop_impersonation_link
- click_element(:stop_impersonation_btn)
+ click_element('stop-impersonation-btn')
end
# To verify whether the user has been directed to a canary web node
@@ -308,20 +308,20 @@ module QA
within_top_menu do
click_element :user_avatar_content unless has_element?(:user_profile_link, wait: 1)
- within_element(:user_dropdown, &block)
+ within_element('user-dropdown', &block)
end
end
def within_groups_menu(&block)
go_to_menu_dropdown_option(:groups_dropdown)
- within_element(:menu_subview, &block)
+ within_element('menu-subview', &block)
end
def within_projects_menu(&block)
go_to_menu_dropdown_option(:projects_dropdown)
- within_element(:menu_subview, &block)
+ within_element('menu-subview', &block)
end
def click_admin_area
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 71c2aa2d0b3..2ff6460b1c8 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -241,7 +241,7 @@ module QA
end
def open_file_tree
- click_element(:file_tree_button) unless has_element?(:file_tree_container)
+ click_element(:file_tree_button) if has_no_element?(:file_tree_container, wait: 1)
end
def has_merge_button?
@@ -286,7 +286,6 @@ module QA
end
def merge!
- close_rich_text_promo_popover_if_present
try_to_merge!
finished_loading?
@@ -311,13 +310,14 @@ module QA
end
end
- # Check if the MR is able to be merged
- # Waits up 10 seconds and returns false if the MR can't be merged
- def mergeable?
- # The merge button is enabled via JS, but `has_element?` calls
- # `wait_for_requests`, which should ensure the disabled/enabled
- # state of the element is reliable
- has_element?(:merge_button, disabled: false)
+ RSpec::Matchers.define :be_mergeable do
+ match do |page|
+ page.has_element?(:merge_button, disabled: false)
+ end
+
+ match_when_negated do |page|
+ page.has_no_element?(:merge_button, disabled: false)
+ end
end
# Waits up 10 seconds and returns false if the Revert button is not enabled
diff --git a/qa/qa/page/profile/emails.rb b/qa/qa/page/profile/emails.rb
index f8aeea50513..1e6b7518e55 100644
--- a/qa/qa/page/profile/emails.rb
+++ b/qa/qa/page/profile/emails.rb
@@ -11,9 +11,16 @@ module QA
element :add_email_address_button
element :email_row_content
element :delete_email_link
+ element :toggle_email_address_field
+ end
+
+ def expand_email_input
+ click_element(:toggle_email_address_field) if has_no_element?(:email_address_field)
+ has_element?(:email_address_field)
end
def add_email_address(email_address)
+ expand_email_input
find_element(:email_address_field).set email_address
click_element(:add_email_address_button)
end
diff --git a/qa/qa/page/profile/ssh_keys.rb b/qa/qa/page/profile/ssh_keys.rb
index 0653df62560..2990ba6a4ac 100644
--- a/qa/qa/page/profile/ssh_keys.rb
+++ b/qa/qa/page/profile/ssh_keys.rb
@@ -24,6 +24,8 @@ module QA
end
def add_key(public_key, title)
+ click_button('Add new key')
+
fill_element(:key_public_key_field, public_key)
fill_element(:key_title_field, title)
# Expire in 2 days just in case the key is created just before midnight
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index 898bf78b46a..9e1bf0a393f 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -19,7 +19,7 @@ module QA
element :import_status_indicator
end
- view "app/assets/javascripts/import_entities/components/group_dropdown.vue" do
+ view "app/assets/javascripts/import_entities/components/import_target_dropdown.vue" do
element :target_namespace_selector_dropdown
end
@@ -47,7 +47,7 @@ module QA
def import!(gh_project_name, target_group_path, project_name)
within_element(:project_import_row, source_project: gh_project_name) do
click_element(:target_namespace_selector_dropdown)
- click_element(:target_group_dropdown_item, group_name: target_group_path)
+ click_element("listbox-item-#{target_group_path}", wait: 10)
fill_element(:project_path_field, project_name)
retry_until do
diff --git a/qa/qa/page/project/import/repo_by_url.rb b/qa/qa/page/project/import/repo_by_url.rb
index 1adfe001573..1e12ec1541d 100644
--- a/qa/qa/page/project/import/repo_by_url.rb
+++ b/qa/qa/page/project/import/repo_by_url.rb
@@ -6,12 +6,12 @@ module QA
module Import
class RepoByURL < Page::Base
view 'app/assets/javascripts/projects/new/components/new_project_url_select.vue' do
- element :select_namespace_dropdown
- element :select_namespace_dropdown_search_field
+ element 'select-namespace-dropdown'
+ element 'select-namespace-dropdown-search-field'
end
view 'app/views/projects/_new_project_fields.html.haml' do
- element :project_create_button
+ element 'project-create-button'
end
def import!(gitlab_repo_path, name)
@@ -39,14 +39,14 @@ module QA
def choose_namespace(namespace)
retry_on_exception do
- click_element :select_namespace_dropdown
- fill_element :select_namespace_dropdown_search_field, namespace
+ click_element 'select-namespace-dropdown'
+ fill_element 'select-namespace-dropdown-search-field', namespace
click_button namespace
end
end
def click_create_button
- click_element(:project_create_button)
+ click_element('project-create-button')
end
def wait_for_success
diff --git a/qa/qa/page/project/infrastructure/kubernetes/add_existing.rb b/qa/qa/page/project/infrastructure/kubernetes/add_existing.rb
deleted file mode 100644
index 2fc65cf0afe..00000000000
--- a/qa/qa/page/project/infrastructure/kubernetes/add_existing.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Infrastructure
- module Kubernetes
- class AddExisting < Page::Base
- view 'app/views/clusters/clusters/user/_form.html.haml' do
- element :cluster_name, 'text_field :name' # rubocop:disable QA/ElementWithPattern
- element :api_url, 'url_field :api_url' # rubocop:disable QA/ElementWithPattern
- element :ca_certificate, 'text_area :ca_cert' # rubocop:disable QA/ElementWithPattern
- element :token, 'text_field :token' # rubocop:disable QA/ElementWithPattern
- element :add_kubernetes_cluster_button
- element :rbac_checkbox
- end
-
- def set_cluster_name(name)
- fill_in 'cluster_name', with: name
- end
-
- def set_api_url(api_url)
- fill_in 'cluster_platform_kubernetes_attributes_api_url', with: api_url
- end
-
- def set_ca_certificate(ca_certificate)
- fill_in 'cluster_platform_kubernetes_attributes_ca_cert', with: ca_certificate
- end
-
- def set_token(token)
- fill_in 'cluster_platform_kubernetes_attributes_token', with: token
- end
-
- def add_cluster!
- click_element :add_kubernetes_cluster_button, Page::Project::Infrastructure::Kubernetes::Show
- end
-
- def uncheck_rbac!
- uncheck_element(:rbac_checkbox)
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/infrastructure/kubernetes/index.rb b/qa/qa/page/project/infrastructure/kubernetes/index.rb
deleted file mode 100644
index 4c759a049e1..00000000000
--- a/qa/qa/page/project/infrastructure/kubernetes/index.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Infrastructure
- module Kubernetes
- class Index < Page::Base
- view 'app/assets/javascripts/clusters_list/components/clusters_actions.vue' do
- element :clusters_actions_button
- end
-
- def connect_cluster
- click_element(:clusters_actions_button)
- end
-
- def has_cluster?(cluster)
- has_element?(:cluster, cluster_name: cluster.to_s)
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/infrastructure/kubernetes/show.rb b/qa/qa/page/project/infrastructure/kubernetes/show.rb
deleted file mode 100644
index 8725f64fe32..00000000000
--- a/qa/qa/page/project/infrastructure/kubernetes/show.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Infrastructure
- module Kubernetes
- class Show < Page::Base
- view 'app/assets/javascripts/clusters/forms/components/integration_form.vue' do
- element :integration_status_toggle
- element :base_domain_field
- end
-
- view 'app/assets/javascripts/integrations/edit/components/integration_form_actions.vue' do
- element :save_changes_button
- end
-
- def set_domain(domain)
- fill_element :base_domain_field, domain
- end
-
- def save_domain
- click_element :save_changes_button, Page::Project::Infrastructure::Kubernetes::Show
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
index c95375dbbb9..8092b69d377 100644
--- a/qa/qa/page/project/issue/show.rb
+++ b/qa/qa/page/project/issue/show.rb
@@ -19,9 +19,9 @@ module QA
end
view 'app/assets/javascripts/issues/show/components/header_actions.vue' do
- element :toggle_issue_state_button
- element :desktop_dropdown
- element :delete_issue_button
+ element 'toggle-issue-state-button'
+ element 'desktop-dropdown'
+ element 'delete-issue-button'
end
view 'app/assets/javascripts/related_issues/components/add_issuable_form.vue' do
@@ -33,7 +33,7 @@ module QA
end
view 'app/assets/javascripts/related_issues/components/related_issues_block.vue' do
- element :related_issues_plus_button
+ element 'related-issues-plus-button'
end
view 'app/assets/javascripts/related_issues/components/related_issues_list.vue' do
@@ -42,7 +42,7 @@ module QA
end
def relate_issue(issue)
- click_element(:related_issues_plus_button)
+ click_element('related-issues-plus-button')
fill_element(:add_issue_field, issue.web_url)
send_keys_to_element(:add_issue_field, :enter)
end
@@ -63,29 +63,30 @@ module QA
end
def click_close_issue_button
- # Click by JS is needed to bypass the Moved MR actions popover
- # Change back to regular click_element when moved_mr_sidebar FF is removed
- # Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/385460
- click_by_javascript(find_element(:toggle_issue_state_button, text: 'Close issue'))
+ open_actions_dropdown
+ click_element('toggle-issue-state-button', text: 'Close issue')
end
def has_reopen_issue_button?
- has_element?(:toggle_issue_state_button, text: 'Reopen issue')
+ open_actions_dropdown
+ has_element?('toggle-issue-state-button', text: 'Reopen issue')
end
def has_delete_issue_button?
- # Click by JS is needed to bypass the Moved MR actions popover
- # Change back to regular click_element when moved_mr_sidebar FF is removed
- # Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/385460
- click_by_javascript(find('[data-testid="desktop-dropdown"] > button'))
- has_element?(:delete_issue_button)
+ open_actions_dropdown
+ has_element?('delete-issue-button')
+ end
+
+ def has_no_delete_issue_button?
+ open_actions_dropdown
+ has_no_element?('delete-issue-button')
end
def delete_issue
has_delete_issue_button?
click_element(
- :delete_issue_button,
+ 'delete-issue-button',
Page::Modal::DeleteIssue,
wait: Support::Repeater::DEFAULT_MAX_WAIT_TIME
)
@@ -94,6 +95,11 @@ module QA
wait_for_requests
end
+
+ def open_actions_dropdown
+ # We use find here because these are gitlab-ui elements
+ find('[data-testid="desktop-dropdown"] > button').click
+ end
end
end
end
diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb
index 8ea0b57ef3e..d61f9cf0218 100644
--- a/qa/qa/page/project/new.rb
+++ b/qa/qa/page/project/new.rb
@@ -6,41 +6,42 @@ module QA
class New < Page::Base
include Page::Component::Project::Templates
include Page::Component::VisibilitySetting
+ include QA::Page::Component::Dropdown
include Layout::Flash
include Page::Component::Import::Selection
include Page::Component::Import::Gitlab
view 'app/views/projects/_new_project_fields.html.haml' do
- element :initialize_with_readme_checkbox
- element :initialize_with_sast_checkbox
- element :project_name
- element :project_path
- element :project_description
- element :project_create_button
- element :visibility_radios
+ element 'initialize-with-readme-checkbox'
+ element 'initialize-with-sast-checkbox'
+ element 'project-name'
+ element 'project-path'
+ element 'project-description'
+ element 'project-create-button'
+ element 'visibility-radios'
end
view 'app/views/projects/project_templates/_template.html.haml' do
- element :use_template_button
- element :template_option_container
+ element 'use-template-button'
+ element 'template-option-container'
end
view 'app/assets/javascripts/projects/new/components/new_project_url_select.vue' do
- element :select_namespace_dropdown
- element :select_namespace_dropdown_search_field
+ element 'select-namespace-dropdown'
+ element 'select-namespace-dropdown-search-field'
end
view 'app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue' do
- element :panel_link
+ element 'panel-link'
end
def click_blank_project_link
- click_element(:panel_link, panel_name: 'blank_project')
+ click_element('panel-link', panel_name: 'blank_project')
end
def click_create_from_template_link
- click_element(:panel_link, panel_name: 'create_from_template')
+ click_element('panel-link', panel_name: 'create_from_template')
end
def choose_test_namespace
@@ -48,9 +49,12 @@ module QA
end
def choose_namespace(namespace)
- click_element :select_namespace_dropdown
- fill_element :select_namespace_dropdown_search_field, namespace
- within_element(:select_namespace_dropdown) { click_button namespace }
+ # The current group is the default, we use end_with? in case we want to select the top level group
+ return if find_element('select-namespace-dropdown').text.end_with?(namespace)
+
+ click_element 'select-namespace-dropdown'
+ fill_element 'select-namespace-dropdown-search-field', namespace
+ select_item(namespace, css: '.gl-dropdown-item')
end
def click_import_project
@@ -62,7 +66,7 @@ module QA
end
def add_description(description)
- return unless has_element?(:project_description, wait: 1)
+ return unless has_element?('project-description', wait: 1)
fill_in 'project_description', with: description
end
@@ -81,9 +85,9 @@ module QA
# Disable experiment for SAST at project creation https://gitlab.com/gitlab-org/gitlab/-/issues/333196
def disable_initialize_with_sast
- return unless has_element?(:initialize_with_sast_checkbox, visible: false)
+ return unless has_element?('initialize-with-sast-checkbox', visible: false)
- uncheck_element(:initialize_with_sast_checkbox, true)
+ uncheck_element('initialize-with-sast-checkbox', true)
end
def click_github_link
@@ -99,7 +103,7 @@ module QA
end
def disable_initialize_with_readme
- uncheck_element(:initialize_with_readme_checkbox, true)
+ uncheck_element('initialize-with-readme-checkbox', true)
end
end
end
diff --git a/qa/qa/page/project/packages/index.rb b/qa/qa/page/project/packages/index.rb
index e58ffba3cd5..f3a8bc8c175 100644
--- a/qa/qa/page/project/packages/index.rb
+++ b/qa/qa/page/project/packages/index.rb
@@ -6,27 +6,27 @@ module QA
module Packages
class Index < QA::Page::Base
view 'app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue' do
- element :package_link
+ element 'details-link'
end
view 'app/assets/javascripts/packages_and_registries/infrastructure_registry/shared/package_list_row.vue' do
- element :package_link
+ element 'details-link'
end
def click_package(name)
- click_element(:package_link, text: name)
+ click_element('details-link', text: name)
end
def has_package?(name)
- has_element?(:package_link, text: name, wait: 20)
+ has_element?('details-link', text: name, wait: 20)
end
def has_module?(name)
- has_element?(:package_link, text: name, wait: 20)
+ has_element?('details-link', text: name, wait: 20)
end
def has_no_package?(name)
- has_no_element?(:package_link, text: name)
+ has_no_element?('details-link', text: name)
end
end
end
diff --git a/qa/qa/page/project/packages/show.rb b/qa/qa/page/project/packages/show.rb
index 5ba9ad7df40..6c265c2a66d 100644
--- a/qa/qa/page/project/packages/show.rb
+++ b/qa/qa/page/project/packages/show.rb
@@ -6,19 +6,19 @@ module QA
module Packages
class Show < QA::Page::Base
view 'app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue' do
- element :delete_button
- element :delete_modal_button
- element :package_information_content
+ element 'delete-package'
+ element 'delete-modal-button'
+ element 'package-information-content'
end
def has_package_info?(name, version)
- has_element?(:package_information_content, text: /#{name}.*#{version}/)
+ has_element?('package-information-content', text: /#{name}.*#{version}/)
end
def click_delete
- click_element(:delete_button)
- wait_for_animated_element(:delete_modal_button)
- click_element(:delete_modal_button)
+ click_element('delete-package')
+ wait_for_animated_element('delete-modal-button')
+ click_element('delete-modal-button')
end
end
end
diff --git a/qa/qa/page/project/registry/show.rb b/qa/qa/page/project/registry/show.rb
index 95850f34962..0deeb5b4ae0 100644
--- a/qa/qa/page/project/registry/show.rb
+++ b/qa/qa/page/project/registry/show.rb
@@ -6,34 +6,34 @@ module QA
module Registry
class Show < QA::Page::Base
view 'app/assets/javascripts/packages_and_registries/container_registry/explorer/components/list_page/image_list_row.vue' do
- element :registry_image_content
+ element 'details-link'
end
view 'app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue' do
- element :more_actions_menu
- element :tag_delete_button
- element :tag_name_content
+ element 'additional-actions'
+ element 'single-delete-button'
+ element :name
end
def has_registry_repository?(name)
- find_element(:registry_image_content, text: name)
+ find_element('details-link', text: name)
end
def click_on_image(name)
- click_element(:registry_image_content, text: name)
+ click_element('details-link', text: name)
end
def has_tag?(tag_name)
- has_element?(:tag_name_content, text: tag_name)
+ has_element?(:name, text: tag_name)
end
def has_no_tag?(tag_name)
- has_no_element?(:tag_name_content, text: tag_name)
+ has_no_element?(:name, text: tag_name)
end
def click_delete
- click_element(:more_actions_menu)
- click_element(:tag_delete_button)
+ click_element('additional-actions')
+ click_element('single-delete-button')
find_button('Delete').click
end
end
diff --git a/qa/qa/page/project/secure/configuration_form.rb b/qa/qa/page/project/secure/configuration_form.rb
index 70eff31bfa9..32609943f3e 100644
--- a/qa/qa/page/project/secure/configuration_form.rb
+++ b/qa/qa/page/project/secure/configuration_form.rb
@@ -8,30 +8,30 @@ module QA
include QA::Page::Settings::Common
view 'app/assets/javascripts/security_configuration/components/app.vue' do
- element :security_configuration_container
- element :security_view_history_link
+ element 'security-configuration-container'
+ element 'security-view-history-link'
end
view 'app/assets/javascripts/security_configuration/components/feature_card.vue' do
- element :feature_status
+ element 'feature-status'
element :sast_enable_button, "`${feature.type}_enable_button`" # rubocop:disable QA/ElementWithPattern
element :dependency_scanning_mr_button, "`${feature.type}_mr_button`" # rubocop:disable QA/ElementWithPattern
end
view 'app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue' do
- element :autodevops_container
+ element 'autodevops-container'
end
def has_security_configuration_history_link?
- has_element?(:security_view_history_link)
+ has_element?('security-view-history-link')
end
def has_no_security_configuration_history_link?
- has_no_element?(:security_view_history_link)
+ has_no_element?('security-view-history-link')
end
def click_security_configuration_history_link
- click_element(:security_view_history_link)
+ click_element('security-view-history-link')
end
def click_sast_enable_button
@@ -43,31 +43,31 @@ module QA
end
def has_true_sast_status?
- has_element?(:feature_status, feature: 'sast_true_status')
+ has_element?('feature-status', feature: 'sast_true_status')
end
def has_false_sast_status?
- has_element?(:feature_status, feature: 'sast_false_status')
+ has_element?('feature-status', feature: 'sast_false_status')
end
def has_true_dependency_scanning_status?
- has_element?(:feature_status, feature: 'dependency_scanning_true_status')
+ has_element?('feature-status', feature: 'dependency_scanning_true_status')
end
def has_false_dependency_scanning_status?
- has_element?(:feature_status, feature: 'dependency_scanning_false_status')
+ has_element?('feature-status', feature: 'dependency_scanning_false_status')
end
def has_auto_devops_container?
- has_element?(:autodevops_container)
+ has_element?('autodevops-container')
end
def has_no_auto_devops_container?
- has_no_element?(:autodevops_container)
+ has_no_element?('autodevops-container')
end
def has_auto_devops_container_description?
- within_element(:autodevops_container) do
+ within_element('autodevops-container') do
has_text?('Quickly enable all continuous testing and compliance tools by enabling Auto DevOps')
end
end
@@ -79,7 +79,7 @@ module QA
private
def go_to_tab(name)
- within_element(:security_configuration_container) do
+ within_element('security-configuration-container') do
find('.nav-item', text: name).click
end
end
diff --git a/qa/qa/page/project/settings/ci_variables.rb b/qa/qa/page/project/settings/ci_variables.rb
index 4b587e28382..36c667866b5 100644
--- a/qa/qa/page/project/settings/ci_variables.rb
+++ b/qa/qa/page/project/settings/ci_variables.rb
@@ -19,8 +19,7 @@ module QA
click_ci_variable_save_button
wait_until(reload: false) do
- # Using data-testid="ci-variable-table"
- within_element(:ci_variable_table) { has_element?(:edit_ci_variable_button) }
+ within_element('ci-variable-table') { has_element?(:edit_ci_variable_button) }
end
end
@@ -29,8 +28,7 @@ module QA
end
def click_edit_ci_variable
- # Using data-testid="ci-variable-table"
- within_element(:ci_variable_table) do
+ within_element('ci-variable-table') do
click_element :edit_ci_variable_button
end
end
diff --git a/qa/qa/page/project/settings/deploy_keys.rb b/qa/qa/page/project/settings/deploy_keys.rb
index b94dbbea533..d8369c12268 100644
--- a/qa/qa/page/project/settings/deploy_keys.rb
+++ b/qa/qa/page/project/settings/deploy_keys.rb
@@ -6,65 +6,70 @@ module QA
module Settings
class DeployKeys < Page::Base
view 'app/views/shared/deploy_keys/_form.html.haml' do
- element :deploy_key_title_field
- element :deploy_key_field
+ element 'deploy-key-title-field'
+ element 'deploy-key-field'
end
view 'app/views/shared/deploy_keys/_project_group_form.html.haml' do
- element :deploy_key_title_field
- element :deploy_key_field
- element :deploy_key_expires_at_field
- element :add_deploy_key_button
+ element 'deploy-key-title-field'
+ element 'deploy-key-field'
+ element 'deploy-key-expires-at-field'
+ element 'add-deploy-key-button'
end
view 'app/assets/javascripts/deploy_keys/components/app.vue' do
- element :project_deploy_keys_container
+ element 'project-deploy-keys-container'
+ element 'add-new-deploy-key-button'
end
view 'app/assets/javascripts/deploy_keys/components/key.vue' do
- element :key_container
- element :key_title_content
- element :key_sha256_fingerprint_content
+ element 'key-container'
+ element 'key-title-content'
+ element 'key-sha256-fingerprint-content'
+ end
+
+ def add_new_key
+ click_element('add-new-deploy-key-button')
end
def add_key
- click_element(:add_deploy_key_button)
+ click_element('add-deploy-key-button')
end
def fill_key_title(title)
- fill_element(:deploy_key_title_field, title)
+ fill_element('deploy-key-title-field', title)
end
def fill_key_value(key)
- fill_element(:deploy_key_field, key)
+ fill_element('deploy-key-field', key)
end
def find_sha256_fingerprint(title)
within_project_deploy_keys do
- find_element(:key_container, text: title)
- .find(element_selector_css(:key_sha256_fingerprint_content)).text
+ find_element('key-container', text: title)
+ .find(element_selector_css('key-sha256-fingerprint-content')).text
end
end
def has_key?(title, sha256_fingerprint)
within_project_deploy_keys do
- find_element(:key_container, text: title)
- .has_css?(element_selector_css(:key_sha256_fingerprint_content), text: sha256_fingerprint)
+ find_element('key-container', text: title)
+ .has_css?(element_selector_css('key-sha256-fingerprint-content'), text: sha256_fingerprint)
end
end
def key_title
within_project_deploy_keys do
- find_element(:key_title_content).text
+ find_element('key-title-content').text
end
end
private
def within_project_deploy_keys
- has_element?(:project_deploy_keys_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
+ has_element?('project-deploy-keys-container', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
- within_element(:project_deploy_keys_container) do
+ within_element('project-deploy-keys-container') do
yield
end
end
diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb
index c9ce80076e2..85b413ba880 100644
--- a/qa/qa/page/project/settings/mirroring_repositories.rb
+++ b/qa/qa/page/project/settings/mirroring_repositories.rb
@@ -13,6 +13,7 @@ module QA
view 'app/views/projects/mirrors/_mirror_repos.html.haml' do
element :mirror_repository_url_field
element :mirror_repository_button
+ element 'add-new-mirror'
end
view 'app/views/projects/mirrors/_mirror_repos_list.html.haml' do
@@ -37,6 +38,7 @@ module QA
end
def repository_url=(value)
+ click_element 'add-new-mirror'
fill_element :mirror_repository_url_field, value
end
diff --git a/qa/qa/page/project/settings/protected_branches.rb b/qa/qa/page/project/settings/protected_branches.rb
index e6b13ed77a0..93522c1deac 100644
--- a/qa/qa/page/project/settings/protected_branches.rb
+++ b/qa/qa/page/project/settings/protected_branches.rb
@@ -5,6 +5,10 @@ module QA
module Project
module Settings
class ProtectedBranches < Page::Base
+ view 'app/views/protected_branches/shared/_index.html.haml' do
+ element 'add-protected-branch-button'
+ end
+
view 'app/views/protected_branches/shared/_dropdown.html.haml' do
element :protected_branch_dropdown
element :protected_branch_dropdown_content
@@ -22,6 +26,7 @@ module QA
end
def select_branch(branch_name)
+ click_element 'add-protected-branch-button'
click_element :protected_branch_dropdown
within_element(:protected_branch_dropdown_content) do
diff --git a/qa/qa/page/project/settings/protected_tags.rb b/qa/qa/page/project/settings/protected_tags.rb
index d9f383154f9..49fdae5f8a3 100644
--- a/qa/qa/page/project/settings/protected_tags.rb
+++ b/qa/qa/page/project/settings/protected_tags.rb
@@ -21,6 +21,7 @@ module QA
end
def set_tag(tag_name)
+ click_button 'Add tag'
click_element :tags_dropdown
filter_and_select(tag_name)
end
@@ -32,6 +33,7 @@ module QA
within_element(:access_levels_content) do
click_on role
end
+ click_element :access_levels_dropdown
end
def click_protect_tag_button
diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb
index d9aaacbde32..4e53ea1aee9 100644
--- a/qa/qa/page/project/settings/repository.rb
+++ b/qa/qa/page/project/settings/repository.rb
@@ -20,7 +20,7 @@ module QA
end
view 'app/views/shared/deploy_keys/_index.html.haml' do
- element :deploy_keys_settings_content
+ element 'deploy-keys-settings-content'
end
view 'app/views/projects/protected_tags/shared/_index.html.haml' do
@@ -38,7 +38,7 @@ module QA
end
def expand_deploy_keys(&block)
- expand_content(:deploy_keys_settings_content) do
+ expand_content('deploy-keys-settings-content') do
Settings::DeployKeys.perform(&block)
end
end
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index 95a6c840684..59cccfd665a 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -26,7 +26,7 @@ module QA
end
view 'app/views/layouts/header/_new_dropdown.html.haml' do
- element :new_menu_toggle
+ element 'new-menu-toggle'
end
view 'app/views/projects/_last_push.html.haml' do
@@ -49,8 +49,8 @@ module QA
element :forked_from_link
end
- view 'app/views/projects/buttons/_fork.html.haml' do
- element :fork_button
+ view 'app/assets/javascripts/forks/components/forks_button.vue' do
+ element 'fork-button'
end
view 'app/views/projects/empty.html.haml' do
@@ -93,7 +93,7 @@ module QA
# Change back to regular click_element when vscode_web_ide FF is removed
# Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/371084
def fork_project
- fork_button = find_element(:fork_button)
+ fork_button = find_element('fork-button')
click_by_javascript(fork_button)
end
diff --git a/qa/qa/page/project/sub_menus/common.rb b/qa/qa/page/project/sub_menus/common.rb
index e8952f9e064..280d28a697d 100644
--- a/qa/qa/page/project/sub_menus/common.rb
+++ b/qa/qa/page/project/sub_menus/common.rb
@@ -6,12 +6,13 @@ module QA
module SubMenus
module Common
extend QA::Page::PageConcern
- include QA::Page::SubMenus::Common
def self.included(base)
super
base.class_eval do
+ include QA::Page::SubMenus::Common
+
view 'app/views/shared/nav/_sidebar_menu_item.html.haml' do
element :sidebar_menu_item_link
end
@@ -25,12 +26,6 @@ module QA
end
end
end
-
- private
-
- def sidebar_element
- QA::Runtime::Env.super_sidebar_enabled? ? :navbar : :project_sidebar
- end
end
end
end
diff --git a/qa/qa/page/sub_menus/common.rb b/qa/qa/page/sub_menus/common.rb
index 28b4cb37333..19d07e885c6 100644
--- a/qa/qa/page/sub_menus/common.rb
+++ b/qa/qa/page/sub_menus/common.rb
@@ -6,6 +6,16 @@ module QA
module Common
prepend Mobile::Page::SubMenus::Common if QA::Runtime::Env.mobile_layout?
+ def self.included(base)
+ super
+
+ base.class_eval do
+ view 'app/assets/javascripts/super_sidebar/components/super_sidebar.vue' do
+ element :navbar
+ end
+ end
+ end
+
def hover_element(element)
within_sidebar do
find_element(element).hover
@@ -16,7 +26,7 @@ module QA
def within_sidebar(&block)
wait_for_requests
- within_element(sidebar_element, &block)
+ within_element(:navbar, &block)
end
def within_submenu(element = nil, &block)
@@ -33,7 +43,7 @@ module QA
#
# @return [void]
def within_new_item_menu
- click_element(:new_menu_toggle)
+ click_element('new-menu-toggle')
yield
end
@@ -58,10 +68,6 @@ module QA
def within_submenu_without_element(&block)
has_css?('.fly-out-list') ? within('.fly-out-list', &block) : yield
end
-
- def sidebar_element
- raise NotImplementedError
- end
end
end
end
diff --git a/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb b/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb
index e5f2e702e60..af06438782d 100644
--- a/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb
+++ b/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb
@@ -12,8 +12,11 @@ module QA
base.class_eval do
view 'app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue' do
- element :context_switcher
- element :context_navigation
+ element 'context-switcher'
+ end
+
+ view 'app/assets/javascripts/super_sidebar/components/context_switcher.vue' do
+ element 'context-navigation'
end
end
end
@@ -44,7 +47,7 @@ module QA
end
def open_context_switcher
- click_element(:context_switcher) unless has_element?(:context_navigation, wait: 0)
+ click_element('context-switcher') unless has_element?('context-navigation', wait: 0)
end
end
end
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index 3f9d2b92a0a..5f431103df3 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -26,7 +26,10 @@ module QA
raise NotImplementedError, "Resource #{self.class.name} does not support fabrication via the API!"
end
- resource_web_url(api_post)
+ resource_web_url = resource_web_url(api_post)
+ wait_for_resource_availability(resource_web_url)
+
+ resource_web_url
end
def reload!
@@ -222,6 +225,22 @@ module QA
v.is_a?(Hash) ? a.merge(flatten_hash(v)) : a.merge(k.to_sym => v)
end
end
+
+ # Given a URL, wait for the given URL to return 200
+ # @param [String] resource_web_url the URL to check
+ # @example
+ # wait_for_resource_availability('https://gitlab.com/api/v4/projects/1234')
+ # @example
+ # wait_for_resource_availability(resource_web_url(Resource::Issue.fabricate_via_api!))
+ def wait_for_resource_availability(resource_web_url)
+ return unless Runtime::Address.valid?(resource_web_url)
+
+ Support::Retrier.retry_until(sleep_interval: 3, max_attempts: 5, raise_on_failure: false) do
+ response_check = get(resource_web_url)
+ Runtime::Logger.debug("Resource availability check ... #{response_check.code}")
+ response_check.code == HTTP_STATUS_OK
+ end
+ end
end
end
end
diff --git a/qa/qa/resource/badge_base.rb b/qa/qa/resource/badge_base.rb
index bc0adf0857d..8139cc2ec7b 100644
--- a/qa/qa/resource/badge_base.rb
+++ b/qa/qa/resource/badge_base.rb
@@ -11,6 +11,7 @@ module QA
def fabricate!
Page::Component::Badges.perform do |badges|
+ badges.show_badge_add_form
badges.fill_name(name)
badges.fill_link_url(link_url)
badges.fill_image_url(image_url)
diff --git a/qa/qa/resource/clusters/agent.rb b/qa/qa/resource/clusters/agent.rb
index 9574289a2ed..9d3f2a32aaf 100644
--- a/qa/qa/resource/clusters/agent.rb
+++ b/qa/qa/resource/clusters/agent.rb
@@ -33,6 +33,10 @@ module QA
"/projects/#{project.id}/cluster_agents"
end
+ def api_delete_path
+ api_get_path
+ end
+
def api_post_body
{
id: project.id,
diff --git a/qa/qa/resource/clusters/agent_token.rb b/qa/qa/resource/clusters/agent_token.rb
index cbd2964c31d..a6eea44100b 100644
--- a/qa/qa/resource/clusters/agent_token.rb
+++ b/qa/qa/resource/clusters/agent_token.rb
@@ -27,6 +27,10 @@ module QA
"/projects/#{agent.project.id}/cluster_agents/#{agent.id}/tokens"
end
+ def api_delete_path
+ api_get_path
+ end
+
def api_post_body
{
id: agent.project.id,
diff --git a/qa/qa/resource/deploy_key.rb b/qa/qa/resource/deploy_key.rb
index b194f97ef1b..36d1221dfda 100644
--- a/qa/qa/resource/deploy_key.rb
+++ b/qa/qa/resource/deploy_key.rb
@@ -29,6 +29,7 @@ module QA
Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_keys do |page|
+ page.add_new_key
page.fill_key_title(title)
page.fill_key_value(key)
diff --git a/qa/qa/resource/group_access_token.rb b/qa/qa/resource/group_access_token.rb
index a1079b16971..cfb2d1a1bca 100644
--- a/qa/qa/resource/group_access_token.rb
+++ b/qa/qa/resource/group_access_token.rb
@@ -84,6 +84,7 @@ module QA
Page::Group::Menu.perform(&:go_to_access_token_settings)
Page::Group::Settings::AccessTokens.perform do |token_page|
+ token_page.click_add_new_token_button
token_page.fill_token_name(name)
token_page.check_api
token_page.fill_expiry_date(expires_at)
diff --git a/qa/qa/resource/impersonation_token.rb b/qa/qa/resource/impersonation_token.rb
index 99a9cd7bbab..07fb7e0d199 100644
--- a/qa/qa/resource/impersonation_token.rb
+++ b/qa/qa/resource/impersonation_token.rb
@@ -82,6 +82,7 @@ module QA
Page::Admin::Overview::Users::Show.perform do |show|
show.go_to_impersonation_tokens do |impersonation_tokens|
+ impersonation_tokens.click_add_new_token_button
impersonation_tokens.fill_token_name(name)
impersonation_tokens.check_api
impersonation_tokens.fill_expiry_date(expires_at)
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index a39e04c61a3..72b57801053 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -20,6 +20,10 @@ module QA
:title,
:description
+ attribute :confidential do
+ false
+ end
+
def initialize
@assignee_ids = []
@labels = []
@@ -57,7 +61,8 @@ module QA
{
assignee_ids: assignee_ids,
labels: labels,
- title: title
+ title: title,
+ confidential: confidential
}.tap do |hash|
hash[:milestone_id] = @milestone.id if @milestone
hash[:weight] = @weight if @weight
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index 93e8c4f3be6..fdf1a2a97ac 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -25,6 +25,7 @@ module QA
:description,
:merge_when_pipeline_succeeds,
:detailed_merge_status,
+ :prepared_at,
:state,
:reviewers
@@ -110,7 +111,9 @@ module QA
rescue ResourceNotFoundError, NoValueError # rescue if iid not populated
populate_target_and_source_if_required
- super
+ url = super
+ wait_for_preparation
+ url
end
def api_merge_path
@@ -265,6 +268,18 @@ module QA
raise Support::Repeater::WaitExceededError,
"Timed out waiting for merge of MR with id '#{iid}'. Final status was '#{detailed_merge_status}'"
end
+
+ # Wait until the merge request is prepared. Raises WaitExceededError if the MR is not prepared within 60 seconds
+ # https://docs.gitlab.com/ee/api/merge_requests.html#preparation-steps
+ #
+ # @return [void]
+ def wait_for_preparation
+ return if Support::Waiter.wait_until(sleep_interval: 1, raise_on_failure: false, log: false) do
+ reload!.prepared_at
+ end
+
+ raise Support::Repeater::WaitExceededError, "Timed out waiting for MR with id '#{iid}' to be prepared."
+ end
end
end
end
diff --git a/qa/qa/resource/personal_access_token.rb b/qa/qa/resource/personal_access_token.rb
index 33044774c59..9152e28e515 100644
--- a/qa/qa/resource/personal_access_token.rb
+++ b/qa/qa/resource/personal_access_token.rb
@@ -105,6 +105,7 @@ module QA
Page::Profile::Menu.perform(&:click_access_tokens)
Page::Profile::PersonalAccessTokens.perform do |token_page|
+ token_page.click_add_new_token_button
token_page.fill_token_name(name || 'api-test-token')
token_page.check_api
token_page.fill_expiry_date(expires_at)
diff --git a/qa/qa/resource/project_access_token.rb b/qa/qa/resource/project_access_token.rb
index 1ccf2103d1d..8bb782ee6db 100644
--- a/qa/qa/resource/project_access_token.rb
+++ b/qa/qa/resource/project_access_token.rb
@@ -84,6 +84,7 @@ module QA
Page::Project::Menu.perform(&:go_to_access_token_settings)
Page::Project::Settings::AccessTokens.perform do |token_page|
+ token_page.click_add_new_token_button
token_page.fill_token_name(name)
token_page.check_api
token_page.fill_expiry_date(expires_at)
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
index e726f7a316f..b75163deb67 100644
--- a/qa/qa/runtime/allure_report.rb
+++ b/qa/qa/runtime/allure_report.rb
@@ -35,6 +35,9 @@ module QA
config.issue_tag = :issue
config.link_issue_pattern = '{}'
+ # custom grouping of failures, https://docs.qameta.io/allure-report/#_categories_2
+ config.categories = File.new(File.join(Runtime::Path.qa_root, "allure", "categories.json"))
+
if Env.running_in_ci?
config.environment_properties = environment_info
# Set custom environment name to separate same specs executed in different jobs
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 517cb00df41..7c9a6c93335 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -451,6 +451,56 @@ module QA
%w[GCLOUD_ACCOUNT_KEY GCLOUD_ACCOUNT_EMAIL].none? { |var| ENV[var].to_s.empty? }
end
+ # ENV variables for workspaces to run against existing cluster or creating new cluster
+ def workspaces_cluster_available?
+ enabled?(ENV['WORKSPACES_CLUSTER_AVAILABLE'], default: false)
+ end
+
+ def workspaces_cluster_name
+ ENV.fetch("WORKSPACES_CLUSTER_NAME")
+ end
+
+ def workspaces_cluster_region
+ ENV.fetch("WORKSPACES_CLUSTER_REGION")
+ end
+
+ # ENV variables for workspaces OAuth App and the domain
+ def workspaces_oauth_app_id
+ ENV.fetch("WORKSPACES_OAUTH_APP_ID")
+ end
+
+ def workspaces_oauth_app_secret
+ ENV.fetch("WORKSPACES_OAUTH_APP_SECRET")
+ end
+
+ def workspaces_oauth_redirect_uri
+ ENV.fetch("WORKSPACES_OAUTH_REDIRECT_URI")
+ end
+
+ def workspaces_oauth_signing_key
+ ENV.fetch("WORKSPACES_OAUTH_SIGNING_KEY")
+ end
+
+ def workspaces_proxy_domain
+ ENV.fetch("WORKSPACES_PROXY_DOMAIN")
+ end
+
+ def workspaces_domain_cert
+ ENV.fetch("WORKSPACES_DOMAIN_CERT")
+ end
+
+ def workspaces_domain_key
+ ENV.fetch("WORKSPACES_DOMAIN_KEY")
+ end
+
+ def workspaces_wildcard_cert
+ ENV.fetch("WORKSPACES_WILDCARD_CERT")
+ end
+
+ def workspaces_wildcard_key
+ ENV.fetch("WORKSPACES_WILDCARD_KEY")
+ end
+
# Specifies the token that can be used for the GitHub API
def github_access_token
ENV['QA_GITHUB_ACCESS_TOKEN'].to_s.strip
@@ -570,6 +620,10 @@ module QA
enabled?(ENV['QA_SKIP_SMOKE_RELIABLE'], default: false)
end
+ def fips?
+ enabled?(ENV['FIPS'], default: false)
+ end
+
def container_registry_host
ENV.fetch('QA_CONTAINER_REGISTRY_HOST', 'registry.gitlab.com')
end
diff --git a/qa/qa/runtime/fixtures.rb b/qa/qa/runtime/fixtures.rb
index 4319f142bba..7075abc4863 100644
--- a/qa/qa/runtime/fixtures.rb
+++ b/qa/qa/runtime/fixtures.rb
@@ -38,6 +38,10 @@ module QA
File.read(Runtime::Path.fixture(fixture_path, file_name))
end
+ def read_ee_fixture(fixture_path, file_name)
+ File.read(File.join(EE::Runtime::Path.fixtures_path, fixture_path, file_name))
+ end
+
private
def api_client
diff --git a/qa/qa/service/cluster_provider/gcloud.rb b/qa/qa/service/cluster_provider/gcloud.rb
index d33ae4915b5..28eb902b89e 100644
--- a/qa/qa/service/cluster_provider/gcloud.rb
+++ b/qa/qa/service/cluster_provider/gcloud.rb
@@ -27,20 +27,29 @@ module QA
def setup
login_if_not_already_logged_in
create_cluster
+ install_helm
end
def teardown
delete_cluster
end
- def install_kubernetes_agent(agent_token:, kas_address:)
- install_helm
+ def connect
+ login_if_not_already_logged_in
+
+ shell <<~CMD.tr("\n", ' ')
+ gcloud container clusters get-credentials
+ --region #{Runtime::Env.workspaces_cluster_region}
+ #{Runtime::Env.workspaces_cluster_name}
+ CMD
+ end
+ def install_kubernetes_agent(agent_token:, kas_address:, agent_name: "gitlab-agent")
shell <<~CMD.tr("\n", ' ')
helm repo add gitlab https://charts.gitlab.io &&
helm repo update &&
- helm upgrade --install test gitlab/gitlab-agent
- --namespace gitlab-agent
+ helm upgrade --install gitlab-agent gitlab/gitlab-agent
+ --namespace "#{agent_name}"
--create-namespace
--set image.tag=#{Runtime::Env.gitlab_agentk_version}
--set config.token=#{agent_token}
@@ -49,6 +58,68 @@ module QA
CMD
end
+ def uninstall_kubernetes_agent(agent_name: "gitlab-agent")
+ shell <<~CMD.tr("\n", ' ')
+ helm uninstall gitlab-agent \
+ --namespace "#{agent_name}"
+ CMD
+ end
+
+ def install_ngnix_ingress
+ shell <<~CMD.tr("\n", ' ')
+ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx &&
+ helm repo update &&
+ helm install \
+ ingress-nginx ingress-nginx/ingress-nginx \
+ --namespace ingress-nginx \
+ --create-namespace \
+ --version 4.3.0
+ CMD
+ end
+
+ def install_gitlab_workspaces_proxy
+ shell <<~CMD.tr("\n", ' ')
+ helm repo add gitlab-workspaces-proxy \
+ https://gitlab.com/api/v4/projects/gitlab-org%2fremote-development%2fgitlab-workspaces-proxy/packages/helm/devel &&
+ helm repo update &&
+ helm upgrade --install gitlab-workspaces-proxy \
+ gitlab-workspaces-proxy/gitlab-workspaces-proxy \
+ --version 0.1.6 \
+ --namespace=gitlab-workspaces \
+ --create-namespace \
+ --set="auth.client_id=#{Runtime::Env.workspaces_oauth_app_id}" \
+ --set="auth.client_secret=#{Runtime::Env.workspaces_oauth_app_secret}" \
+ --set="auth.host=#{Runtime::Env.gitlab_url}" \
+ --set="auth.redirect_uri=https://#{Runtime::Env.workspaces_proxy_domain}/auth/callback" \
+ --set="auth.signing_key=#{Runtime::Env.workspaces_oauth_signing_key}" \
+ --set="ingress.host.workspaceDomain=#{Runtime::Env.workspaces_proxy_domain}" \
+ --set="ingress.host.wildcardDomain=*.#{Runtime::Env.workspaces_proxy_domain}" \
+ --set="ingress.tls.workspaceDomainCert=#{Runtime::Env.workspaces_domain_cert}" \
+ --set="ingress.tls.workspaceDomainKey=#{Runtime::Env.workspaces_domain_key}" \
+ --set="ingress.tls.wildcardDomainCert=#{Runtime::Env.workspaces_wildcard_cert}" \
+ --set="ingress.tls.wildcardDomainKey=#{Runtime::Env.workspaces_wildcard_key}" \
+ --set="ingress.className=nginx"
+ CMD
+ end
+
+ def update_dns(load_balancer_ip)
+ shell <<~CMD.tr("\n", ' ')
+ gcloud dns record-sets update #{Runtime::Env.workspaces_proxy_domain} \
+ --rrdatas=#{load_balancer_ip} \
+ --ttl=300 \
+ --type=A \
+ --zone=gitlabqa-dev
+ CMD
+
+ shell <<~CMD.tr("\n", ' ')
+ gcloud dns record-sets update "*.#{Runtime::Env.workspaces_proxy_domain}" \
+ --rrdatas=#{load_balancer_ip} \
+ --ttl=300 \
+ --type=A \
+ --zone=gitlabqa-dev
+ CMD
+ end
+
private
def install_helm
@@ -99,7 +170,7 @@ module QA
create #{cluster_name}
#{auth_options}
--region #{@region}
- --disk-size 10GB
+ --disk-size 15GB
--num-nodes #{Runtime::Env.gcloud_num_nodes}
&& gcloud container clusters
get-credentials
diff --git a/qa/qa/service/docker_run/base.rb b/qa/qa/service/docker_run/base.rb
index d6b50db7fa9..3bd7912958f 100644
--- a/qa/qa/service/docker_run/base.rb
+++ b/qa/qa/service/docker_run/base.rb
@@ -111,8 +111,14 @@ module QA
# @return [String]
def host_ip
docker_host = shell("docker context inspect --format='{{json .Endpoints.docker.Host}}'").delete('"')
- ip = Addrinfo.tcp(URI(docker_host).host, nil).ip_address
+ hostname = URI(docker_host).host
+ # The docker host could be bound to a Unix socket, in which case as a URI it has no host
+ host = hostname.presence || Socket.gethostname
+ ip = Addrinfo.tcp(host, nil).ip_address
ip == '0.0.0.0' ? '127.0.0.1' : ip
+ rescue SocketError
+ # If the host could not be resolved, fallback on localhost
+ '127.0.0.1'
end
end
end
diff --git a/qa/qa/service/docker_run/gitlab_runner.rb b/qa/qa/service/docker_run/gitlab_runner.rb
index b0bb999e5d6..b3f9d91e933 100644
--- a/qa/qa/service/docker_run/gitlab_runner.rb
+++ b/qa/qa/service/docker_run/gitlab_runner.rb
@@ -40,7 +40,7 @@ module QA
raise("Missing runner token value!") unless token
cmd = <<~CMD.tr("\n", ' ')
- docker run -d --rm --network #{network} --name #{@name}
+ docker run -d --rm --network #{network} --name #{@name} #{'--user=root' if Runtime::Env.fips?}
#{'-v /var/run/docker.sock:/var/run/docker.sock' if @executor == :docker}
--privileged
#{"--add-host gdk.test:#{gdk_host_ip}" if gdk_network}
diff --git a/qa/qa/service/docker_run/smocker.rb b/qa/qa/service/docker_run/smocker.rb
index 59f32e29b44..dbc32a22c6e 100644
--- a/qa/qa/service/docker_run/smocker.rb
+++ b/qa/qa/service/docker_run/smocker.rb
@@ -45,9 +45,11 @@ module QA
attr_reader :public_port, :admin_port
def host_name
- return host_ip unless QA::Runtime::Env.running_in_ci? || QA::Runtime::Env.qa_hostname
-
- "#{@name}.#{@network_cache}"
+ @host_name ||= if QA::Runtime::Env.running_in_ci? || QA::Runtime::Env.qa_hostname
+ "#{@name}.#{@network_cache}"
+ else
+ host_ip
+ end
end
def wait_for_running
diff --git a/qa/qa/service/kubernetes_cluster.rb b/qa/qa/service/kubernetes_cluster.rb
index ed57d825643..d1cabc58f76 100644
--- a/qa/qa/service/kubernetes_cluster.rb
+++ b/qa/qa/service/kubernetes_cluster.rb
@@ -24,6 +24,15 @@ module QA
self
end
+ def connect!
+ validate_dependencies
+
+ @provider.validate_dependencies
+ @provider.connect
+
+ self
+ end
+
def remove!
@provider.teardown
end
@@ -36,8 +45,24 @@ module QA
cluster_name
end
- def install_kubernetes_agent(agent_token)
- @provider.install_kubernetes_agent(agent_token: agent_token, kas_address: fetch_kas_address)
+ def install_kubernetes_agent(agent_token, agent_name)
+ @provider.install_kubernetes_agent(agent_token: agent_token, kas_address: fetch_kas_address,
+ agent_name: agent_name)
+ end
+
+ def uninstall_kubernetes_agent(agent_name)
+ @provider.uninstall_kubernetes_agent(agent_name: agent_name)
+ end
+
+ def setup_workspaces_in_cluster
+ @provider.install_ngnix_ingress
+ @provider.install_gitlab_workspaces_proxy
+ end
+
+ def update_dns_with_load_balancer_ip
+ load_balancer_ip = shell("kubectl -n ingress-nginx get svc ingress-nginx-controller \
+ -o jsonpath='{.status.loadBalancer.ingress[0].ip}'")
+ @provider.update_dns(load_balancer_ip)
end
def create_secret(secret, secret_name)
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb
index 425ab0fa162..6990aa0e08e 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb
@@ -34,11 +34,7 @@ module QA
let(:source_storage) { { type: :gitaly, name: 'default' } }
let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.additional_repository_storage } }
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'repo-storage-move-status'
- project.initialize_with_readme = true
- project.api_client = Runtime::API::Client.as_admin
- end
+ create(:project, :with_readme, name: 'repo-storage-move-status', api_client: Runtime::API::Client.as_admin)
end
before do
@@ -56,12 +52,11 @@ module QA
let(:source_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } }
let(:destination_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } }
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'repo-storage-move'
- project.initialize_with_readme = true
- project.repository_storage = source_storage[:name]
- project.api_client = Runtime::API::Client.as_admin
- end
+ create(:project,
+ :with_readme,
+ name: 'repo-storage-move',
+ repository_storage: source_storage[:name],
+ api_client: Runtime::API::Client.as_admin)
end
before do
@@ -79,12 +74,11 @@ module QA
let(:source_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } }
let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } }
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'repo-storage-move'
- project.initialize_with_readme = true
- project.repository_storage = source_storage[:name]
- project.api_client = Runtime::API::Client.as_admin
- end
+ create(:project,
+ :with_readme,
+ name: 'repo-storage-move',
+ repository_storage: source_storage[:name],
+ api_client: Runtime::API::Client.as_admin)
end
before do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
index ac85795b2bb..75203584edd 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
@@ -7,11 +7,10 @@ module QA
describe "Gitlab migration" do
context 'with subgroups and labels' do
let(:subgroup) do
- Resource::Group.fabricate_via_api! do |group|
- group.api_client = source_admin_api_client
- group.sandbox = source_group
- group.path = "subgroup-for-import-#{SecureRandom.hex(4)}"
- end
+ create(:group,
+ path: "subgroup-for-import-#{SecureRandom.hex(4)}",
+ sandbox: source_group,
+ api_client: source_admin_api_client)
end
let(:imported_subgroup) do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
index 7cbccf9be44..100b50abfdb 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
@@ -13,19 +13,14 @@ module QA
# do not use top level group (sandbox) to avoid issues when applying permissions etc. because it will contain
# a lot subgroups and projects on live envs
- let!(:source_sandbox) do
- Resource::Group.fabricate_via_api! do |group|
- group.api_client = admin_api_client
- end
- end
+ let!(:source_sandbox) { create(:group, api_client: admin_api_client) }
let!(:source_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.api_client = admin_api_client
- group.sandbox = source_sandbox
- group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
- group.avatar = File.new(Runtime::Path.fixture('designs', 'tanuki.jpg'), 'r')
- end
+ create(:group,
+ api_client: admin_api_client,
+ sandbox: source_sandbox,
+ path: "source-group-for-import-#{SecureRandom.hex(4)}",
+ avatar: File.new(Runtime::Path.fixture('designs', 'tanuki.jpg'), 'r'))
end
let!(:target_sandbox) { source_sandbox }
diff --git a/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb b/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
index eeeb78e17d7..af0eef290f7 100644
--- a/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
@@ -5,9 +5,7 @@ module QA
describe 'Project access token', product_group: :authentication_and_authorization do
before(:all) do
@project_access_token = QA::Resource::ProjectAccessToken.fabricate_via_api! do |pat|
- pat.project = Resource::Project.fabricate_via_api! do |project|
- project.initialize_with_readme = true
- end
+ pat.project = create(:project, :with_readme)
end
@user_api_client = Runtime::API::Client.new(:gitlab, personal_access_token: @project_access_token.token)
diff --git a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
index 8759c36f43f..578891b2722 100644
--- a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
@@ -13,23 +13,13 @@ module QA
@user_api_client = Runtime::API::Client.new(:gitlab, user: @user)
- @sandbox = Resource::Sandbox.fabricate! do |sandbox_group|
- sandbox_group.path = "sandbox-for-access-termination-#{SecureRandom.hex(4)}"
- sandbox_group.api_client = admin_api_client
- end
+ @sandbox = create(:sandbox, path: "sandbox-for-access-termination-#{SecureRandom.hex(4)}", api_client: admin_api_client)
- group = QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "group-to-test-access-termination-#{SecureRandom.hex(8)}"
- group.sandbox = @sandbox
- end
+ group = create(:group, path: "group-to-test-access-termination-#{SecureRandom.hex(8)}", sandbox: @sandbox)
@sandbox.add_member(@user)
- @project = Resource::Project.fabricate_via_api! do |project|
- project.group = group
- project.name = "project-for-user-group-access-termination"
- project.initialize_with_readme = true
- end
+ @project = create(:project, :with_readme, name: 'project-for-user-group-access-termination', group: group)
end
context 'after parent group membership termination' do
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb
index fc00d851087..1edf1d942be 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options', product_group: :code_review do
+ describe 'Merge request push options', :reliable, product_group: :code_review do
# If run locally on GDK, push options need to be enabled on the host with the following command:
#
# git config --global receive.advertisepushoptions true
@@ -10,11 +10,7 @@ module QA
let(:branch) { "push-options-test-#{SecureRandom.hex(8)}" }
let(:title) { "MR push options test #{SecureRandom.hex(8)}" }
let(:commit_message) { 'Add README.md' }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme) }
def create_new_mr_via_push
Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb
index 9fed6787ade..5c4fc8cef56 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb
@@ -10,12 +10,7 @@ module QA
let(:branch) { "push-options-test-#{SecureRandom.hex(8)}" }
let(:title) { "MR push options test #{SecureRandom.hex(8)}" }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'merge-request-push-options'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'merge-request-push-options') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
@@ -74,7 +69,14 @@ module QA
end
end
- it 'merges when pipeline succeeds', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347842' do
+ it(
+ 'merges when pipeline succeeds',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347842',
+ quarantine: {
+ type: :flaky,
+ issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/346425"
+ }
+ ) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb
index 11328c2f517..9c27793a52d 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb
@@ -2,20 +2,14 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options', product_group: :code_review do
+ describe 'Merge request push options', :reliable, product_group: :code_review do
# If run locally on GDK, push options need to be enabled on the host with the following command:
#
# git config --global receive.advertisepushoptions true
let(:branch) { "push-options-test-#{SecureRandom.hex(8)}" }
let(:title) { "MR push options test #{SecureRandom.hex(8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'merge-request-push-options'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'merge-request-push-options') }
it 'removes the source branch', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347841' do
Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb
index eb7d3da0f97..1a5b6f88f4f 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb
@@ -2,19 +2,14 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options', product_group: :code_review do
+ describe 'Merge request push options', :reliable, product_group: :code_review do
# If run locally on GDK, push options need to be enabled on the host with the following command:
#
# git config --global receive.advertisepushoptions true
let(:title) { "MR push options test #{SecureRandom.hex(8)}" }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'merge-request-push-options'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'merge-request-push-options') }
it 'sets a target branch', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347726' do
target_branch = "push-options-test-target-#{SecureRandom.hex(8)}"
diff --git a/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb b/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb
index dd297f47975..4e8a5a426d4 100644
--- a/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb
+++ b/qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb
@@ -2,17 +2,12 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options', product_group: :code_review do
+ describe 'Merge request push options', :reliable, product_group: :code_review do
# If run locally on GDK, push options need to be enabled on the host with the following command:
#
# git config --global receive.advertisepushoptions true
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'merge-request-push-options'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'merge-request-push-options') }
it 'sets title and description', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347844' do
description = "This is a test of MR push options"
diff --git a/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb
index f69a8a4dfa5..2f7cef2112e 100644
--- a/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb
@@ -2,12 +2,7 @@
module QA
RSpec.describe 'Create' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-qa-test'
- project.description = 'project for qa test'
- end
- end
+ let(:project) { create(:project, name: 'project-qa-test', description: 'project for qa test') }
describe 'Create, Retrieve and Delete branches via API', :requires_admin, product_group: :source_code do
created_branch = 'create-branch'
diff --git a/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb b/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb
index 4ee436a597a..74d1c9e3e94 100644
--- a/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Create a new project from a template', product_group: :source_code do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'templated-project'
- project.template_name = 'dotnetcore'
- end
- end
+ let(:project) { create(:project, name: 'templated-project', template_name: 'dotnetcore') }
it 'commits via the api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/357234' do
expect do
diff --git a/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb b/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb
index 123a4a625ab..a512bb76560 100644
--- a/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb
@@ -12,10 +12,7 @@ module QA
end
it 'sets the default branch name for a new project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347837' do
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = "default-branch-name"
- project.initialize_with_readme = true
- end
+ project = create(:project, :with_readme, name: 'default-branch-name')
# It takes a moment to create the project. We wait until we
# know it exists before we try to clone it
@@ -32,7 +29,7 @@ module QA
it 'allows a project to be created via the CLI with a different default branch name', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347838' do
project_name = "default-branch-name-via-cli-#{SecureRandom.hex(8)}"
- group = Resource::Group.fabricate_via_api!
+ group = create(:group)
Git::Repository.perform do |repository|
repository.init_repository
diff --git a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
index d72672e2104..87faec86947 100644
--- a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb
@@ -46,12 +46,7 @@ module QA
end
def create_project(user, api_client, project_name)
- project = Resource::Project.fabricate_via_api! do |project|
- project.personal_namespace = user.username
- project.add_name_uuid = false
- project.name = project_name
- project.api_client = api_client
- end
+ project = create(:project, name: project_name, api_client: api_client, add_name_uuid: false, personal_namespace: user.username)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb b/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb
index 1d41184df98..df61dd43bb0 100644
--- a/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb
@@ -6,12 +6,7 @@ module QA
# Tests that a push does not result in multiple changes from repeated PostReceive executions.
# One of the consequences would be duplicate push events
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'push-postreceive-idempotent'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'push-postreceive-idempotent') }
after do
project&.remove_via_api!
diff --git a/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb b/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb
index 8c7a58be43a..72ce2dda053 100644
--- a/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb
@@ -30,9 +30,7 @@ module QA
# attempt to detect large differences that could indicate a regression to previous behavior.
it 'matches cloned repo usage to reported usage',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/365196' do
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = project_name
- end
+ project = create(:project, name: project_name)
shared_data = SecureRandom.random_bytes(500000)
diff --git a/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb b/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb
index 700cf69da80..d0f1ee66488 100644
--- a/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb
@@ -3,11 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Prereceive hook', product_group: :source_code do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme) }
context 'when creating a tag for a ref' do
context 'when it triggers a prereceive hook configured with a custom error' do
diff --git a/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb b/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb
index a360c662cf8..5b0e0573016 100644
--- a/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb
+++ b/qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb
@@ -12,11 +12,7 @@ module QA
end
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-canceled-schedule'
- end
- end
+ let(:project) { create(:project, name: 'project-for-canceled-schedule') }
before do
project.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
diff --git a/qa/qa/specs/features/api/4_verify/file_variable_downstream_pipeline_spec.rb b/qa/qa/specs/features/api/4_verify/file_variable_downstream_pipeline_spec.rb
new file mode 100644
index 00000000000..289133b33cc
--- /dev/null
+++ b/qa/qa/specs/features/api/4_verify/file_variable_downstream_pipeline_spec.rb
@@ -0,0 +1,231 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_security, feature_flag: {
+ name: 'ci_prevent_file_var_expansion_downstream_pipeline',
+ scope: :project
+ } do
+ describe 'Pipeline with file variables and downstream pipelines' do
+ let(:random_string) { Faker::Alphanumeric.alphanumeric(number: 8) }
+ let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
+ let!(:project) { create(:project, name: 'upstream-project-with-file-variables') }
+ let!(:downstream_project) { create(:project, name: 'downstream-project') }
+
+ let!(:project_runner) do
+ Resource::ProjectRunner.fabricate! do |runner|
+ runner.project = project
+ runner.name = executor
+ runner.tags = [executor]
+ end
+ end
+
+ let!(:downstream_project_runner) do
+ Resource::ProjectRunner.fabricate! do |runner|
+ runner.project = downstream_project
+ runner.name = "#{executor}-downstream"
+ runner.tags = [executor]
+ end
+ end
+
+ let(:add_ci_file) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml and child.yml'
+ commit.add_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ default:
+ tags: [#{executor}]
+
+ variables:
+ EXTRA_ARGS: "-f $TEST_PROJECT_FILE"
+ DOCKER_REMOTE_ARGS: --tlscacert="$DOCKER_CA_CERT"
+ EXTRACTED_CRT_FILE: ${DOCKER_CA_CERT}.crt
+ MY_FILE_VAR: $TEST_PROJECT_FILE
+
+ trigger_child:
+ trigger:
+ strategy: depend
+ include:
+ - local: child.yml
+
+ trigger_downstream_project:
+ trigger:
+ strategy: depend
+ project: #{downstream_project.path_with_namespace}
+
+ YAML
+ },
+ {
+ file_path: 'child.yml',
+ content: <<~YAML
+ default:
+ tags: [#{executor}]
+
+ child_job_echo:
+ script:
+ - echo "run something $EXTRA_ARGS"
+ - echo "docker run $DOCKER_REMOTE_ARGS"
+ - echo "run --output=$EXTRACTED_CRT_FILE"
+ - echo "Will read private key from $MY_FILE_VAR"
+
+ child_job_cat:
+ script:
+ - cat "$MY_FILE_VAR"
+ - cat "$DOCKER_CA_CERT"
+ YAML
+ }
+ ]
+ )
+ end
+ end
+
+ let(:add_downstream_project_ci_file) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = downstream_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ default:
+ tags: [#{executor}]
+
+ downstream_job_echo:
+ script:
+ - echo "run something $EXTRA_ARGS"
+ - echo "docker run $DOCKER_REMOTE_ARGS"
+ - echo "run --output=$EXTRACTED_CRT_FILE"
+ - echo "Will read private key from $MY_FILE_VAR"
+
+ downstream_job_cat:
+ script:
+ - cat "$MY_FILE_VAR"
+ - cat "$DOCKER_CA_CERT"
+ YAML
+ }
+ ]
+ )
+ end
+ end
+
+ let(:add_project_file_variables) do
+ {
+ 'TEST_PROJECT_FILE' => "hello, this is test\n",
+ 'DOCKER_CA_CERT' => "This is secret\n"
+ }.each do |file_name, content|
+ add_file_variable_to_project(project, file_name, content)
+ end
+ end
+
+ let(:upstream_pipeline) do
+ Resource::Pipeline.fabricate_via_api! do |pipeline|
+ pipeline.project = project
+ end
+ end
+
+ def child_pipeline
+ Resource::Pipeline.fabricate_via_api! do |pipeline|
+ pipeline.project = project
+ pipeline.id = upstream_pipeline.downstream_pipeline_id(bridge_name: 'trigger_child')
+ end
+ end
+
+ def downstream_project_pipeline
+ Resource::Pipeline.fabricate_via_api! do |pipeline|
+ pipeline.project = downstream_project
+ pipeline.id = upstream_pipeline.downstream_pipeline_id(bridge_name: 'trigger_downstream_project')
+ end
+ end
+
+ around do |example|
+ Runtime::Feature.enable(:ci_prevent_file_var_expansion_downstream_pipeline, project: project)
+ example.run
+ Runtime::Feature.disable(:ci_prevent_file_var_expansion_downstream_pipeline, project: project)
+ end
+
+ before do
+ add_project_file_variables
+ add_downstream_project_ci_file
+ add_ci_file
+ upstream_pipeline
+ wait_for_pipelines
+ end
+
+ after do
+ project_runner.remove_via_api!
+ downstream_project_runner.remove_via_api!
+ end
+
+ it(
+ 'creates variable with file path in downstream pipelines and can read file variable content',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/416337'
+ ) do
+ child_echo_job = Resource::Job.fabricate_via_api! do |job|
+ job.project = project
+ job.id = project.job_by_name('child_job_echo')[:id]
+ end
+
+ child_cat_job = Resource::Job.fabricate_via_api! do |job|
+ job.project = project
+ job.id = project.job_by_name('child_job_cat')[:id]
+ end
+
+ downstream_project_echo_job = Resource::Job.fabricate_via_api! do |job|
+ job.project = downstream_project
+ job.id = downstream_project.job_by_name('downstream_job_echo')[:id]
+ end
+
+ downstream_project_cat_job = Resource::Job.fabricate_via_api! do |job|
+ job.project = downstream_project
+ job.id = downstream_project.job_by_name('downstream_job_cat')[:id]
+ end
+
+ aggregate_failures do
+ trace = child_echo_job.trace
+ expect(trace).to include('run something -f', "#{project.name}.tmp/TEST_PROJECT_FILE")
+ expect(trace).to include('docker run --tlscacert=', "#{project.name}.tmp/DOCKER_CA_CERT")
+ expect(trace).to include('run --output=', "#{project.name}.tmp/DOCKER_CA_CERT.crt")
+ expect(trace).to include('Will read private key from', "#{project.name}.tmp/TEST_PROJECT_FILE")
+
+ trace = child_cat_job.trace
+ expect(trace).to have_content('hello, this is test')
+ expect(trace).to have_content('This is secret')
+
+ trace = downstream_project_echo_job.trace
+ expect(trace).to include('run something -f', "#{downstream_project.name}.tmp/TEST_PROJECT_FILE")
+ expect(trace).to include('docker run --tlscacert=', "#{downstream_project.name}.tmp/DOCKER_CA_CERT")
+ expect(trace).to include('run --output=', "#{downstream_project.name}.tmp/DOCKER_CA_CERT.crt")
+ expect(trace).to include('Will read private key from', "#{downstream_project.name}.tmp/TEST_PROJECT_FILE")
+
+ trace = downstream_project_cat_job.trace
+ expect(trace).to have_content('hello, this is test')
+ expect(trace).to have_content('This is secret')
+ end
+ end
+
+ private
+
+ def add_file_variable_to_project(project, key, value)
+ Resource::CiVariable.fabricate_via_api! do |ci_variable|
+ ci_variable.project = project
+ ci_variable.key = key
+ ci_variable.value = value
+ ci_variable.variable_type = 'file'
+ end
+ end
+
+ def wait_for_pipelines
+ Support::Waiter.wait_until(max_duration: 300, sleep_interval: 10) do
+ upstream_pipeline.reload!
+ upstream_pipeline.status == 'success' &&
+ child_pipeline.status == 'success' &&
+ downstream_project_pipeline.status == 'success'
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/4_verify/file_variable_spec.rb b/qa/qa/specs/features/api/4_verify/file_variable_spec.rb
index 2d9deec399c..d7adc1d8454 100644
--- a/qa/qa/specs/features/api/4_verify/file_variable_spec.rb
+++ b/qa/qa/specs/features/api/4_verify/file_variable_spec.rb
@@ -4,12 +4,7 @@ module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_security do
describe 'Pipeline with project file variables' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-file-variables'
- end
- end
+ let(:project) { create(:project, name: 'project-with-file-variables') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb b/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
index 23d8585d07a..d2b1cbd2c95 100644
--- a/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
+++ b/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
@@ -12,11 +12,7 @@ module QA
let(:api_client) { Runtime::API::Client.new(:gitlab) }
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-registry-api'
- project.template_name = 'express'
- project.api_client = api_client
- end
+ create(:project, name: 'project-with-registry-api', template_name: 'express', api_client: api_client)
end
let!(:runner) do
diff --git a/qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb b/qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb
index 48e9d3dc164..6f8b6df6658 100644
--- a/qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb
@@ -5,17 +5,10 @@ module QA
describe 'User', :requires_admin, product_group: :tenant_scale do
let(:admin_api_client) { Runtime::API::Client.as_admin }
- let!(:parent_group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "parent-group-to-test-user-access-#{SecureRandom.hex(8)}"
- end
- end
+ let!(:parent_group) { create(:group, path: "parent-group-to-test-user-access-#{SecureRandom.hex(8)}") }
let!(:sub_group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "sub-group-to-test-user-access-#{SecureRandom.hex(8)}"
- group.sandbox = parent_group
- end
+ create(:group, path: "sub-group-to-test-user-access-#{SecureRandom.hex(8)}", sandbox: parent_group)
end
context 'when added to parent group' do
@@ -30,11 +23,7 @@ module QA
end
let!(:sub_group_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = sub_group
- project.name = "sub-group-project-to-test-user-access"
- project.initialize_with_readme = true
- end
+ create(:project, :with_readme, name: 'sub-groupd-project-to-test-user-access', group: sub_group)
end
before do
@@ -106,11 +95,7 @@ module QA
context 'when added to sub-group' do
let!(:parent_group_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = parent_group
- project.name = "parent-group-project-to-test-user-access"
- project.initialize_with_readme = true
- end
+ create(:project, :with_readme, name: 'parent-group-project-to-test-user-access', group: parent_group)
end
let!(:sub_group_user) do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb
index 63c57ad455b..f40d953acd2 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb
@@ -15,18 +15,9 @@ module QA
end
let(:jenkins_project_name) { "gitlab_jenkins_#{SecureRandom.hex(5)}" }
-
let(:connection_name) { 'gitlab-connection' }
-
let(:project_name) { "project_with_jenkins_#{SecureRandom.hex(4)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = project_name
- project.initialize_with_readme = true
- project.auto_devops_enabled = false
- end
- end
+ let(:project) { create(:project, :with_readme, name: project_name) }
let(:access_token) do
Runtime::Env.personal_access_token ||= fabricate_access_token
diff --git a/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb
index 1bd819ad87d..f336a0d5d82 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb
@@ -6,11 +6,7 @@ module QA
describe 'Jira integration', :jira, :orchestrated, :requires_admin, product_group: :import_and_integrate do
let(:jira_project_key) { 'JITP' }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "project_with_jira_integration"
- end
- end
+ let(:project) { create(:project, name: 'project_with_jira_integration') }
before do
page.visit Vendor::Jira::JiraAPI.perform(&:base_url)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
index 02224406e6d..15b6d74c7f1 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
@@ -8,11 +8,7 @@ module QA
let(:jira_issue_description) { "This issue is for testing importing Jira issues to GitLab." }
let(:jira_issue_label_1) { "jira-import::#{jira_project_key}-1" }
let(:jira_issue_label_2) { "QA" }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "jira_issue_import"
- end
- end
+ let(:project) { create(:project, name: "jira_issue_import") }
it 'imports issues from Jira', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347966' do
set_up_jira_integration
diff --git a/qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb
index 1ea19144a74..c19ebd9f7a7 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb
@@ -28,12 +28,7 @@ module QA
describe 'Pipeline status emails' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:emails) { %w[foo@bar.com baz@buzz.com] }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-status-project'
- end
- end
+ let(:project) { create(:project, name: 'pipeline-status-project') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/integrations/slash_commands_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/slash_commands_spec.rb
index f5e33cb5b1e..99be4e87251 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/integrations/slash_commands_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/slash_commands_spec.rb
@@ -10,13 +10,7 @@ module QA
# state to be used in the GitLab API
let(:project_name) { "project_with_slack" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = project_name
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: project_name) }
before(:context) do
Runtime::Env.require_slack_env!
@@ -101,12 +95,7 @@ module QA
end
context 'with target project' do
- let(:target) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'target_slack_project'
- project.initialize_with_readme = true
- end
- end
+ let(:target) { create(:project, :with_readme, name: 'target_slack_project') }
after do
target.remove_via_api!
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
index 0f3d6a104a7..f2582d47723 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
@@ -23,11 +23,7 @@ module QA
end
let(:group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.sandbox = sandbox_group
- group.api_client = owner_api_client
- group.require_two_factor_authentication = true
- end
+ create(:group, :require_2fa, sandbox: sandbox_group, api_client: owner_api_client)
end
before do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
index 84664cb8b94..89f15759b54 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :requires_admin, :skip_live_env, product_group: :authentication_and_authorization do
+ RSpec.describe 'Manage', :requires_admin, product_group: :authentication_and_authorization do
describe '2FA' do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let(:owner_api_client) { Runtime::API::Client.new(:gitlab, user: owner_user) }
@@ -14,6 +14,7 @@ module QA
end
let(:sandbox_group) do
+ Flow::Login.sign_in(as: owner_user)
Resource::Sandbox.fabricate! do |sandbox_group|
sandbox_group.path = "gitlab-qa-2fa-sandbox-group-#{SecureRandom.hex(8)}"
sandbox_group.api_client = owner_api_client
@@ -21,11 +22,7 @@ module QA
end
let(:group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.sandbox = sandbox_group
- group.api_client = owner_api_client
- group.path = "group-with-2fa-#{SecureRandom.hex(8)}"
- end
+ create(:group, sandbox: sandbox_group, api_client: owner_api_client, path: "group-with-2fa-#{SecureRandom.hex(8)}")
end
let(:developer_user) do
@@ -46,7 +43,7 @@ module QA
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931',
quarantine: {
type: :bug,
- only: { condition: -> { !QA::Runtime::Env.super_sidebar_enabled? } },
+ only: { condition: -> { QA::Runtime::Env.super_sidebar_enabled? } },
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/409336'
}
) do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
index 1a53fda4cdb..afc7e8202e2 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
@@ -9,11 +9,7 @@ module QA
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'email-notification-test'
- end
- end
+ let(:project) { create(:project, name: 'email-notification-test') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
index 2f177d12389..5d8f9f7d7b3 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
@@ -10,11 +10,7 @@ module QA
end
end
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'xss-test-for-mentions-project'
- end
- end
+ let!(:project) { create(:project, name: 'xss-test-for-mentions-project') }
describe 'check xss occurence in @mentions in issues', :requires_admin do
before do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
index f7dc9157275..2fe88c543de 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
@@ -6,7 +6,7 @@ module QA
before do
Flow::Login.sign_in
- Resource::Issue.fabricate_via_api!.visit!
+ create(:issue).visit!
end
it 'comments on an issue and edits the comment', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347978' do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
index bad312bb392..c489a61ca2a 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
@@ -7,10 +7,7 @@ module QA
let(:template_content) { 'This is a custom issue template test' }
let(:template_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "custom-issue-template-project"
- project.initialize_with_readme = true
- end
+ create(:project, :with_readme, name: 'custom-issue-template-project')
end
before do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
index 5e989cdb03f..45c7f307834 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
@@ -3,11 +3,7 @@
module QA
RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Issues list' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-to-test-export-issues-as-csv'
- end
- end
+ let(:project) { create(:project, name: 'project-to-test-export-issues-as-csv') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
index 060e52276a9..d282b0dbbd5 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
@@ -5,11 +5,7 @@ module QA
describe 'Assignees' do
let(:user1) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:user2) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-to-test-assignees'
- end
- end
+ let(:project) { create(:project, name: 'project-to-test-assignees') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
index 7377b0ff8af..92a67437d06 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
@@ -3,11 +3,7 @@
module QA
RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Issue board focus mode' do
- let(:project) do
- QA::Resource::Project.fabricate_via_api! do |project|
- project.name = 'sample-project-issue-board-focus-mode'
- end
- end
+ let(:project) { create(:project, name: 'sample-project-issue-board-focus-mode') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb
index 56e110e6f61..c3c2ad68abf 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb
@@ -8,18 +8,9 @@ module QA
let(:start_date) { current_date_yyyy_mm_dd }
let(:due_date) { next_month_yyyy_mm_dd }
- let(:group) do
- Resource::Group.fabricate_via_api! do |group|
- group.name = "group-to-test-milestones-#{SecureRandom.hex(4)}"
- end
- end
+ let(:group) { create(:group, name: "group-to-test-milestones-#{SecureRandom.hex(4)}") }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "project-to-test-milestones-#{SecureRandom.hex(4)}"
- project.group = group
- end
- end
+ let(:project) { create(:project, name: "project-to-test-milestones-#{SecureRandom.hex(4)}", group: group) }
let(:issue) do
Resource::Issue.fabricate_via_api! do |issue|
diff --git a/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb
index 919b4b2c46e..3d4ec8a422e 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb
@@ -12,13 +12,7 @@ module QA
feature_flag: { name: 'show_pages_in_deployments_menu' } do
# TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300906
describe 'Pages', product_group: :knowledge do
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'gitlab-pages-project'
- project.template_name = :plainhtml
- end
- end
-
+ let!(:project) { create(:project, name: 'gitlab-pages-projects', template_name: :plainhtml) }
let(:pipeline) do
Resource::Pipeline.fabricate_via_api! do |pipeline|
pipeline.project = project
diff --git a/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_content_creation_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_content_creation_spec.rb
index e1f73acd375..19c9ac6c238 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_content_creation_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_content_creation_spec.rb
@@ -7,7 +7,7 @@ module QA
let(:new_wiki_content) { "this content is changed or added" }
let(:commit_message) { "this is a new addition to the wiki" }
- let(:project) { Resource::Project.fabricate_via_api! }
+ let(:project) { create(:project) }
let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
before do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb
index 197e283c93b..87a0cf1b310 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Related issues' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-to-test-related-issues'
- end
- end
-
+ let(:project) { create(:project, name: 'project-to-test-related-issues') }
let(:issue_1) do
Resource::Issue.fabricate_via_api! do |issue|
issue.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb
index 8f99644bd24..0e5806a00ff 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb
@@ -2,14 +2,8 @@
module QA
RSpec.describe 'Create' do
- describe 'Cherry picking from a merge request', product_group: :code_review do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project'
- project.initialize_with_readme = true
- end
- end
-
+ describe 'Cherry picking from a merge request', :reliable, product_group: :code_review do
+ let(:project) { create(:project, :with_readme) }
let(:feature_mr) do
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
index 111adf32a69..fa4a1293025 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
@@ -2,16 +2,9 @@
module QA
RSpec.describe 'Create' do
- describe 'Cherry picking a commit', product_group: :code_review do
+ describe 'Cherry picking a commit', :reliable, product_group: :code_review do
let(:file_name) { "secret_file.md" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project'
- project.initialize_with_readme = true
- end
- end
-
+ let(:project) { create(:project, :with_readme) }
let(:commit) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_from_push_notification_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_from_push_notification_spec.rb
index 509714fb5a4..ed44017db75 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_from_push_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_from_push_notification_spec.rb
@@ -2,14 +2,11 @@
module QA
RSpec.describe 'Create' do
- describe 'Create a new merge request from the event notification after a push', product_group: :code_review do
+ describe 'Create a new merge request from the event notification after a push', :reliable,
+ product_group: :code_review do
let(:branch_name) { "merge-request-test-#{SecureRandom.hex(8)}" }
let(:title) { "Merge from push event notification test #{SecureRandom.hex(8)}" }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme) }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
index fcce6bb291c..89b43e88bde 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Create a new merge request', product_group: :code_review do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project'
- end
- end
-
+ let(:project) { create(:project) }
let(:merge_request_title) { 'One merge request to rule them all' }
let(:merge_request_description) { '... to find them, to bring them all, and in the darkness bind them' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
index 1ce9430290f..4072416374a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
@@ -5,13 +5,7 @@ module QA
describe 'Merge request custom templates' do
let(:template_name) { 'custom_merge_request_template' }
let(:template_content) { 'This is a custom merge request template test' }
- let(:template_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'custom-mr-template-project'
- project.initialize_with_readme = true
- end
- end
-
+ let(:template_project) { create(:project, :with_readme, name: 'custom-mr-template-project') }
let(:merge_request_title) { 'One merge request to rule them all' }
before do
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
index 38831f6f158..cad50fc032b 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
@@ -5,14 +5,7 @@ module QA
describe 'Merge requests' do
shared_examples 'merge when pipeline succeeds' do |repeat: 1|
let(:runner_name) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'merge-when-pipeline-succeeds'
- project.initialize_with_readme = true
- end
- end
-
+ let(:project) { create(:project, :with_readme, name: 'merge-when-pipeline-succeeds') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
index a79c56bd051..5e3260fb44f 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
@@ -4,14 +4,7 @@ module QA
RSpec.describe 'Create', :reliable, product_group: :code_review do
describe 'Reverting a commit' do
let(:file_name) { "secret_file.md" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project'
- project.initialize_with_readme = true
- end
- end
-
+ let(:project) { create(:project, :with_readme) }
let(:commit) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb
index a7071d5fe1b..8f85bab8677 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Merged merge request', :requires_admin, product_group: :code_review do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'revert'
- end
- end
-
+ let(:project) { create(:project) }
let(:revertible_merge_request) do
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
index a127b846eb9..33d5a5b050e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
@@ -2,13 +2,8 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request squashing', product_group: :code_review do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "squash-before-merge"
- end
- end
-
+ describe 'Merge request squashing', :reliable, product_group: :code_review do
+ let(:project) { create(:project, name: 'squash-before-merge') }
let(:merge_request) do
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
index 297f91be0bb..c69db9cf7b5 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
@@ -2,13 +2,8 @@
module QA
RSpec.describe 'Create', :reliable, product_group: :code_review do
- context 'with merge request batch suggestions' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'suggestions_project'
- end
- end
-
+ describe 'Merge request batch suggestions' do
+ let(:project) { create(:project, name: 'batch-suggestions-project') }
let(:merge_request) do
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
index ce32f4aadca..8a7fb2021e6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
@@ -2,15 +2,9 @@
module QA
RSpec.describe 'Create' do
- context 'with merge request suggestions', product_group: :code_review do
+ describe 'Merge request suggestions', :reliable, product_group: :code_review do
let(:commit_message) { 'Applying suggested change for testing purposes.' }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'suggestions_project'
- end
- end
-
+ let(:project) { create(:project, name: 'mr-suggestions-project') }
let(:merge_request) do
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
index 3b332e6b9f5..09967b05ffa 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Download merge request patch and diff', :requires_admin, product_group: :code_review do
+ describe 'Download merge request patch and diff', :reliable, :requires_admin, product_group: :code_review do
let(:merge_request) do
Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.title = 'This is a merge request'
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
index 7d21c635347..0a311a42863 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb
@@ -6,11 +6,10 @@ module QA
include Runtime::Fixtures
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'file-template-project'
- project.description = 'Add file templates via the Files view'
- project.initialize_with_readme = true
- end
+ create(:project,
+ :with_readme,
+ name: 'file-template-project',
+ description: 'Add file templates via the Files view')
end
templates = [
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
index 1d9dccbddf6..6e508ba5206 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
@@ -6,12 +6,7 @@ module QA
let(:branch_name) { 'new-branch' }
let(:allowed_to_push_role) { Resource::ProtectedBranch::Roles::NO_ONE }
let(:allowed_to_merge_role) { Resource::ProtectedBranch::Roles::MAINTAINERS }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'branch-rule-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'branch-rule-project') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
index afa9be034eb..368ac1f8cdb 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
@@ -4,12 +4,7 @@ module QA
RSpec.describe 'Create' do
describe 'Branch with unusual name', product_group: :source_code do
let(:branch_name) { 'unUsually/named#br--anch' }
- let(:project) do
- Resource::Project.fabricate_via_api! do |resource|
- resource.name = 'unusually-named-branch-project'
- resource.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'unusually-named-branch-project') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
index b7df22fc2c2..15bd324da7c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Git clone over HTTP', product_group: :source_code do
- let(:project) do
- Resource::Project.fabricate_via_api! do |scenario|
- scenario.name = 'project-with-code'
- scenario.description = 'project for git clone tests'
- end
- end
+ let(:project) { create(:project, name: 'project-with-code', description: 'project for git clone tests') }
before do
Git::Repository.perform do |repository|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb
index d7da29219e6..5e221d06815 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb
@@ -4,12 +4,7 @@ module QA
RSpec.describe 'Create' do
describe 'File with unusual name', product_group: :source_code do
let(:file_name) { '-un:usually;named#file?.md' }
- let(:project) do
- Resource::Project.fabricate_via_api! do |resource|
- resource.name = 'unusually-named-file-project'
- resource.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'unusually-named-file-project') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
index f00ef65fab4..8c8834b44a0 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
@@ -7,7 +7,7 @@ module QA
project.remove_via_api!
end
- let(:project) { Resource::Project.fabricate_via_api! }
+ let(:project) { create(:project) }
shared_examples 'project license detection' do
it 'displays the name of the license on the repository' do
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
index a13b1517740..781096323d2 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
@@ -4,13 +4,7 @@ module QA
RSpec.describe 'Create', :orchestrated, :repository_storage, :requires_admin, product_group: :source_code do
describe 'Gitaly repository storage' do
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
- let(:parent_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'parent-project'
- project.initialize_with_readme = true
- end
- end
-
+ let(:parent_project) { create(:project, :with_readme, name: 'parent-project') }
let(:fork_project) do
Resource::Fork.fabricate_via_api! do |fork|
fork.user = user
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb
index 479c5816938..0b55ea8241e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb
@@ -3,13 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Repository tags', :reliable, product_group: :source_code do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-tags'
- project.initialize_with_readme = true
- end
- end
-
+ let(:project) { create(:project, :with_readme, name: 'project-for-tags') }
let(:developer_user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb
index 557a27c002d..2cf8c4ae154 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb
@@ -7,9 +7,7 @@ module QA
Flow::Login.sign_in
# Create a project to push to
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'git-protocol-project'
- end
+ project = create(:project, name: 'git-protocol-project')
file_name = 'README.md'
file_content = 'Test Git protocol v2'
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb
index 2472d1cdf25..1f60eb16b01 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb
@@ -28,9 +28,7 @@ module QA
end
it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347734' do
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'git-protocol-project'
- end
+ project = create(:project, name: 'git-protocol-project')
file_name = 'README.md'
file_content = 'Test Git protocol v2'
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
index b8a018552c6..4f45feb1b0a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
@@ -7,9 +7,7 @@ module QA
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
- target_project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'push-mirror-target-project'
- end
+ target_project = create(:project, name: 'push-mirror-target-project')
target_project_uri = target_project.repository_http_location.uri
target_project_uri.user = Runtime::User.username
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
index b87c47761bd..4cd371b524d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
@@ -7,9 +7,7 @@ module QA
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
- target_project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'push-mirror-target-project'
- end
+ target_project = create(:project, name: 'push-mirror-target-project')
target_project_uri = target_project.repository_http_location.uri
target_project_uri.user = Runtime::User.username
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
index 324dbbc46ef..76aba401aaa 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
@@ -7,12 +7,7 @@ module QA
describe 'push after setting the file size limit via admin/application_settings' do
include Support::API
- let!(:project) do
- Resource::Project.fabricate_via_api! do |p|
- p.name = 'project-test-push-limit'
- p.initialize_with_readme = true
- end
- end
+ let!(:project) { create(:project, :with_readme, name: 'project-test-push-limit') }
after(:context) do
set_file_size_limit(nil)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
index edc85849356..0b689081b7f 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
@@ -23,10 +23,9 @@ module QA
:requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347789' do
Flow::Login.sign_in_as_admin
- project = Resource::Project.fabricate_via_api! do |storage_project|
- storage_project.name = 'specific-repository-storage'
- storage_project.repository_storage = QA::Runtime::Env.praefect_repository_storage
- end
+ project = create(:project,
+ name: 'specific-repository-storage',
+ repository_storage: Runtime::Env.praefect_repository_storage)
Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = project.repository_http_location.uri
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
index e097e1fd2bb..b06879e9140 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
@@ -5,12 +5,7 @@ module QA
describe 'Protected branch support' do
let(:branch_name) { 'protected-branch' }
let(:commit_message) { 'Protected push commit message' }
- let(:project) do
- Resource::Project.fabricate_via_api! do |resource|
- resource.name = 'protected-branch-project'
- resource.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'protected-branch-project') }
before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb
index d95a880c305..b20b1f8cd92 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb
@@ -6,10 +6,7 @@ module QA
it 'pushes to a project using a canary specific Gitaly repository storage', :smoke, :requires_admin, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/351116' do
Flow::Login.sign_in_as_admin
- project = Resource::Project.fabricate_via_api! do |storage_project|
- storage_project.name = 'canary-specific-repository-storage'
- storage_project.repository_storage = 'nfs-file-cny01' # TODO: move to ENV var
- end
+ project = create(:project, name: 'canary-specific-repository-storage', repository_storage: 'nfs-file-cny01') # TODO: move to ENV var
Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = project.repository_http_location.uri
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
index 64858287285..a2fe79ae65d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
@@ -29,7 +29,7 @@ module QA
ssh_keys.remove_key(key.title)
end
- expect(page).not_to have_content("Title: #{key.title}")
+ expect(page).not_to have_content(key.title)
expect(page).not_to have_content(key.sha256_fingerprint)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
index 13b42209114..4f2e657fada 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Commit data', product_group: :source_code do
+ describe 'Commit data', :reliable, product_group: :source_code do
before(:context) do
# Get the user's details to confirm they're included in the email patch
@user = Resource::User.fabricate_via_api! do |user|
diff --git a/qa/qa/specs/features/browser_ui/3_create/source_editor/source_editor_toolbar_spec.rb b/qa/qa/specs/features/browser_ui/3_create/source_editor/source_editor_toolbar_spec.rb
index 9b1df337065..bd98cb17332 100644
--- a/qa/qa/specs/features/browser_ui/3_create/source_editor/source_editor_toolbar_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/source_editor/source_editor_toolbar_spec.rb
@@ -3,13 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Source editor toolbar preview', product_group: :source_code do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'empty-project-with-md'
- project.initialize_with_readme = true
- end
- end
-
+ let(:project) { create(:project, :with_readme, name: 'empty-project-with-md') }
let(:edited_readme_content) { 'Here is the edited content.' }
before do
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
index 3e8f9307cec..4172aa03a72 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
@@ -8,12 +8,7 @@ module QA
type: :flaky
} do
describe 'Add a directory in Web IDE' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'add-directory-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'add-directory-project') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
index 336d32bcc35..afed95e18f9 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
@@ -9,13 +9,7 @@ module QA
} do
describe 'Upload a file in Web IDE' do
let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', file_name)) }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'upload-file-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'upload-file-project') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb
index 3e24fb496e7..18dd4d912d8 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb
@@ -11,11 +11,10 @@ module QA
include Runtime::Fixtures
before(:all) do
- @project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'file-template-project'
- project.description = 'Add file templates via the Web IDE'
- project.initialize_with_readme = true
- end
+ @project = create(:project,
+ :with_readme,
+ name: 'file-template-project',
+ description: 'Add file templates via Web IDE')
end
templates = [
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb
index 775e14500d5..8fe58078393 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb
@@ -8,13 +8,7 @@ module QA
end
describe 'First file using Web IDE' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'empty-project'
- project.initialize_with_readme = false
- end
- end
-
+ let(:project) { create(:project, :with_readme, name: 'empty-project') }
let(:file_name) { 'the very first file.txt' }
before do
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb
index bea2e906d5e..57c8945d5c4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb
@@ -9,11 +9,7 @@ module QA
describe 'Link to line in Web IDE' do
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.template_name = 'express'
- end
- end
+ let(:project) { create(:project, template_name: 'express') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb
index c4ed2038f4c..10483a7cbee 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb
@@ -23,12 +23,7 @@ module QA
}
]
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.initialize_with_readme = true
- end
- end
-
+ let(:project) { create(:project, :with_readme) }
let(:source) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb
index 1043e9051e3..4044494d3da 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb
@@ -11,13 +11,7 @@ module QA
let(:new_file) { 'awesome_new_file.txt' }
let(:original_text) { 'Text' }
let(:review_text) { 'Reviewed ' }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'review-merge-request-spec-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'review-mr-spec-project') }
let(:merge_request) do
Resource::MergeRequest.fabricate_via_api! do |mr|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
index 05925505610..42fcbf5352f 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
@@ -10,13 +10,9 @@ module QA
describe 'Git Server Hooks' do
let(:file_path) { Runtime::Path.fixture('web_ide', 'README.md') }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- # Projects that have names that include pattern 'reject-prereceive' trigger a server hook on orchestrated env
- # that returns an error string using GL-HOOK-ERR
- project.name = "project-reject-prereceive-#{SecureRandom.hex(8)}"
- end
- end
+ # Projects that have names that include pattern 'reject-prereceive' trigger a server hook on orchestrated env
+ # that returns an error string using GL-HOOK-ERR
+ let(:project) { create(:project, name: "project-reject-prereceive-#{SecureRandom.hex(8)}") }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
index c557f2fa8a6..ab035d3b52c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
@@ -9,12 +9,7 @@ module QA
describe 'Upload a file in Web IDE' do
let(:file_path) { Runtime::Path.fixture('web_ide', file_name) }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'upload-file-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'upload-file-project') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb
index b08a36b0d43..d5de93fdee6 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb
@@ -2,15 +2,9 @@
module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_security do
- describe "Unlocking job artifacts across parent-child pipelines" do
+ describe 'Unlocking job artifacts across parent-child pipelines' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'unlock-job-artifacts-parent-child-project'
- end
- end
-
+ let(:project) { create(:project, name: 'unlock-job-artifacts-parent-child-project') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
@@ -249,6 +243,8 @@ module QA
private
def update_parent_child_ci_files(parent_job_name:, parent_script:, child_job_name:, child_script:)
+ original_pipeline_count = pipeline_count
+
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Update parent and child pipelines CI files.'
@@ -259,9 +255,13 @@ module QA
]
)
end
+
+ wait_for_pipeline_creation(original_pipeline_count)
end
def add_parent_child_ci_files(parent_job_name:, parent_script:, child_job_name:, child_script:)
+ original_pipeline_count = pipeline_count
+
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add parent and child pipelines CI files.'
@@ -272,6 +272,8 @@ module QA
]
)
end
+
+ wait_for_pipeline_creation(original_pipeline_count)
end
def parent_ci_file(job_name, script)
@@ -316,6 +318,16 @@ module QA
job.id = project.job_by_name(job_name)[:id]
end
end
+
+ def wait_for_pipeline_creation(original_pipeline_count)
+ Support::Waiter.wait_until(sleep_interval: 1, message: 'Wait for pipeline creation') do
+ pipeline_count > original_pipeline_count
+ end
+ end
+
+ def pipeline_count
+ project.pipelines.length
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb
index 41ce868f0d6..91e62dfba9b 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb
@@ -4,12 +4,7 @@ module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_security do
describe "Unlocking job artifacts across pipelines" do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'unlock-job-artifacts-project'
- end
- end
+ let(:project) { create(:project, name: 'unlock-job-artifacts-project') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb
index 4515353dfc5..4ec9360be24 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb
@@ -6,13 +6,7 @@ module QA
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:pipeline_job_name) { 'customizable-variable' }
let(:variable_custom_value) { 'Custom Foo' }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-customizable-variable-pipeline'
- end
- end
-
+ let(:project) { create(:project, name: 'project-with-customizable-variable-pipeline') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb
index e2d25e64687..8e168ef80f6 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb
@@ -5,13 +5,7 @@ module QA
describe 'Pipeline with protected variable' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:protected_value) { Faker::Alphanumeric.alphanumeric(number: 8) }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-ci-variables'
- project.description = 'project with CI variables'
- end
- end
+ let(:project) { create(:project, name: 'project-with-ci-vars', description: 'project with CI vars') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb
index b62ae85436f..8d315f66034 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb
@@ -8,12 +8,7 @@ module QA
let(:prefill_variable_value5) { Faker::Lorem.word }
let(:prefill_variable_description2) { Faker::Lorem.sentence }
let(:prefill_variable_description5) { Faker::Lorem.sentence }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-prefill-variables'
- end
- end
-
+ let(:project) { create(:project, name: 'project-with-prefill-variables') }
let!(:commit) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb
index 15959721935..f47949e0024 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb
@@ -5,12 +5,7 @@ module QA
describe 'Pipeline with raw variables in YAML', product_group: :pipeline_security do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:pipeline_job_name) { 'rspec' }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-raw-variable-pipeline'
- end
- end
+ let(:project) { create(:project, name: 'project-with-raw-variable-pipeline') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
index 027383550a7..8cf923f543b 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
@@ -3,11 +3,7 @@
module QA
RSpec.describe 'Verify' do
describe 'Include local config file paths with wildcard', :reliable, product_group: :pipeline_authoring do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline'
- end
- end
+ let(:project) { create(:project, name: 'project-with-pipeline') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb
index 5bbe09b3fb0..fe655f41992 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb
@@ -7,17 +7,8 @@ module QA
let(:expected_text) { Faker::Lorem.sentence }
let(:unexpected_text) { Faker::Lorem.sentence }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline-1'
- end
- end
-
- let(:other_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline-2'
- end
- end
+ let(:project) { create(:project, name: 'project-with-pipeline-1') }
+ let(:other_project) { create(:project, name: 'project-with-pipeline-2') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_multiple_projects_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_multiple_projects_spec.rb
index 59591fbe1cd..da7b7ec720f 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_multiple_projects_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_multiple_projects_spec.rb
@@ -4,25 +4,9 @@ module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Include multiple files from multiple projects' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:main_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline'
- end
- end
-
- let(:project1) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'external-project-1'
- end
- end
-
- let(:project2) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'external-project-2'
- end
- end
-
+ let(:main_project) { create(:project, name: 'project-with-pipeline') }
+ let(:project1) { create(:project, name: 'external-project-1') }
+ let(:project2) { create(:project, name: 'external-project-2') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = main_project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb
index ecf4826262b..3e1e2bc5b5b 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb
@@ -8,13 +8,7 @@ module QA
} do
context 'when pipeline is blocked' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-blocked-pipeline'
- end
- end
-
+ let(:project) { create(:project, name: 'project-with-blocked-pipeline') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb
index fef90a7c8fc..52efacfd407 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Verify', :runner, :reliable, product_group: :pipeline_execution do
describe 'Parent-child pipelines independent relationship' do
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-independent-relationship'
- end
- end
-
+ let!(:project) { create(:project, name: 'pipeline-independent-relationship') }
let!(:runner) do
Resource::ProjectRunner.fabricate_via_api! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb
index 6295c596dda..f9a3856f810 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb
@@ -5,21 +5,9 @@ module QA
describe 'Pass dotenv variables to downstream via bridge' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:upstream_var) { Faker::Alphanumeric.alphanumeric(number: 8) }
- let(:group) { Resource::Group.fabricate_via_api! }
-
- let(:upstream_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = group
- project.name = 'upstream-project-with-bridge'
- end
- end
-
- let(:downstream_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = group
- project.name = 'downstream-project-with-bridge'
- end
- end
+ let(:group) { create(:group) }
+ let(:upstream_project) { create(:project, group: group, name: 'upstream-project-with-bridge') }
+ let(:downstream_project) { create(:project, group: group, name: 'downstream-project-with-bridge') }
let!(:runner) do
Resource::GroupRunner.fabricate! do |runner|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb
index 1f7871b0900..f4847a9ec99 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb
@@ -3,12 +3,7 @@
module QA
RSpec.describe 'Verify' do
describe 'Pipeline editor', product_group: :pipeline_authoring do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-editor-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'pipeline-editor-project') }
before do
Flow::Login.sign_in
@@ -27,13 +22,6 @@ module QA
Page::Project::PipelineEditor::New.perform(&:create_new_ci)
Page::Project::PipelineEditor::Show.perform do |show|
- # Editor should display default content when project does not have CI file yet
- # New MR checkbox should not be rendered when a new target branch is yet to be provided
- aggregate_failures 'check editor default conditions' do
- expect(show.editing_content).not_to be_empty
- expect(show).to have_no_new_mr_checkbox
- end
-
# The new MR checkbox is visible after a new branch name is set
show.set_source_branch(SecureRandom.hex(10))
expect(show).to have_new_mr_checkbox
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb
index 1abe1df5964..69d8467e6ea 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb
@@ -5,13 +5,7 @@ module QA
describe 'Pipeline with image:pull_policy' do
let(:runner_name) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:job_name) { "test-job-#{pull_policies.join('-')}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-with-image-pull-policy'
- end
- end
-
+ let(:project) { create(:project, name: 'pipeline-with-image-pull-policy') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
index 9f43471035f..b96869658c9 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
@@ -5,12 +5,7 @@ module QA
describe 'Run pipeline', :reliable, product_group: :pipeline_execution do
context 'with web only rule' do
let(:job_name) { 'test_job' }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'web-only-pipeline'
- end
- end
-
+ let(:project) { create(:project, name: 'web-only-pipeline') }
let!(:ci_file) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_with_manual_jobs_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_with_manual_jobs_spec.rb
index d733ac9ba72..019228da130 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_with_manual_jobs_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_with_manual_jobs_spec.rb
@@ -6,10 +6,7 @@ module QA
let(:executor) { "qa-runner-#{SecureRandom.hex(4)}" }
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-with-manual-job'
- project.description = 'Project for pipeline with manual job'
- end
+ create(:project, name: 'pipeline-with-manual-job', description: 'Project for pipeline with manual job')
end
let!(:runner) do
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb
index 3361ab98bda..09d1fd331cd 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb
@@ -4,13 +4,7 @@ module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_execution do
describe "Trigger child pipeline with 'when:manual'" do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline'
- end
- end
-
+ let(:project) { create(:project, name: 'project-with-pipeline') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb
index bd656142989..6eea6756ee7 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb
@@ -4,13 +4,7 @@ module QA
RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Trigger matrix' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline'
- end
- end
-
+ let(:project) { create(:project, name: 'project-with-pipeline') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb
index a749da4608a..5c0e2a9d668 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb
@@ -4,13 +4,7 @@ module QA
RSpec.describe 'Verify' do
describe 'Update CI file with pipeline editor', product_group: :pipeline_authoring do
let(:random_test_string) { SecureRandom.hex(10) }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-editor-project'
- end
- end
-
+ let(:project) { create(:project, name: 'pipeline-editor-project') }
let!(:runner) do
Resource::ProjectRunner.fabricate_via_api! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb
index e2bb6c33513..da7a6c537b8 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb
@@ -11,12 +11,7 @@ module QA
# User views pipeline succeeds (Web read)
RSpec.describe 'Verify', :runner, product_group: :pipeline_security do
context 'Endpoint Coverage' do
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'endpoint-coverage'
- end
- end
-
+ let!(:project) { create(:project, name: 'endpoint-coverage') }
let!(:runner) do
Resource::ProjectRunner.fabricate_via_api! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/container_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/container_registry_spec.rb
index 4b2d9f96cd2..49d1434035f 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/container_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/container_registry_spec.rb
@@ -4,50 +4,46 @@ module QA
RSpec.describe 'Package' do
describe 'SaaS Container Registry', only: { subdomain: %i[staging staging-canary pre] },
product_group: :container_registry do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-registry'
- project.template_name = 'express'
- end
- end
-
- let(:registry_repository) do
- Resource::RegistryRepository.fabricate! do |repository|
- repository.name = project.path_with_namespace.to_s
- repository.project = project
- end
- end
-
+ let(:project) { create(:project, name: 'project-with-registry', template_name: 'express') }
let!(:gitlab_ci_yaml) do
<<~YAML
- build:
- image: docker:24.0.1
- stage: build
- services:
- - docker:24.0.1-dind
- variables:
- IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
- DOCKER_HOST: tcp://docker:2376
- DOCKER_TLS_CERTDIR: "/certs"
- DOCKER_TLS_VERIFY: 1
- DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
- before_script:
- - |
- echo "Waiting for docker to start..."
- for i in $(seq 1 30)
- do
- docker info && break
- sleep 1s
- done
- script:
- - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- - docker build -t $IMAGE_TAG .
- - docker push $IMAGE_TAG
- YAML
- end
+ stages:
+ - test
+ - build
- after do
- registry_repository&.remove_via_api!
+ test:
+ image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest
+ stage: test
+ script:
+ - 'status_code=$(curl --header "Authorization: Bearer $CI_JOB_TOKEN" "https://${CI_SERVER_HOST}/gitlab/v1")'
+ - |
+ if [ "$status_code" -eq 404 ]; then
+ echo "The registry implements this API specification, but it is unavailable because the metadata database is disabled."
+ exit 1
+ fi
+ build:
+ image: docker:24.0.1
+ stage: build
+ services:
+ - docker:24.0.1-dind
+ variables:
+ IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ DOCKER_HOST: tcp://docker:2376
+ DOCKER_TLS_CERTDIR: "/certs"
+ DOCKER_TLS_VERIFY: 1
+ DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
+ before_script:
+ - |
+ echo "Waiting for docker to start..."
+ for i in $(seq 1 30); do
+ docker info && break
+ sleep 1s
+ done
+ script:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ - docker build -t $IMAGE_TAG .
+ - docker push $IMAGE_TAG
+ YAML
end
it 'pushes project image to the container registry and deletes tag',
@@ -69,11 +65,20 @@ module QA
Flow::Pipeline.visit_latest_pipeline
Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('test')
+ end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 200)
+
+ job.click_element(:pipeline_path)
+ end
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.click_job('build')
end
Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
+ expect(job).to be_successful(timeout: 500)
end
Page::Project::Menu.perform(&:go_to_container_registry)
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/pull_container_registry_image_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/pull_container_registry_image_spec.rb
index 85a88b54cc2..3c656d9ca75 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/pull_container_registry_image_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/saas/pull_container_registry_image_spec.rb
@@ -2,16 +2,18 @@
module QA
RSpec.describe 'Package' do
- describe 'SaaS Container Registry', only: { subdomain: %i[staging] }, product_group: :container_registry do
- let(:project) do
- Resource::Project.init do |project|
- project.path_with_namespace = 'gitlab-qa/container-registry-sanity'
- end.reload!
+ describe 'SaaS Container Registry', :smoke,
+ only: { subdomain: :staging }, product_group: :container_registry do
+ before do
+ Flow::Login.sign_in
end
it 'pulls an image from an existing repository',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/412799' do
- Flow::Login.sign_in
+ project = Resource::Project.init do |project|
+ project.path_with_namespace = 'gitlab-qa/container-registry-sanity'
+ end.reload!
+
project.visit!
Page::Project::Menu.perform(&:go_to_pipelines)
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/self_managed/container_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/self_managed/container_registry_spec.rb
index 800b3a01dc6..e4d6ba9c4db 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/self_managed/container_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/self_managed/container_registry_spec.rb
@@ -5,14 +5,7 @@ module QA
describe 'Self-managed Container Registry' do
include Support::Helpers::MaskToken
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-registry'
- project.template_name = 'express'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'project-with-registry', template_name: 'express') }
let(:project_deploy_token) do
Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
deploy_token.name = 'registry-deploy-token'
@@ -43,10 +36,6 @@ module QA
project.visit!
end
- after do
- runner.remove_via_api!
- end
-
context "when tls is disabled" do
where do
{
@@ -200,27 +189,27 @@ module QA
file_path: '.gitlab-ci.yml',
content:
<<~YAML
- build:
- image: docker:23.0.6
- stage: build
- services:
+ build:
+ image: docker:23.0.6
+ stage: build
+ services:
- name: docker:23.0.6-dind
command:
- - /bin/sh
- - -c
- - |
- apk add --no-cache openssl
- true | openssl s_client -showcerts -connect gitlab.test:5050 > /usr/local/share/ca-certificates/gitlab.test.crt
- update-ca-certificates
- dockerd-entrypoint.sh || exit
- variables:
- IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
- script:
- - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD gitlab.test:5050
- - docker build -t $IMAGE_TAG .
- - docker push $IMAGE_TAG
- tags:
- - "runner-for-#{project.name}"
+ - /bin/sh
+ - -c
+ - |
+ apk add --no-cache openssl
+ true | openssl s_client -showcerts -connect gitlab.test:5050 > /usr/local/share/ca-certificates/gitlab.test.crt
+ update-ca-certificates
+ dockerd-entrypoint.sh || exit
+ variables:
+ IMAGE_TAG: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
+ script:
+ - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD gitlab.test:5050
+ - docker build -t $IMAGE_TAG .
+ - docker push $IMAGE_TAG
+ tags:
+ - "runner-for-#{project.name}"
YAML
}
]
@@ -234,7 +223,11 @@ module QA
pipeline.click_job('build')
end
- Support::Retrier.retry_until(max_duration: 800, sleep_interval: 10) do
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 200)
+ end
+
+ Support::Retrier.retry_until(max_duration: 500, sleep_interval: 10) do
project.pipelines.last[:status] == 'success'
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb b/qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb
index 235c3604523..dae0e17746c 100644
--- a/qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb
@@ -6,13 +6,7 @@ module QA
using RSpec::Parameterized::TableSyntax
include Support::Helpers::MaskToken
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'dependency-proxy-project'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'dependency-proxy-project') }
let!(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
@@ -35,8 +29,7 @@ module QA
let(:personal_access_token) { Runtime::Env.personal_access_token }
- let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
- let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" }
+ let(:gitlab_host_with_port) { Support::GitlabAddress.host_with_port }
let(:dependency_proxy_url) { "#{gitlab_host_with_port}/#{project.group.full_path}/dependency_proxy/containers" }
let(:image_sha) { 'alpine@sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb' }
diff --git a/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb
index 8dc9fb6db36..05c6694e69a 100644
--- a/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb
@@ -10,7 +10,7 @@ module QA
} do
include Runtime::Fixtures
- let(:group) { Resource::Group.fabricate_via_api! }
+ let(:group) { create(:group) }
let(:imported_project) do
Resource::ProjectImportedFromURL.fabricate_via_browser_ui! do |project|
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb
index 58eb63de21d..6e52208004f 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/composer_registry_spec.rb
@@ -1,17 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'Composer Repository' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'Composer Repository', :external_api_calls do
include Runtime::Fixtures
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'composer-package-project'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :privtae, name: 'composer-package-project') }
let(:package) do
Resource::Package.init do |package|
package.name = "my_package-#{SecureRandom.hex(4)}"
@@ -28,10 +22,7 @@ module QA
end
end
- let!(:gitlab_address_with_port) do
- uri = URI.parse(Runtime::Scenario.gitlab_address)
- "#{uri.scheme}://#{uri.host}:#{uri.port}"
- end
+ let(:gitlab_host_with_port) { Support::GitlabAddress.host_with_port }
before do
Flow::Login.sign_in
@@ -71,7 +62,14 @@ module QA
package.remove_via_api!
end
- it 'publishes a composer package and deletes it', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348016' do
+ it(
+ 'publishes a composer package and deletes it',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348016',
+ quarantine: {
+ type: :broken,
+ issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/421885"
+ }
+ ) do
Page::Project::Menu.perform(&:go_to_package_registry)
Page::Project::Packages::Index.perform do |index|
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb
index 83662e04fab..f2e19068f18 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb
@@ -1,21 +1,15 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, product_group: :package_registry, quarantine: {
- only: { job: %w[object_storage relative_url airgapped], condition: -> { QA::Support::FIPS.enabled? } },
+ RSpec.describe 'Package', :object_storage, :external_api_calls, product_group: :package_registry, quarantine: {
+ only: { job: 'object_storage', condition: -> { QA::Support::FIPS.enabled? } },
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417584',
type: :bug
} do
describe 'Conan Repository' do
include Runtime::Fixtures
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'conan-package-project'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'conan-package-project') }
let(:package) do
Resource::Package.init do |package|
package.name = "conantest-#{SecureRandom.hex(8)}"
@@ -33,8 +27,7 @@ module QA
end
let(:gitlab_address_with_port) do
- uri = URI.parse(Runtime::Scenario.gitlab_address)
- "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ Support::GitlabAddress.address_with_port
end
after do
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb
index 1253dc91ca3..3c43e97e21e 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb
@@ -1,17 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'Generic Repository' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'Generic Repository', :external_api_calls do
include Runtime::Fixtures
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'generic-package-project'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'generic-package-project') }
let(:package) do
Resource::Package.init do |package|
package.name = "my_package-#{SecureRandom.hex(8)}"
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
index 7bfda7f5956..42635a9e59f 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
@@ -2,12 +2,7 @@
module QA
RSpec.describe 'Package', :object_storage, product_group: :package_registry do
- describe 'Helm Registry',
- quarantine: {
- only: { job: %w[relative_url airgapped] },
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417590',
- type: :investigating
- } do
+ describe 'Helm Registry', :external_api_calls do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
index ce6c54b6ed8..3cbc78ab806 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
@@ -2,12 +2,7 @@
module QA
RSpec.describe 'Package', :object_storage, product_group: :package_registry do
- describe 'Maven group level endpoint',
- quarantine: {
- only: { job: %w[relative_url airgapped] },
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417600',
- type: :investigating
- } do
+ describe 'Maven group level endpoint', :external_api_calls do
include Runtime::Fixtures
include Support::Helpers::MaskToken
include_context 'packages registry qa scenario'
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
index 35f80f8d447..d1663f075e0 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
@@ -1,12 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage,
- quarantine: {
- only: { job: %w[relative_url airgapped] },
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417600',
- type: :investigating
- } do
+ RSpec.describe 'Package', :object_storage, :external_api_calls do
describe 'Maven project level endpoint', product_group: :package_registry do
include Runtime::Fixtures
include Support::Helpers::MaskToken
@@ -17,15 +12,7 @@ module QA
let(:package_version) { '1.3.7' }
let(:package_type) { 'maven' }
let(:personal_access_token) { Runtime::Env.personal_access_token }
-
- let(:package_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "#{package_type}_package_project"
- project.initialize_with_readme = true
- project.visibility = :private
- end
- end
-
+ let(:package_project) { create(:project, :with_readme, :private, name: "#{package_type}_package_project") }
let(:package) do
Resource::Package.init do |package|
package.name = package_name
@@ -43,8 +30,7 @@ module QA
end
let(:gitlab_address_with_port) do
- uri = URI.parse(Runtime::Scenario.gitlab_address)
- "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ Support::GitlabAddress.address_with_port
end
let(:project_deploy_token) do
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
index f24466ed003..28037391aeb 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage,
+ RSpec.describe 'Package', :object_storage, :external_api_calls,
quarantine: {
- only: { job: 'relative_url', condition: -> { QA::Support::FIPS.enabled? } },
+ only: { condition: -> { QA::Support::FIPS.enabled? } },
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417600',
type: :investigating
}, product_group: :package_registry do
@@ -17,15 +17,7 @@ module QA
let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
let(:package_version) { '1.3.7' }
let(:package_type) { 'maven_gradle' }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "#{package_type}_project"
- project.initialize_with_readme = true
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, :with_readme, name: "#{package_type}_project") }
let(:runner) do
Resource::ProjectRunner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
@@ -36,8 +28,7 @@ module QA
end
let(:gitlab_address_with_port) do
- uri = URI.parse(Runtime::Scenario.gitlab_address)
- "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ Support::GitlabAddress.address_with_port
end
let(:project_deploy_token) do
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_group_level_spec.rb
index 1b97f7d0a6a..0550c3373da 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_group_level_spec.rb
@@ -2,170 +2,156 @@
module QA
RSpec.describe 'Package' do
- describe 'Package Registry', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'npm group level endpoint' do
- using RSpec::Parameterized::TableSyntax
- include Runtime::Fixtures
- include Support::Helpers::MaskToken
+ describe 'npm Registry group level endpoint', :object_storage, :external_api_calls,
+ product_group: :package_registry do
+ using RSpec::Parameterized::TableSyntax
+ include Runtime::Fixtures
+ include Support::Helpers::MaskToken
- let!(:registry_scope) { Runtime::Namespace.sandbox_name }
- let!(:personal_access_token) do
- Flow::Login.sign_in unless Page::Main::Menu.perform(&:signed_in?)
+ let!(:registry_scope) { Runtime::Namespace.sandbox_name }
+ let!(:personal_access_token) do
+ Flow::Login.sign_in unless Page::Main::Menu.perform(&:signed_in?)
- Resource::PersonalAccessToken.fabricate!.token
- end
-
- let(:project_deploy_token) do
- Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
- deploy_token.name = 'npm-deploy-token'
- deploy_token.project = project
- deploy_token.scopes = %w[
- read_repository
- read_package_registry
- write_package_registry
- ]
- end
- end
-
- let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
- let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
- let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" }
+ Resource::PersonalAccessToken.fabricate!.token
+ end
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'npm-group-level-publish'
- end
+ let(:project_deploy_token) do
+ Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'npm-deploy-token'
+ deploy_token.project = project
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
end
+ end
- let!(:another_project) do
- Resource::Project.fabricate_via_api! do |another_project|
- another_project.name = 'npm-group-level-install'
- another_project.group = project.group
- end
+ let(:gitlab_address_without_port) { Support::GitlabAddress.address_with_port(with_default_port: false) }
+ let(:gitlab_host_without_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
+ let!(:project) { create(:project, name: 'npm-group-level-publish') }
+ let!(:another_project) { create(:project, name: 'npm-group-level-install', group: project.group) }
+ let!(:runner) do
+ Resource::GroupRunner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{project.group.name}"]
+ runner.executor = :docker
+ runner.group = project.group
end
+ end
- let!(:runner) do
- Resource::GroupRunner.fabricate! do |runner|
- runner.name = "qa-runner-#{Time.now.to_i}"
- runner.tags = ["runner-for-#{project.group.name}"]
- runner.executor = :docker
- runner.group = project.group
- end
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}"
+ package.project = project
end
+ end
- let(:package) do
- Resource::Package.init do |package|
- package.name = "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}"
- package.project = project
- end
- end
+ after do
+ package.remove_via_api!
+ runner.remove_via_api!
+ project.remove_via_api!
+ another_project.remove_via_api!
+ end
- after do
- package.remove_via_api!
- runner.remove_via_api!
- project.remove_via_api!
- another_project.remove_via_api!
- end
+ where(:case_name, :authentication_token_type, :token_name, :testcase) do
+ 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/413760'
+ 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/413761'
+ 'using project deploy token' | :project_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/413762'
+ end
- where(:case_name, :authentication_token_type, :token_name, :testcase) do
- 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/413760'
- 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/413761'
- 'using project deploy token' | :project_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/413762'
+ with_them do
+ let(:auth_token) do
+ case authentication_token_type
+ when :personal_access_token
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: another_project)
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :project_deploy_token
+ use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
+ use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: another_project)
+ end
end
- with_them do
- let(:auth_token) do
- case authentication_token_type
- when :personal_access_token
- use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
- use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: another_project)
- when :ci_job_token
- '${CI_JOB_TOKEN}'
- when :project_deploy_token
- use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
- use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: another_project)
+ it 'push and pull a npm package via CI', testcase: params[:testcase] do
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ npm_upload_yaml = ERB.new(read_fixture('package_managers/npm',
+ 'npm_upload_package_group.yaml.erb')).result(binding)
+ package_json = ERB.new(read_fixture('package_managers/npm', 'package.json.erb')).result(binding)
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add files'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: npm_upload_yaml
+ },
+ {
+ file_path: 'package.json',
+ content: package_json
+ }
+ ])
end
end
- it 'push and pull a npm package via CI', testcase: params[:testcase] do
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- npm_upload_yaml = ERB.new(read_fixture('package_managers/npm',
- 'npm_upload_package_group.yaml.erb')).result(binding)
- package_json = ERB.new(read_fixture('package_managers/npm', 'package.json.erb')).result(binding)
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: npm_upload_yaml
- },
- {
- file_path: 'package.json',
- content: package_json
- }
- ])
- end
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- npm_install_yaml = ERB.new(read_fixture('package_managers/npm',
- 'npm_install_package_group.yaml.erb')).result(binding)
-
- commit.project = another_project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: npm_install_yaml
- }
- ])
- end
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ npm_install_yaml = ERB.new(read_fixture('package_managers/npm',
+ 'npm_install_package_group.yaml.erb')).result(binding)
+
+ commit.project = another_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: npm_install_yaml
+ }
+ ])
end
+ end
- another_project.visit!
- Flow::Pipeline.visit_latest_pipeline
+ another_project.visit!
+ Flow::Pipeline.visit_latest_pipeline
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- job.click_browse_button
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ job.click_browse_button
+ end
- Page::Project::Artifact::Show.perform do |artifacts|
- artifacts.go_to_directory('node_modules')
- artifacts.go_to_directory("@#{registry_scope}")
- expect(artifacts).to have_content(project.name.to_s)
- end
+ Page::Project::Artifact::Show.perform do |artifacts|
+ artifacts.go_to_directory('node_modules')
+ artifacts.go_to_directory("@#{registry_scope}")
+ expect(artifacts).to have_content(project.name.to_s)
+ end
- project.visit!
- Page::Project::Menu.perform(&:go_to_package_registry)
+ project.visit!
+ Page::Project::Menu.perform(&:go_to_package_registry)
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
- index.click_package(package.name)
- end
+ index.click_package(package.name)
+ end
- Page::Project::Packages::Show.perform do |show|
- expect(show).to have_package_info(package.name, "1.0.0")
- end
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package.name, "1.0.0")
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb
index b0702b3f089..f8e526a01b0 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb
@@ -2,168 +2,154 @@
module QA
RSpec.describe 'Package' do
- describe 'Package Registry', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'npm instance level endpoint' do
- using RSpec::Parameterized::TableSyntax
- include Runtime::Fixtures
- include Support::Helpers::MaskToken
+ describe 'npm Registry instance level endpoint', :object_storage, :external_api_calls,
+ product_group: :package_registry do
+ using RSpec::Parameterized::TableSyntax
+ include Runtime::Fixtures
+ include Support::Helpers::MaskToken
- let!(:registry_scope) { Runtime::Namespace.sandbox_name }
- let!(:personal_access_token) do
- Flow::Login.sign_in unless Page::Main::Menu.perform(&:signed_in?)
+ let!(:registry_scope) { Runtime::Namespace.sandbox_name }
+ let!(:personal_access_token) do
+ Flow::Login.sign_in unless Page::Main::Menu.perform(&:signed_in?)
- Resource::PersonalAccessToken.fabricate!.token
- end
-
- let(:project_deploy_token) do
- Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
- deploy_token.name = 'npm-deploy-token'
- deploy_token.project = project
- deploy_token.scopes = %w[
- read_repository
- read_package_registry
- write_package_registry
- ]
- end
- end
-
- let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
- let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
- let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" }
+ Resource::PersonalAccessToken.fabricate!.token
+ end
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'npm-instace-level-publish'
- end
+ let(:project_deploy_token) do
+ Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'npm-deploy-token'
+ deploy_token.project = project
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
end
+ end
- let!(:another_project) do
- Resource::Project.fabricate_via_api! do |another_project|
- another_project.name = 'npm-instance-level-install'
- another_project.group = project.group
- end
+ let(:gitlab_address_without_port) { Support::GitlabAddress.address_with_port(with_default_port: false) }
+ let(:gitlab_host_without_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
+ let!(:project) { create(:project, name: 'npm-instance-level-publish') }
+ let!(:another_project) { create(:project, name: 'npm-instance-level-install', group: project.group) }
+ let!(:runner) do
+ Resource::GroupRunner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{project.group.name}"]
+ runner.executor = :docker
+ runner.group = project.group
end
+ end
- let!(:runner) do
- Resource::GroupRunner.fabricate! do |runner|
- runner.name = "qa-runner-#{Time.now.to_i}"
- runner.tags = ["runner-for-#{project.group.name}"]
- runner.executor = :docker
- runner.group = project.group
- end
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}"
+ package.project = project
end
+ end
- let(:package) do
- Resource::Package.init do |package|
- package.name = "@#{registry_scope}/#{project.name}-#{SecureRandom.hex(8)}"
- package.project = project
- end
- end
+ after do
+ package.remove_via_api!
+ runner.remove_via_api!
+ project.remove_via_api!
+ another_project.remove_via_api!
+ end
- after do
- package.remove_via_api!
- runner.remove_via_api!
- project.remove_via_api!
- another_project.remove_via_api!
- end
+ where(:case_name, :authentication_token_type, :token_name, :testcase) do
+ 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347600'
+ 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347599'
+ 'using project deploy token' | :project_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347598'
+ end
- where(:case_name, :authentication_token_type, :token_name, :testcase) do
- 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347600'
- 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347599'
- 'using project deploy token' | :project_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347598'
+ with_them do
+ let(:auth_token) do
+ case authentication_token_type
+ when :personal_access_token
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: another_project)
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :project_deploy_token
+ use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
+ use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: another_project)
+ end
end
- with_them do
- let(:auth_token) do
- case authentication_token_type
- when :personal_access_token
- use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
- use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: another_project)
- when :ci_job_token
- '${CI_JOB_TOKEN}'
- when :project_deploy_token
- use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
- use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: another_project)
+ it 'push and pull a npm package via CI', testcase: params[:testcase] do
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ npm_upload_yaml = ERB.new(read_fixture('package_managers/npm', 'npm_upload_package_instance.yaml.erb')).result(binding)
+ package_json = ERB.new(read_fixture('package_managers/npm', 'package.json.erb')).result(binding)
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add files'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: npm_upload_yaml
+ },
+ {
+ file_path: 'package.json',
+ content: package_json
+ }
+ ])
end
end
- it 'push and pull a npm package via CI', testcase: params[:testcase] do
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- npm_upload_yaml = ERB.new(read_fixture('package_managers/npm', 'npm_upload_package_instance.yaml.erb')).result(binding)
- package_json = ERB.new(read_fixture('package_managers/npm', 'package.json.erb')).result(binding)
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: npm_upload_yaml
- },
- {
- file_path: 'package.json',
- content: package_json
- }
- ])
- end
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- npm_install_yaml = ERB.new(read_fixture('package_managers/npm', 'npm_install_package_instance.yaml.erb')).result(binding)
-
- commit.project = another_project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: npm_install_yaml
- }
- ])
- end
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ npm_install_yaml = ERB.new(read_fixture('package_managers/npm', 'npm_install_package_instance.yaml.erb')).result(binding)
+
+ commit.project = another_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: npm_install_yaml
+ }
+ ])
end
+ end
- another_project.visit!
- Flow::Pipeline.visit_latest_pipeline
+ another_project.visit!
+ Flow::Pipeline.visit_latest_pipeline
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- job.click_browse_button
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ job.click_browse_button
+ end
- Page::Project::Artifact::Show.perform do |artifacts|
- artifacts.go_to_directory('node_modules')
- artifacts.go_to_directory("@#{registry_scope}")
- expect(artifacts).to have_content(project.name.to_s)
- end
+ Page::Project::Artifact::Show.perform do |artifacts|
+ artifacts.go_to_directory('node_modules')
+ artifacts.go_to_directory("@#{registry_scope}")
+ expect(artifacts).to have_content(project.name.to_s)
+ end
- project.visit!
- Page::Project::Menu.perform(&:go_to_package_registry)
+ project.visit!
+ Page::Project::Menu.perform(&:go_to_package_registry)
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
- index.click_package(package.name)
- end
+ index.click_package(package.name)
+ end
- Page::Project::Packages::Show.perform do |show|
- expect(show).to have_package_info(package.name, "1.0.0")
- end
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package.name, "1.0.0")
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb
index 1eed68d1b88..11df6dcb303 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb
@@ -2,141 +2,132 @@
module QA
RSpec.describe 'Package' do
- describe 'Package Registry', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'npm project level endpoint' do
- using RSpec::Parameterized::TableSyntax
- include Runtime::Fixtures
- include Support::Helpers::MaskToken
+ describe 'npm Registry project level endpoint', :object_storage, :external_api_calls,
+ product_group: :package_registry do
+ using RSpec::Parameterized::TableSyntax
+ include Runtime::Fixtures
+ include Support::Helpers::MaskToken
- let!(:registry_scope) { Runtime::Namespace.sandbox_name }
- let!(:personal_access_token) do
- Flow::Login.sign_in unless Page::Main::Menu.perform(&:signed_in?)
+ let!(:registry_scope) { Runtime::Namespace.sandbox_name }
+ let!(:personal_access_token) do
+ Flow::Login.sign_in unless Page::Main::Menu.perform(&:signed_in?)
- Resource::PersonalAccessToken.fabricate!.token
+ Resource::PersonalAccessToken.fabricate!.token
+ end
+
+ let(:project_deploy_token) do
+ Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'npm-deploy-token'
+ deploy_token.project = project
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
end
+ end
- let(:project_deploy_token) do
- Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
- deploy_token.name = 'npm-deploy-token'
- deploy_token.project = project
- deploy_token.scopes = %w[
- read_repository
- read_package_registry
- write_package_registry
- ]
- end
+ let(:gitlab_address_without_port) { Support::GitlabAddress.address_with_port(with_default_port: false) }
+ let(:gitlab_host_without_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
+ let!(:project) { create(:project, :private, name: 'npm-project-level') }
+ let!(:runner) do
+ Resource::ProjectRunner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{project.name}"]
+ runner.executor = :docker
+ runner.project = project
end
+ end
- let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
- let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
- let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" }
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = "@#{registry_scope}/mypackage-#{SecureRandom.hex(8)}"
+ package.project = project
+ end
+ end
- let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'npm-project-level'
- project.visibility = :private
+ after do
+ package.remove_via_api!
+ runner.remove_via_api!
+ project.remove_via_api!
+ end
+
+ where(:case_name, :authentication_token_type, :token_name, :testcase) do
+ 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347592'
+ 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347594'
+ 'using project deploy token' | :project_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347593'
+ end
+
+ with_them do
+ let(:auth_token) do
+ case authentication_token_type
+ when :personal_access_token
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :project_deploy_token
+ use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
end
end
- let!(:runner) do
- Resource::ProjectRunner.fabricate! do |runner|
- runner.name = "qa-runner-#{Time.now.to_i}"
- runner.tags = ["runner-for-#{project.name}"]
- runner.executor = :docker
- runner.project = project
+ it 'push and pull a npm package via CI', testcase: params[:testcase] do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ npm_upload_install_yaml = ERB.new(read_fixture('package_managers/npm', 'npm_upload_install_package_project.yaml.erb')).result(binding)
+ package_json = ERB.new(read_fixture('package_managers/npm', 'package.json.erb')).result(binding)
+
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: npm_upload_install_yaml
+ },
+ {
+ file_path: 'package.json',
+ content: package_json
+ }
+ ])
end
- end
- let(:package) do
- Resource::Package.init do |package|
- package.name = "@#{registry_scope}/mypackage-#{SecureRandom.hex(8)}"
- package.project = project
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
end
- end
- after do
- package.remove_via_api!
- runner.remove_via_api!
- project.remove_via_api!
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
- where(:case_name, :authentication_token_type, :token_name, :testcase) do
- 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347592'
- 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347594'
- 'using project deploy token' | :project_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347593'
- end
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ job.click_browse_button
+ end
+
+ Page::Project::Artifact::Show.perform do |artifacts|
+ artifacts.go_to_directory('node_modules')
+ artifacts.go_to_directory("@#{registry_scope}")
+ expect(artifacts).to have_content('mypackage')
+ end
+
+ project.visit!
+ Page::Project::Menu.perform(&:go_to_package_registry)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
- with_them do
- let(:auth_token) do
- case authentication_token_type
- when :personal_access_token
- use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project)
- when :ci_job_token
- '${CI_JOB_TOKEN}'
- when :project_deploy_token
- use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
- end
+ index.click_package(package.name)
end
- it 'push and pull a npm package via CI', testcase: params[:testcase] do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- npm_upload_install_yaml = ERB.new(read_fixture('package_managers/npm', 'npm_upload_install_package_project.yaml.erb')).result(binding)
- package_json = ERB.new(read_fixture('package_managers/npm', 'package.json.erb')).result(binding)
-
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: npm_upload_install_yaml
- },
- {
- file_path: 'package.json',
- content: package_json
- }
- ])
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- job.click_browse_button
- end
-
- Page::Project::Artifact::Show.perform do |artifacts|
- artifacts.go_to_directory('node_modules')
- artifacts.go_to_directory("@#{registry_scope}")
- expect(artifacts).to have_content('mypackage')
- end
-
- project.visit!
- Page::Project::Menu.perform(&:go_to_package_registry)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
-
- index.click_package(package.name)
- end
-
- Page::Project::Packages::Show.perform do |show|
- expect(show).to have_package_info(package.name, "1.0.0")
- end
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package.name, "1.0.0")
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
index 5413ae85dcd..04e020178ee 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
@@ -1,20 +1,13 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'NuGet group level endpoint' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'NuGet group level endpoint', :external_api_calls do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'nuget-package-project'
- project.template_name = 'dotnetcore'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'nuget-package-project', template_name: 'dotnetcore') }
let(:personal_access_token) do
unless Page::Main::Menu.perform(&:signed_in?)
Flow::Login.sign_in
@@ -42,14 +35,7 @@ module QA
end
end
- let(:another_project) do
- Resource::Project.fabricate_via_api! do |another_project|
- another_project.name = 'nuget-package-install-project'
- another_project.template_name = 'dotnetcore'
- another_project.group = project.group
- end
- end
-
+ let(:another_project) { create(:project, name: 'nuget-package-install-project', template_name: 'dotnetcore', group: project.group) }
let(:package_project_inbound_job_token_disabled) do
Resource::CICDSettings.fabricate_via_api! do |settings|
settings.project_path = project.full_path
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
index 9a192bc005f..b4cac8af1dc 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
@@ -1,20 +1,12 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'NuGet project level endpoint' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'NuGet project level endpoint', :external_api_calls do
include Support::Helpers::MaskToken
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'nuget-package-project'
- project.template_name = 'dotnetcore'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'nuget-package-project', template_name: 'dotnetcore') }
let(:personal_access_token) { Resource::PersonalAccessToken.fabricate! }
-
let(:project_deploy_token) do
Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
deploy_token.name = 'package-deploy-token'
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb
index 7e2885d3724..80439501299 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb
@@ -2,22 +2,11 @@
module QA
RSpec.describe 'Package', :object_storage, product_group: :package_registry do
- describe 'PyPI Repository',
- quarantine: {
- only: { job: %w[relative_url airgapped] },
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417592',
- type: :investigating
- } do
+ describe 'PyPI Repository', :external_api_calls do
include Runtime::Fixtures
include Support::Helpers::MaskToken
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pypi-package-project'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'pypi-package-project') }
let(:package) do
Resource::Package.init do |package|
package.name = "mypypipackage-#{SecureRandom.hex(8)}"
@@ -40,15 +29,8 @@ module QA
use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: Runtime::Env.personal_access_token, project: project)
end
- let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
- let(:gitlab_host_with_port) do
- # Don't specify port if it is a standard one
- if uri.port == 80 || uri.port == 443
- uri.host
- else
- "#{uri.host}:#{uri.port}"
- end
- end
+ let(:gitlab_address_with_port) { Support::GitlabAddress.address_with_port }
+ let(:gitlab_host_with_port) { Support::GitlabAddress.host_with_port(with_default_port: false) }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb
index 0c58d41d96e..c77bb9b1b4b 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb
@@ -1,18 +1,12 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' },
+ RSpec.describe 'Package', :object_storage, :external_api_calls,
feature_flag: { name: 'rubygem_packages', scope: :project } do
describe 'RubyGems Repository', product_group: :package_registry do
include Runtime::Fixtures
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'rubygems-package-project'
- project.visibility = :private
- end
- end
-
+ let(:project) { create(:project, :private, name: 'rubygems-package-project') }
let(:package) do
Resource::Package.init do |package|
package.name = "mygem-#{SecureRandom.hex(8)}"
@@ -30,8 +24,7 @@ module QA
end
let(:gitlab_address_with_port) do
- uri = URI.parse(Runtime::Scenario.gitlab_address)
- "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ Support::GitlabAddress.address_with_port
end
before do
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
index 51006dd1e38..d9a1f1cd4a6 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
@@ -7,13 +7,7 @@ module QA
describe 'Git clone using a deploy key' do
let(:runner_name) { "qa-runner-#{SecureRandom.hex(4)}" }
let(:repository_location) { project.repository_ssh_location }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'deploy-key-clone-project'
- end
- end
-
+ let(:project) { create(:project, name: 'deploy-key-clone-project') }
let!(:runner) do
Resource::ProjectRunner.fabricate_via_api! do |resource|
resource.project = project
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
index 42a64099a3d..7e941a135f1 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
@@ -25,12 +25,11 @@ module QA
with_them do
let!(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = "#{template}-autodevops-project-template"
- project.template_name = template
- project.description = "Let's see if the #{template} project works..."
- project.auto_devops_enabled = true
- end
+ create(:project,
+ :auto_devops,
+ name: "#{template}-autodevops-project-template",
+ template_name: template,
+ description: "Let's see if the #{template} project works")
end
let(:pipeline) do
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index 0a9f30f0529..8ee77f5c054 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -4,16 +4,8 @@ module QA
RSpec.describe 'Configure',
only: { pipeline: %i[staging staging-canary canary production] }, product_group: :configure do
describe 'Auto DevOps with a Kubernetes Agent' do
- let!(:app_project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'autodevops-app-project'
- project.template_name = 'express'
- project.auto_devops_enabled = true
- end
- end
-
+ let!(:app_project) { create(:project, :auto_devops, name: 'autodevops-app-project', template_name: 'express') }
let!(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::Gcloud).create! }
-
let!(:kubernetes_agent) do
Resource::Clusters::Agent.fabricate_via_api! do |agent|
agent.name = 'agent1'
@@ -28,7 +20,7 @@ module QA
end
before do
- cluster.install_kubernetes_agent(agent_token.token)
+ cluster.install_kubernetes_agent(agent_token.token, kubernetes_agent.name)
upload_agent_config(app_project, kubernetes_agent.name)
set_kube_ingress_base_domain(app_project)
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/alert_settings_create_new_alerts_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/alert_settings_create_new_alerts_spec.rb
index b44020ddfce..79739006928 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/alert_settings_create_new_alerts_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/alert_settings_create_new_alerts_spec.rb
@@ -12,13 +12,7 @@ module QA
end
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-alerts'
- project.description = 'Project for alerts'
- end
- end
-
+ let(:project) { create(:project, name: 'project-for-alerts', description: 'Project for alerts') }
let(:alert_title) { Faker::Lorem.word }
before do
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/automatically_creates_incident_for_alert_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/automatically_creates_incident_for_alert_spec.rb
index 565f56b90ec..dff130a5793 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/automatically_creates_incident_for_alert_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/automatically_creates_incident_for_alert_spec.rb
@@ -12,12 +12,7 @@ module QA
end
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-alerts'
- project.description = 'Project for alerts'
- end
- end
+ let(:project) { create(:project, name: 'project-for-alerts', description: 'Project for alerts') }
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/create_alert_using_authorization_key_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/create_alert_using_authorization_key_spec.rb
index 96db10c1683..dfc41fdad85 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/create_alert_using_authorization_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/create_alert_using_authorization_key_spec.rb
@@ -28,15 +28,8 @@ module QA
end
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-alerts'
- project.description = 'Project for alerts'
- end
- end
-
+ let(:project) { create(:project, name: 'project-for-alerts', description: 'Project for alerts') }
let(:alert_title) { Faker::Lorem.word }
-
let(:credentials) do
Flow::AlertSettings.integration_credentials
end
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb
index 008d8f808b3..85aa12062d5 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb
@@ -19,13 +19,7 @@ module QA
end
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-for-alerts'
- project.description = 'Project for alerts'
- end
- end
-
+ let(:project) { create(:project, name: 'project-for-alerts', description: 'Project for alerts') }
let(:alert_title) { Faker::Lorem.word }
let(:mail_hog_api) { Vendor::MailHog::API.new }
let(:alert_email_subject) { "#{project.name} | Alert: #{alert_title}" }
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb
index 1206898431a..0c977e5259c 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb
@@ -12,10 +12,7 @@ module QA
end
let!(:group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "group-for-access-request-#{SecureRandom.hex(8)}"
- group.api_client = admin_api_client
- end
+ create(:group, path: "group-for-access-request-#{SecureRandom.hex(8)}", api_client: admin_api_client)
end
before do
@@ -27,7 +24,7 @@ module QA
Flow::Login.sign_in_as_admin
Page::Main::Menu.perform do |menu|
- menu.go_to_page_by_shortcut(:todos_shortcut_button)
+ menu.go_to_page_by_shortcut('todos-shortcut-button')
end
Page::Dashboard::Todos.perform do |todos|
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb
index 2f14e2c10da..2a1f8a58108 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb
@@ -3,23 +3,12 @@
module QA
RSpec.describe 'Data Stores' do
describe 'Subgroup transfer', product_group: :tenant_scale do
- let(:source_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "source-group-for-transfer_#{SecureRandom.hex(8)}"
- end
- end
+ let(:source_group) { create(:group, path: "source-group-for-transfer_#{SecureRandom.hex(8)}") }
- let!(:target_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "target-group-for-transfer_#{SecureRandom.hex(8)}"
- end
- end
+ let!(:target_group) { create(:group, path: "target-group-for-transfer_#{SecureRandom.hex(8)}") }
let(:sub_group_for_transfer) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "subgroup-for-transfer_#{SecureRandom.hex(8)}"
- group.sandbox = source_group
- end
+ create(:group, path: "subgroup-for-transfer_#{SecureRandom.hex(8)}", sandbox: source_group)
end
before do
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb
index 02e1598d6e7..6de1d08e674 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb
@@ -2,26 +2,10 @@
module QA
RSpec.describe 'Data Stores' do
- describe 'Project transfer between groups', :reliable, product_group: :tenant_scale do
- let(:source_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "source-group-#{SecureRandom.hex(8)}"
- end
- end
-
- let!(:target_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "target-group-for-transfer_#{SecureRandom.hex(8)}"
- end
- end
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.group = source_group
- project.name = 'transfer-project'
- end
- end
-
+ describe 'Project transfer', :reliable, product_group: :tenant_scale do
+ let(:project) { create(:project, name: 'transfer-project', group: source_group) }
+ let(:source_group) { create(:group, path: "source-group-#{SecureRandom.hex(8)}") }
+ let!(:target_group) { create(:group, path: "target-group-for-transfer_#{SecureRandom.hex(8)}") }
let(:readme_content) { 'Here is the edited content.' }
before do
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb
index 0beb297ffdb..7fb970c3f25 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb
@@ -2,16 +2,13 @@
module QA
RSpec.describe 'Data Stores', :reliable, product_group: :tenant_scale do
- describe 'Add project member' do
- it 'user adds project member', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347887' do
+ describe 'Project Member' do
+ it 'adds a project member', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347887' do
Flow::Login.sign_in
user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
- project = Resource::Project.fabricate_via_api! do |project|
- project.name = 'add-member-project'
- end
-
+ project = create(:project, name: 'add-member-project')
project.visit!
Page::Project::Menu.perform(&:click_members)
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb
index 87492af089e..22f8cc93737 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb
@@ -2,26 +2,21 @@
module QA
RSpec.describe 'Data Stores' do
- describe 'Create project badge', :reliable, product_group: :tenant_scale do
+ describe 'Project badge', :reliable, product_group: :tenant_scale do
let(:badge_name) { "project-badge-#{SecureRandom.hex(8)}" }
let(:expected_badge_link_url) { "#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}" }
let(:expected_badge_image_url) do
"#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}/badges/main/pipeline.svg"
end
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'badge-test-project'
- project.initialize_with_readme = true
- end
- end
+ let(:project) { create(:project, :with_readme, name: 'badge-test-project') }
before do
Flow::Login.sign_in
project.visit!
end
- it 'creates project badge successfully',
+ it 'creates project badge',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/350065' do
Resource::ProjectBadge.fabricate! do |badge|
badge.name = badge_name
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb
index f2136773f59..2ea96dfef95 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb
@@ -16,7 +16,7 @@ module QA
user.remove_via_api!
end
- it 'loads all images' do
+ it do
Flow::Login.sign_in(as: user)
Page::Dashboard::Welcome.perform do |welcome|
@@ -32,14 +32,14 @@ module QA
describe 'Check for broken images', :requires_admin, :reliable do
context(
- 'when logged in as a new user',
+ 'when a new user logs in',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347885'
) do
it_behaves_like 'loads all images', false
end
context(
- 'when logged in as a new admin',
+ 'when a new admin logs in',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347884'
) do
it_behaves_like 'loads all images', true
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb
index c7501d437eb..29e39d48c67 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb
@@ -4,7 +4,7 @@ module QA
RSpec.describe 'Data Stores' do
describe 'Invite group', :reliable, product_group: :tenant_scale do
shared_examples 'invites group to project' do
- it 'verifies group is added and members can access project with correct access level' do
+ it 'grants group and members correct access level' do
Page::Project::Menu.perform(&:click_members)
Page::Project::Members.perform do |project_members|
project_members.invite_group(group.path, 'Developer')
@@ -40,19 +40,14 @@ module QA
context 'with a personal namespace project',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do
- let(:group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "group-for-personal-project-#{SecureRandom.hex(8)}"
- end
- end
+ let(:group) { create(:group, path: "group-for-personal-project-#{SecureRandom.hex(8)}") }
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'personal-namespace-project'
- project.personal_namespace = Runtime::User.username
- project.visibility = :private
- project.description = 'test personal namespace project'
- end
+ create(:project,
+ :private,
+ name: 'personal-namespace-project',
+ description: 'test personal namespace project',
+ personal_namespace: Runtime::User.username)
end
after do
@@ -64,19 +59,9 @@ module QA
end
context 'with a group project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349340' do
- let(:group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "group-for-group-project-#{SecureRandom.hex(8)}"
- end
- end
+ let(:group) { create(:group, path: "group-for-group-project-#{SecureRandom.hex(8)}") }
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'group-project'
- project.visibility = :private
- project.description = 'test group project'
- end
- end
+ let(:project) { create(:project, :private, name: 'group-project', description: 'test group project') }
after do
project.remove_via_api!
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
index 2793b0440a4..310b8747584 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
@@ -13,7 +13,7 @@ module QA
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
end
- shared_examples 'when user is added as owner' do |project_type, testcase|
+ shared_examples 'adds user as owner' do |project_type, testcase|
let!(:issue) do
Resource::Issue.fabricate_via_api! do |issue|
issue.api_client = owner_api_client
@@ -27,7 +27,7 @@ module QA
Flow::Login.sign_in(as: owner)
end
- it "has owner role with owner permissions", testcase: testcase do
+ it "has owner role and permissions", testcase: testcase do
Page::Dashboard::Projects.perform do |projects|
projects.filter_by_name(project.name)
@@ -44,7 +44,7 @@ module QA
end
end
- shared_examples 'when user is added as maintainer' do |testcase|
+ shared_examples 'adds user as maintainer' do |testcase|
let!(:issue) do
Resource::Issue.fabricate_via_api! do |issue|
issue.api_client = owner_api_client
@@ -82,12 +82,12 @@ module QA
end
end
- it_behaves_like 'when user is added as owner', :personal_project, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352542'
- it_behaves_like 'when user is added as maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352607'
+ it_behaves_like 'adds user as owner', :personal_project, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352542'
+ it_behaves_like 'adds user as maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352607'
end
context 'for group projects' do
- let!(:group) { Resource::Group.fabricate_via_api! }
+ let!(:group) { create(:group) }
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -96,8 +96,8 @@ module QA
end
end
- it_behaves_like 'when user is added as owner', :group_project, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366436'
- it_behaves_like 'when user is added as maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366435'
+ it_behaves_like 'adds user as owner', :group_project, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366436'
+ it_behaves_like 'adds user as maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366435'
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb
index 4945ef533a4..5cdb88407fb 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb
@@ -3,22 +3,24 @@
module QA
RSpec.describe 'Data Stores' do
describe 'Project activity', :reliable, product_group: :tenant_scale do
- it 'user creates an event in the activity page upon Git push',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
- Flow::Login.sign_in
+ context 'with git push' do
+ it 'creates an event in the activity page',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
+ Flow::Login.sign_in
- project = Resource::Repository::ProjectPush.fabricate! do |push|
- push.file_name = 'README.md'
- push.file_content = '# This is a test project'
- push.commit_message = 'Add README.md'
- end.project
+ project = Resource::Repository::ProjectPush.fabricate! do |push|
+ push.file_name = 'README.md'
+ push.file_content = '# This is a test project'
+ push.commit_message = 'Add README.md'
+ end.project
- project.visit!
- Page::Project::Menu.perform(&:click_activity)
- Page::Project::Activity.perform do |activity|
- activity.click_push_events
+ project.visit!
+ Page::Project::Menu.perform(&:click_activity)
+ Page::Project::Activity.perform do |activity|
+ activity.click_push_events
- expect(activity).to have_content("pushed new branch #{project.default_branch}")
+ expect(activity).to have_content("pushed new branch #{project.default_branch}")
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
index c78151b94b7..a119d600667 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
@@ -22,10 +22,9 @@ module QA
end
let(:group) do
- group = QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "group_for_follow_user_activity_#{SecureRandom.hex(8)}"
- group.api_client = admin_api_client
- end
+ group = create(:group,
+ path: "group_for_follow_user_activity_#{SecureRandom.hex(8)}",
+ api_client: admin_api_client)
group.add_member(followed_user, Resource::Members::AccessLevel::MAINTAINER)
group
end
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
index 7e88f3a9ac3..562bd1b1aa1 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
@@ -11,11 +11,7 @@ module QA
end
end
- let!(:group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "group-to-test-access-termination-#{SecureRandom.hex(8)}"
- end
- end
+ let!(:group) { create(:group, path: "group-to-test-access-termination-#{SecureRandom.hex(8)}") }
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -25,7 +21,7 @@ module QA
end
end
- context 'when parent group membership is terminated' do
+ context 'with terminated parent group membership' do
before do
group.add_member(user)
@@ -40,7 +36,7 @@ module QA
end
end
- it 'is not allowed to edit the project files',
+ it 'can not edit the project files',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347866' do
Flow::Login.sign_in(as: user)
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
index 78baba403fd..8553e1739ce 100644
--- a/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
@@ -6,16 +6,11 @@ module QA
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:parent_group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "parent-group-to-test-user-access-#{SecureRandom.hex(8)}"
- end
+ create(:group, path: "parent-group-to-test-user-access-#{SecureRandom.hex(8)}")
end
let!(:sub_group) do
- QA::Resource::Group.fabricate_via_api! do |group|
- group.path = "sub-group-to-test-user-access-#{SecureRandom.hex(8)}"
- group.sandbox = parent_group
- end
+ create(:group, path: "sub-group-to-test-user-access-#{SecureRandom.hex(8)}", sandbox: parent_group)
end
context 'when added to parent group' do
diff --git a/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb b/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
index 55ed9abb0da..445586d31ac 100644
--- a/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
+++ b/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
@@ -10,10 +10,7 @@ module QA
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:group) do
- Resource::Group.fabricate_via_api! do |resource|
- resource.api_client = api_client
- resource.path = "destination-group-for-import-#{SecureRandom.hex(4)}"
- end
+ create(:group, api_client: api_client, path: "destination-group-for-import-#{SecureRandom.hex(4)}")
end
let!(:user) do
diff --git a/qa/qa/specs/features/shared_contexts/packages_registry_shared_context.rb b/qa/qa/specs/features/shared_contexts/packages_registry_shared_context.rb
index 5ab7bb331c0..3905a05633f 100644
--- a/qa/qa/specs/features/shared_contexts/packages_registry_shared_context.rb
+++ b/qa/qa/specs/features/shared_contexts/packages_registry_shared_context.rb
@@ -51,8 +51,7 @@ module QA
end
let(:gitlab_address_with_port) do
- uri = URI.parse(Runtime::Scenario.gitlab_address)
- "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ Support::GitlabAddress.address_with_port
end
let(:project_deploy_token) do
diff --git a/qa/qa/specs/features/shared_contexts/variable_inheritance_shared_context.rb b/qa/qa/specs/features/shared_contexts/variable_inheritance_shared_context.rb
index 2219031e9c6..69786c55be8 100644
--- a/qa/qa/specs/features/shared_contexts/variable_inheritance_shared_context.rb
+++ b/qa/qa/specs/features/shared_contexts/variable_inheritance_shared_context.rb
@@ -5,12 +5,7 @@ module QA
let(:key) { 'TEST_VAR' }
let(:value) { 'This is great!' }
let(:random_string) { Faker::Alphanumeric.alphanumeric(number: 8) }
-
- let(:group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "group-for-variable-inheritance-#{random_string}"
- end
- end
+ let(:group) { create(:group, path: "group-for-variable-inheritance-#{random_string}") }
let(:upstream_project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/shared_examples/create_and_terminate_workspace_shared_examples.rb b/qa/qa/specs/features/shared_examples/create_and_terminate_workspace_shared_examples.rb
new file mode 100644
index 00000000000..7a9a485d611
--- /dev/null
+++ b/qa/qa/specs/features/shared_examples/create_and_terminate_workspace_shared_examples.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.shared_examples 'workspaces actions' do
+ it 'creates a new workspace and then stops and terminates it' do
+ QA::Page::Main::Menu.perform(&:go_to_workspaces)
+ workspace_name = ""
+
+ QA::EE::Page::Workspace::List.perform do |list|
+ existing_workspaces = list.get_workspaces_list
+ list.create_workspace(kubernetes_agent.name, devfile_project.name)
+ updated_workspaces = list.get_workspaces_list
+ workspace_name = (updated_workspaces - existing_workspaces).fetch(0, '').to_s
+ raise "Workspace name is empty" if workspace_name == ''
+
+ expect(list).to have_workspace_state(workspace_name, "Creating")
+ list.wait_for_workspaces_creation(workspace_name)
+ expect(list).to have_workspace_state(workspace_name, "Running")
+ end
+
+ QA::EE::Page::Workspace::Action.perform do |workspace|
+ workspace.click_workspace_action(workspace_name, "stop")
+ end
+
+ QA::EE::Page::Workspace::List.perform do |list_item|
+ expect(list_item).to have_workspace_state(workspace_name, "Stopped")
+ end
+
+ QA::EE::Page::Workspace::Action.perform do |workspace|
+ workspace.click_workspace_action(workspace_name, "terminate")
+ end
+
+ QA::EE::Page::Workspace::List.perform do |list_item|
+ expect(list_item).to have_workspace_state(workspace_name, "Terminated")
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb
index 1601dd46c62..965e3c2f88c 100644
--- a/qa/qa/specs/spec_helper.rb
+++ b/qa/qa/specs/spec_helper.rb
@@ -1,7 +1,12 @@
# frozen_string_literal: true
-require_relative '../../qa'
require 'active_support/testing/time_helpers'
+require 'factory_bot'
+
+require_relative '../../qa'
+
+# Require shared test tooling from Rails test suite
+require_relative '../../../spec/support/fast_quarantine'
QA::Specs::QaDeprecationToolkitEnv.configure!
@@ -24,6 +29,9 @@ RSpec.configure do |config|
config.include ActiveSupport::Testing::TimeHelpers
config.include QA::Support::Matchers::EventuallyMatcher
config.include QA::Support::Matchers::HaveMatcher
+ config.include FactoryBot::Syntax::Methods
+
+ FactoryBot.definition_file_paths = ['qa/factories']
config.add_formatter QA::Support::Formatters::ContextFormatter
config.add_formatter QA::Support::Formatters::QuarantineFormatter
@@ -41,6 +49,10 @@ RSpec.configure do |config|
Thread.current[:browser_ui_fabrication] = 0
end
+ config.before(:suite) do
+ FactoryBot.find_definitions
+ end
+
config.after do
# If a .netrc file was created during the test, delete it so that subsequent tests don't try to use the same logins
QA::Git::Repository.new.delete_netrc
diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb
index 0081b1c1d46..f0a73391d5d 100644
--- a/qa/qa/support/api.rb
+++ b/qa/qa/support/api.rb
@@ -99,6 +99,15 @@ module QA
url.sub(/private_token=[^&]*/, "private_token=[****]")
end
+ # Returns the response body with secrets masked.
+ #
+ # @param [String] response the response body as the string value of a JSON hash
+ # @param [Array<Symbol>] mask_by_key the keys of the JSON parsed response body whose values will be masked
+ # @return [Hash] the response body with the specified secrets values replaced with `****`
+ def masked_parsed_response(response, mask_by_key:)
+ Helpers::Masker.mask(parse_body(response), by_key: Array(mask_by_key))
+ end
+
# Merges the gitlab_canary cookie into existing cookies for mixed environment testing.
#
# @param [Hash] args the existing args passed to method
diff --git a/qa/qa/support/formatters/test_metrics_formatter.rb b/qa/qa/support/formatters/test_metrics_formatter.rb
index cdc0e83dc02..5b3f5d1d77a 100644
--- a/qa/qa/support/formatters/test_metrics_formatter.rb
+++ b/qa/qa/support/formatters/test_metrics_formatter.rb
@@ -74,11 +74,15 @@ module QA
def save_test_metrics
return log(:debug, "Saving test metrics json not enabled, skipping") unless save_metrics_json?
- File.write("tmp/test-metrics-#{env('CI_JOB_NAME_SLUG') || 'local'}.json", execution_data.to_json)
+ file = "tmp/test-metrics-#{env('CI_JOB_NAME_SLUG') || 'local'}.json"
+
+ File.write(file, execution_data.to_json) && log(:debug, "Saved test metrics to #{file}")
rescue StandardError => e
log(:error, "Failed to save test execution metrics, error: #{e}")
end
+ # rubocop:disable Metrics/AbcSize
+
# Transform example to influxdb compatible metrics data
# https://github.com/influxdata/influxdb-client-ruby#data-format
#
@@ -123,6 +127,7 @@ module QA
pipeline_id: env('CI_PIPELINE_ID'),
job_id: env('CI_JOB_ID'),
merge_request_iid: merge_request_iid,
+ failure_exception: example.execution_result.exception.to_s.delete("\n"),
**custom_metrics_fields(example.metadata)
}
}
@@ -131,6 +136,8 @@ module QA
nil
end
+ # rubocop:enable Metrics/AbcSize
+
# Resource fabrication data point
#
# @param [String] resource
diff --git a/qa/qa/support/gitlab_address.rb b/qa/qa/support/gitlab_address.rb
index d978bb2eee5..0dff8413706 100644
--- a/qa/qa/support/gitlab_address.rb
+++ b/qa/qa/support/gitlab_address.rb
@@ -13,17 +13,43 @@ module QA
validate_address(address)
- Runtime::Scenario.define(:gitlab_address, address)
+ Runtime::Scenario.define(:gitlab_address, address_with_port(address, with_default_port: false))
# Define the "About" page as an `about` subdomain.
# @example
# Given *gitlab_address* = 'https://gitlab.com/' #=> https://about.gitlab.com/
# Given *gitlab_address* = 'https://staging.gitlab.com/' #=> https://about.staging.gitlab.com/
# Given *gitlab_address* = 'http://gitlab-abc123.test/' #=> http://about.gitlab-abc123.test/
- Runtime::Scenario.define(:about_address, URI(address).tap { |uri| uri.host = "about.#{uri.host}" }.to_s)
+ Runtime::Scenario.define(
+ :about_address,
+ URI(address).then { |uri| "#{uri.scheme}://about.#{host_with_port(address, with_default_port: false)}" }
+ )
@initialized = true
end
+ # Get gitlab address with port and path
+ #
+ # @param [String] address
+ # @param [Boolean] with_default_port keep default port 80 or 443
+ # @return [String]
+ def address_with_port(address = Runtime::Scenario.gitlab_address, with_default_port: true)
+ uri = URI.parse(address)
+
+ "#{uri.scheme}://#{host_with_port(uri, with_default_port: with_default_port)}"
+ end
+
+ # Get gitlab host with port and path
+ #
+ # @param [<String, URI>] address
+ # @param [Boolean] with_default_port keep default port 80 or 443
+ # @return [String]
+ def host_with_port(address = Runtime::Scenario.gitlab_address, with_default_port: true)
+ uri = address.is_a?(URI) ? address : URI.parse(address)
+ port = !with_default_port && [80, 443].include?(uri.port) ? "" : ":#{uri.port}"
+
+ "#{uri.host}#{port}#{uri.path}"
+ end
+
private
# Gitlab address already set up
diff --git a/qa/qa/support/helpers/masker.rb b/qa/qa/support/helpers/masker.rb
new file mode 100644
index 00000000000..8a01336483f
--- /dev/null
+++ b/qa/qa/support/helpers/masker.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module QA
+ module Support
+ module Helpers
+ # A helper class to mask secrets.
+ class Masker
+ # Returns the content with secrets masked.
+ #
+ # @param [Object] content the content to mask
+ # @param [Array<Symbol>] by_key the keys of the content whose values will be masked
+ # @param [Array<String>] by_value the content to be masked. Masks whole- or sub-strings
+ # @param [String] mask the string used to replace secrets (default '****')
+ # @return [Object] the content with the specified secrets replaced with the mask
+ def self.mask(content, by_key: [], by_value: [], mask: '****')
+ new(by_key: by_key, by_value: by_value, mask: mask).mask(content)
+ end
+
+ # @param [Array<Symbol>] by_key the keys of the content whose values will be masked
+ # @param [Array<String>] by_value the content to be masked. Masks whole- or sub-strings
+ # @param [String] mask the string used to replace secrets (default '****')
+ def initialize(by_key: [], by_value: [], mask: '****')
+ by_key.present? || by_value.present? ||
+ raise(ArgumentError, 'Please specify `by_key` or `by_value`')
+
+ @by_key = Array(by_key)
+ @by_value = Array(by_value)
+ @mask = mask
+ end
+
+ # @param [Object] content the content to mask
+ # @return [Object] the content with the specified secrets replaced with the mask
+ def mask(content)
+ return content if content.blank? || [true, false].include?(content)
+
+ @content = content
+ @content = mask_by_key(@content) if @by_key.present?
+ @content = mask_by_value(@content) if @by_value.present?
+ @content
+ end
+
+ private
+
+ attr_reader :by_key, :by_value
+
+ # Masks by using the given secrets as hash keys. If the key exists, the corresponding value is replaced with the
+ # mask. Recursively masks nested hashes and arrays.
+ def mask_by_key(content)
+ case content
+ when Hash
+ ActiveSupport::ParameterFilter.new(by_key, mask: @mask).filter(content)
+ when Array
+ content.map { |item| mask_by_key(item) }
+ else
+ content
+ end
+ end
+
+ # Masks by substituting the given secrets found in the content. If a secret exists as substrings, the substrings
+ # are replaced with the mask. Recursively masks nested hashes and arrays, and each element of arrays.
+ def mask_by_value(content)
+ case content
+ when Hash
+ content.each { |k, v| content[k] = mask_by_value(v) }
+ when Array
+ content.map { |item| mask_by_value(item) }
+ when String
+ by_value.reduce(content) { |s, secret| s.gsub(secret.to_s, @mask) }
+ else
+ by_value.include?(content) ? @mask : content
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/helpers/plan.rb b/qa/qa/support/helpers/plan.rb
index b6950c6bacd..c3867b4a1b8 100644
--- a/qa/qa/support/helpers/plan.rb
+++ b/qa/qa/support/helpers/plan.rb
@@ -56,6 +56,14 @@ module QA
storage: 10
}.freeze
+ CODE_SUGGESTIONS = {
+ # Annual plan, rate and price
+ plan_id: '8a8aa0ac8874ddc4018878da1f736782',
+ rate_charge_id: '8a8aa0ac8874ddc4018878da1f9a6784',
+ name: 'code suggestions',
+ price: 108
+ }.freeze
+
LICENSE_TYPE = {
legacy_license: 'legacy license',
online_cloud: 'online license',
diff --git a/qa/qa/support/matchers/have_matcher.rb b/qa/qa/support/matchers/have_matcher.rb
index c77b585ada8..6fa88ef205b 100644
--- a/qa/qa/support/matchers/have_matcher.rb
+++ b/qa/qa/support/matchers/have_matcher.rb
@@ -30,6 +30,7 @@ module QA
alert_with_title
incident
framework
+ delete_issue_button
].each do |predicate|
RSpec::Matchers.define "have_#{predicate}" do |*args, **kwargs|
match do |page_object|
diff --git a/qa/qa/support/wait_for_requests.rb b/qa/qa/support/wait_for_requests.rb
index 2856602629a..8c7d87e960a 100644
--- a/qa/qa/support/wait_for_requests.rb
+++ b/qa/qa/support/wait_for_requests.rb
@@ -7,9 +7,10 @@ module QA
DEFAULT_MAX_WAIT_TIME = 60
- def wait_for_requests(skip_finished_loading_check: false, skip_resp_code_check: false)
+ def wait_for_requests(skip_finished_loading_check: false, skip_resp_code_check: false, finish_loading_wait: 1)
Waiter.wait_until(log: false) do
- finished_all_ajax_requests? && (!skip_finished_loading_check ? finished_loading?(wait: 1) : true)
+ finished_all_ajax_requests? &&
+ (!skip_finished_loading_check ? finished_loading?(wait: finish_loading_wait) : true)
end
rescue Repeater::WaitExceededError
raise $!, 'Page did not fully load. This could be due to an unending async request or loading icon.'
diff --git a/qa/qa/tools/ci/helpers.rb b/qa/qa/tools/ci/helpers.rb
index 55bb123de20..4650532f89a 100644
--- a/qa/qa/tools/ci/helpers.rb
+++ b/qa/qa/tools/ci/helpers.rb
@@ -17,33 +17,6 @@ module QA
source: "CI Tools"
)
end
-
- # Api get request
- #
- # @param [String] path
- # @param [Hash] args
- # @return [Hash, Array]
- def api_get(path, **args)
- response = get("#{api_url}/#{path}", { headers: { "PRIVATE-TOKEN" => access_token }, **args })
- response = response.follow_redirection if response.code == Support::API::HTTP_STATUS_PERMANENT_REDIRECT
- raise "Request failed: '#{response.body}'" unless response.code == Support::API::HTTP_STATUS_OK
-
- args[:raw_response] ? response : parse_body(response)
- end
-
- # Gitlab api url
- #
- # @return [String]
- def api_url
- @api_url ||= ENV.fetch('CI_API_V4_URL', 'https://gitlab.com/api/v4')
- end
-
- # Api access token
- #
- # @return [String]
- def access_token
- @access_token ||= ENV.fetch('QA_GITLAB_CI_TOKEN') { raise('Variable QA_GITLAB_CI_TOKEN missing') }
- end
end
end
end
diff --git a/qa/qa/vendor/saml_idp/page/login.rb b/qa/qa/vendor/saml_idp/page/login.rb
index 9b4fbe15366..dda9cd3758f 100644
--- a/qa/qa/vendor/saml_idp/page/login.rb
+++ b/qa/qa/vendor/saml_idp/page/login.rb
@@ -11,12 +11,6 @@ module QA
fill_in 'username', with: username
fill_in 'password', with: password
click_on 'Login'
-
- if Runtime::Env.super_sidebar_enabled?
- QA::Page::Main::Menu.perform(&:enable_new_navigation)
- else
- QA::Page::Main::Menu.perform(&:disable_new_navigation)
- end
end
def login_if_required(username, password)
diff --git a/qa/spec/page/element_spec.rb b/qa/spec/page/element_spec.rb
index da1fd224564..c354d55fb19 100644
--- a/qa/spec/page/element_spec.rb
+++ b/qa/spec/page/element_spec.rb
@@ -1,17 +1,10 @@
# frozen_string_literal: true
RSpec.describe QA::Page::Element do
- describe '#selector' do
- it 'transforms element name into QA-specific selector' do
- expect(described_class.new(:sign_in_button).selector)
- .to eq 'qa-sign-in-button'
- end
- end
-
describe '#selector_css' do
it 'transforms element name into QA-specific clickable css selector' do
expect(described_class.new(:sign_in_button).selector_css)
- .to include('.qa-sign-in-button')
+ .to eq('[data-testid="sign_in_button"],[data-qa-selector="sign_in_button"]')
end
end
@@ -42,10 +35,6 @@ RSpec.describe QA::Page::Element do
context 'when pattern is not provided' do
subject { described_class.new(:some_name) }
- it 'matches when QA specific selector is present' do
- expect(subject.matches?('some qa-some-name selector')).to be true
- end
-
it 'does not match if QA selector is not there' do
expect(subject.matches?('some_name selector')).to be false
end
@@ -53,15 +42,18 @@ RSpec.describe QA::Page::Element do
it 'matches when element name is specified' do
expect(subject.matches?('data:{qa:{selector:"some_name"}}')).to be true
end
+
+ it 'matches when element name is specified (single quotes)' do
+ expect(subject.matches?("data:{qa:{selector:'some_name'}}")).to be true
+ end
end
describe 'attributes' do
context 'element with no args' do
subject { described_class.new(:something) }
- it 'defaults pattern to #selector' do
- expect(subject.attributes[:pattern]).to eq 'qa-something'
- expect(subject.attributes[:pattern]).to eq subject.selector
+ it 'has no attribute[pattern]' do
+ expect(subject.attributes[:pattern]).to be(nil)
end
it 'is not required by default' do
@@ -84,11 +76,6 @@ RSpec.describe QA::Page::Element do
context 'element with requirement; no pattern' do
subject { described_class.new(:something, required: true) }
- it 'has an attribute[pattern] of the selector' do
- expect(subject.attributes[:pattern]).to eq 'qa-something'
- expect(subject.attributes[:pattern]).to eq subject.selector
- end
-
it 'is required' do
expect(subject.required?).to be true
end
@@ -104,10 +91,6 @@ RSpec.describe QA::Page::Element do
it 'is required' do
expect(subject.required?).to be true
end
-
- it 'has a selector of the name' do
- expect(subject.selector).to eq 'qa-something'
- end
end
end
@@ -126,18 +109,20 @@ RSpec.describe QA::Page::Element do
let(:element) { described_class.new(:my_element, index: 3, another_match: 'something') }
let(:required_element) { described_class.new(:my_element, required: true, index: 3) }
- it 'matches on additional data-qa properties' do
- expect(element.selector_css).to include(%q([data-qa-selector="my_element"][data-qa-index="3"]))
+ it 'matches on additional data-qa properties translating snake_case to kebab-case' do
+ expect(element.selector_css)
+ .to include('[data-testid="my_element"][data-qa-index="3"][data-qa-another-match="something"]')
+ expect(element.selector_css)
+ .to include('[data-qa-selector="my_element"][data-qa-index="3"][data-qa-another-match="something"]')
end
it 'doesnt conflict with element requirement' do
+ expect(element).not_to be_required
+ expect(element.selector_css).not_to include(%q(data-qa-required))
+
expect(required_element).to be_required
expect(required_element.selector_css).not_to include(%q(data-qa-required))
end
-
- it 'translates snake_case to kebab-case' do
- expect(element.selector_css).to include(%q(data-qa-another-match))
- end
end
end
end
diff --git a/qa/spec/support/api_spec.rb b/qa/spec/support/api_spec.rb
new file mode 100644
index 00000000000..5bf09da9020
--- /dev/null
+++ b/qa/spec/support/api_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe QA::Support::API do
+ describe ".masked_parsed_response" do
+ let(:response) { Struct.new(:body).new('{ "secret": "foobar", "name": "gitlab" }') }
+
+ it 'calls Masker to mask secrets' do
+ expect(QA::Support::Helpers::Masker).to receive(:mask)
+ .with(
+ JSON.parse(response.body, symbolize_names: true),
+ by_key: [:secret]
+ )
+
+ described_class.masked_parsed_response(response, mask_by_key: [:secret])
+ end
+
+ it 'accepts a single secret key' do
+ expect(QA::Support::Helpers::Masker).to receive(:mask)
+ .with(
+ JSON.parse(response.body, symbolize_names: true),
+ by_key: ['secret']
+ )
+
+ described_class.masked_parsed_response(response, mask_by_key: 'secret')
+ end
+ end
+ end
+end
diff --git a/qa/spec/support/formatters/test_metrics_formatter_spec.rb b/qa/spec/support/formatters/test_metrics_formatter_spec.rb
index 2b8a0791dc5..5342cfe12e3 100644
--- a/qa/spec/support/formatters/test_metrics_formatter_spec.rb
+++ b/qa/spec/support/formatters/test_metrics_formatter_spec.rb
@@ -68,7 +68,8 @@ describe QA::Support::Formatters::TestMetricsFormatter do
pipeline_url: ci_pipeline_url,
pipeline_id: ci_pipeline_id,
job_id: ci_job_id,
- merge_request_iid: nil
+ merge_request_iid: nil,
+ failure_exception: ''
}
}
end
diff --git a/qa/spec/support/gitlab_address_spec.rb b/qa/spec/support/gitlab_address_spec.rb
new file mode 100644
index 00000000000..c3a470b7547
--- /dev/null
+++ b/qa/spec/support/gitlab_address_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+RSpec.describe QA::Support::GitlabAddress do
+ subject(:gitlab_address) { described_class }
+
+ describe ".define_gitlab_address_attribute!" do
+ let(:address) { "http://example.com" }
+
+ before do
+ allow(QA::Runtime::Scenario).to receive(:define)
+
+ gitlab_address.instance_variable_set(:@initialized, initialized)
+ gitlab_address.define_gitlab_address_attribute!(address)
+ end
+
+ context "with attribute not initialized" do
+ let(:initialized) { nil }
+
+ it "initializes gitlab address attribute", :aggregate_failures do
+ expect(QA::Runtime::Scenario).to have_received(:define).with(:gitlab_address, address)
+ expect(QA::Runtime::Scenario).to have_received(:define).with(:about_address, "http://about.example.com")
+ end
+ end
+
+ context "with attribute already initialized" do
+ let(:initialized) { true }
+
+ it "skips setting gitlab address attribute" do
+ expect(QA::Runtime::Scenario).not_to have_received(:define)
+ end
+ end
+ end
+
+ describe ".address_with_port" do
+ context "when fetching address" do
+ let(:address) { gitlab_address.address_with_port("http://example.com/relative") }
+
+ it { expect(address).to eq("http://example.com:80/relative") }
+ end
+ end
+
+ describe ".host_with_port" do
+ context "when fetching host with default port" do
+ let(:host) { gitlab_address.host_with_port("http://example.com/relative") }
+
+ it { expect(host).to eq("example.com:80/relative") }
+ end
+
+ context "when fetching host with default port ommitted" do
+ let(:host) { gitlab_address.host_with_port("http://example.com/relative", with_default_port: false) }
+
+ it { expect(host).to eq("example.com/relative") }
+ end
+
+ context "when fetching host for address with custom port" do
+ let(:host) { gitlab_address.host_with_port("http://example.com:3322/relative", with_default_port: false) }
+
+ it { expect(host).to eq("example.com:3322/relative") }
+ end
+ end
+end
diff --git a/qa/spec/support/helpers/masker_spec.rb b/qa/spec/support/helpers/masker_spec.rb
new file mode 100644
index 00000000000..3d89f152891
--- /dev/null
+++ b/qa/spec/support/helpers/masker_spec.rb
@@ -0,0 +1,169 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe QA::Support::Helpers::Masker do
+ let(:secrets) { [:secret_content, 'secret'] }
+ let(:content) do
+ {
+ numeric_content: 1,
+ secret_content: 'a-private-token',
+ public_content: 'gitlab',
+ array_content: ['secret', :foo],
+ private: 'hide me',
+ hash_content: {
+ secret: 'a-private-key',
+ public: 'gitlab',
+ array: ['secret', :bar],
+ hash: { foo: 'secret' }
+ }
+ }
+ end
+
+ subject { described_class.new(by_key: secrets).mask(content) }
+
+ shared_examples 'masks secrets' do
+ it 'masks secrets' do
+ expect(subject).to match(a_hash_including(expected))
+ end
+ end
+
+ describe '.mask' do
+ it 'instantiates an object and calls the mask instance method' do
+ instance = instance_double('QA::Support::Helpers::Masker')
+
+ expect(described_class).to receive(:new)
+ .with(by_key: secrets, by_value: nil, mask: nil)
+ .and_return(instance)
+ expect(instance).to receive(:mask).with(content)
+
+ described_class.mask(content, by_key: secrets, by_value: nil, mask: nil)
+ end
+ end
+
+ describe '#initialize' do
+ it 'requires by_key or by_key' do
+ expect { described_class.new }.to raise_error(ArgumentError, /Please specify `by_key` or `by_value`/)
+ end
+ end
+
+ describe '#mask' do
+ context 'when content is blank' do
+ let(:content) { [] }
+
+ it 'returns content' do
+ expect(subject).to match([])
+ end
+ end
+
+ context 'when masking by key' do
+ subject { described_class.new(by_key: secrets).mask(content) }
+
+ let(:secrets) { [:secret_content, 'secret'] }
+
+ it 'masks secrets' do
+ expect(subject).to match(a_hash_including({
+ secret_content: '****',
+ hash_content: {
+ secret: '****',
+ public: 'gitlab',
+ array: ['secret', :bar],
+ hash: { foo: 'secret' }
+ }
+ }))
+ end
+
+ it 'does not mask by value' do
+ expect(subject).to match(a_hash_including({
+ array_content: ['secret', :foo],
+ hash_content: {
+ secret: '****',
+ public: 'gitlab',
+ array: ['secret', :bar],
+ hash: { foo: 'secret' }
+ }
+ }))
+ end
+
+ context 'with values that are not strings' do
+ let(:secrets) { [:numeric_content] }
+ let(:expected) { { numeric_content: '****' } }
+
+ include_examples 'masks secrets'
+ end
+
+ context 'when by_key is not an array' do
+ let(:secrets) { :secret_content }
+ let(:expected) { { secret_content: '****' } }
+
+ include_examples 'masks secrets'
+ end
+ end
+
+ context 'when masking by value' do
+ shared_examples 'does not mask' do
+ it 'does not mask' do
+ expect(subject).to eq(content)
+ end
+ end
+
+ subject { described_class.new(by_value: secrets).mask(content) }
+
+ let(:secrets) { [:private, 'secret'] }
+
+ it 'masks secrets' do
+ expect(subject).to match(a_hash_including({
+ secret_content: 'a-****-token',
+ array_content: ['****', :foo],
+ private: 'hide me',
+ hash_content: {
+ secret: 'a-****-key',
+ public: 'gitlab',
+ array: ['****', :bar],
+ hash: { foo: '****' }
+ }
+ }))
+ end
+
+ it 'does not mask by key' do
+ expect(subject).to match(a_hash_including(private: 'hide me'))
+ expect(subject.fetch(:hash_content)).to match(a_hash_including(secret: 'a-****-key'))
+ end
+
+ context 'when content is an Array' do
+ let(:content) { %w[secret not-secret] }
+
+ it 'masks secrets' do
+ expect(subject).to match_array(%w[**** not-****])
+ end
+ end
+
+ context 'when content is a String' do
+ let(:content) { 'secret' }
+ let(:expected) { '****' }
+
+ it 'masks secret values' do
+ expect(subject).to eq(expected)
+ end
+ end
+
+ context 'when content is an Integer' do
+ let(:content) { 1 }
+
+ include_examples 'does not mask'
+ end
+
+ context 'when content is a Float' do
+ let(:content) { 1.0 }
+
+ include_examples 'does not mask'
+ end
+
+ context 'when content is a Boolean' do
+ let(:content) { false }
+
+ include_examples 'does not mask'
+ end
+ end
+ end
+ end
+end