summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-11-17 11:33:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-17 11:33:21 +0000
commit7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0 (patch)
tree5bdc2229f5198d516781f8d24eace62fc7e589e9 /qa
parent185b095e93520f96e9cfc31d9c3e69b498cdab7c (diff)
downloadgitlab-ce-7021455bd1ed7b125c55eb1b33c5a01f2bc55ee0.tar.gz
Add latest changes from gitlab-org/gitlab@15-6-stable-eev15.6.0-rc42
Diffstat (limited to 'qa')
-rw-r--r--qa/Dockerfile5
-rw-r--r--qa/Gemfile31
-rw-r--r--qa/Gemfile.lock86
-rw-r--r--qa/lib/gitlab/page/group/settings/usage_quotas.rb5
-rw-r--r--qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb (renamed from qa/lib/gitlab/page/group/settings/usage_quota.stub.rb)302
-rw-r--r--qa/qa/fixtures/package_managers/helm/helm_install_package.yaml.erb3
-rw-r--r--qa/qa/fixtures/package_managers/helm/helm_upload_package.yaml.erb3
-rw-r--r--qa/qa/flow/sign_up.rb4
-rw-r--r--qa/qa/git/repository.rb5
-rw-r--r--qa/qa/mobile/page/base.rb16
-rw-r--r--qa/qa/page/admin/overview/users/index.rb4
-rw-r--r--qa/qa/page/base.rb71
-rw-r--r--qa/qa/page/component/access_tokens.rb18
-rw-r--r--qa/qa/page/component/delete_modal.rb35
-rw-r--r--qa/qa/page/component/groups_filter.rb23
-rw-r--r--qa/qa/page/component/issuable/sidebar.rb74
-rw-r--r--qa/qa/page/component/lazy_loader.rb4
-rw-r--r--qa/qa/page/component/legacy_clone_panel.rb2
-rw-r--r--qa/qa/page/component/namespace_select.rb9
-rw-r--r--qa/qa/page/component/users_select.rb14
-rw-r--r--qa/qa/page/component/wiki.rb2
-rw-r--r--qa/qa/page/file/edit.rb4
-rw-r--r--qa/qa/page/file/form.rb4
-rw-r--r--qa/qa/page/file/shared/editor.rb4
-rw-r--r--qa/qa/page/group/members.rb1
-rw-r--r--qa/qa/page/group/new.rb2
-rw-r--r--qa/qa/page/issuable/new.rb9
-rw-r--r--qa/qa/page/label/index.rb2
-rw-r--r--qa/qa/page/main/menu.rb14
-rw-r--r--qa/qa/page/profile/two_factor_auth.rb7
-rw-r--r--qa/qa/page/project/branches/show.rb38
-rw-r--r--qa/qa/page/project/import/github.rb9
-rw-r--r--qa/qa/page/project/new.rb2
-rw-r--r--qa/qa/page/project/pipeline/show.rb10
-rw-r--r--qa/qa/page/project/pipeline_editor/show.rb10
-rw-r--r--qa/qa/page/project/settings/advanced.rb44
-rw-r--r--qa/qa/page/project/settings/ci_variables.rb7
-rw-r--r--qa/qa/page/project/settings/default_branch.rb6
-rw-r--r--qa/qa/page/project/settings/mirroring_repositories.rb47
-rw-r--r--qa/qa/page/project/settings/protected_branches.rb6
-rw-r--r--qa/qa/page/project/settings/repository.rb2
-rw-r--r--qa/qa/page/project/show.rb14
-rw-r--r--qa/qa/page/project/sub_menus/ci_cd.rb2
-rw-r--r--qa/qa/page/project/sub_menus/issues.rb2
-rw-r--r--qa/qa/resource/approval_configuration.rb55
-rw-r--r--qa/qa/resource/base.rb16
-rw-r--r--qa/qa/resource/group.rb10
-rw-r--r--qa/qa/resource/members.rb7
-rw-r--r--qa/qa/resource/merge_request.rb30
-rw-r--r--qa/qa/resource/project.rb11
-rw-r--r--qa/qa/resource/project_imported_from_github.rb5
-rw-r--r--qa/qa/resource/sandbox.rb4
-rw-r--r--qa/qa/resource/user.rb15
-rw-r--r--qa/qa/runtime/allure_report.rb9
-rw-r--r--qa/qa/runtime/browser.rb2
-rw-r--r--qa/qa/runtime/env.rb6
-rw-r--r--qa/qa/runtime/key/ed25519.rb4
-rw-r--r--qa/qa/scenario/bootable.rb5
-rw-r--r--qa/qa/scenario/test/instance/gitlab_pages.rb13
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb8
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb2
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/group_access_token_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb312
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb15
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb79
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/project_access_token_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb2
-rw-r--r--qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_labels_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_mwps_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_remove_source_branch_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_target_branch_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/merge_request/push_options_title_description_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb1
-rw-r--r--qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb2
-rw-r--r--qa/qa/specs/features/api/4_verify/api_variable_inheritance_with_forward_pipeline_variables_spec.rb2
-rw-r--r--qa/qa/specs/features/api/4_verify/cancel_pipeline_when_block_user_spec.rb2
-rw-r--r--qa/qa/specs/features/api/4_verify/file_variable_spec.rb70
-rw-r--r--qa/qa/specs/features/api/4_verify/remove_runner_spec.rb2
-rw-r--r--qa/qa/specs/features/api/5_package/container_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/api/8_monitor/metrics_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/14_analytics/performance_bar_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/14_analytics/service_ping_default_enabled_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/14_analytics/service_ping_disabled_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/group_access_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb114
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/impersonation_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb18
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb2
-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/create_issue_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb38
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_a_merge_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_from_push_notification_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/reverting_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb2
-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/pages/new_static_page_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/source_editor/source_editor_toolbar_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb86
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/pipeline_with_protected_variable_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb71
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb148
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_multiple_files_from_a_project_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/merge_mr_when_pipline_is_blocked_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/parent_child_pipelines_independent_relationship_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pass_dotenv_variables_to_downstream_via_bridge_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb21
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_with_manual_jobs_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_child_pipeline_with_manual_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/trigger_matrix_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/dependency_proxy/dependency_proxy_spec.rb2
-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.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/generic_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb14
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/rubygems_registry_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb4
-rw-r--r--qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb46
-rw-r--r--qa/qa/specs/features/shared_contexts/import/gitlab_project_migration_common.rb (renamed from qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb)0
-rw-r--r--qa/qa/specs/helpers/context_selector.rb1
-rw-r--r--qa/qa/specs/runner.rb2
-rw-r--r--qa/qa/specs/spec_helper.rb10
-rw-r--r--qa/qa/support/fips.rb2
-rw-r--r--qa/qa/support/formatters/allure_metadata_formatter.rb16
-rw-r--r--qa/qa/support/formatters/context_formatter.rb1
-rw-r--r--qa/qa/support/formatters/test_metrics_formatter.rb (renamed from qa/qa/support/formatters/test_stats_formatter.rb)97
-rw-r--r--qa/qa/support/influxdb_tools.rb4
-rw-r--r--qa/qa/support/loglinking.rb28
-rw-r--r--qa/qa/support/page/logging.rb15
-rw-r--r--qa/qa/tools/ci/qa_changes.rb2
-rw-r--r--qa/qa/tools/ci/test_metrics.rb52
-rw-r--r--qa/qa/tools/delete_subgroups.rb137
-rw-r--r--qa/spec/resource/api_fabricator_spec.rb4
-rw-r--r--qa/spec/resource/base_spec.rb36
-rw-r--r--qa/spec/resource/user_spec.rb27
-rw-r--r--qa/spec/specs/runner_spec.rb2
-rw-r--r--qa/spec/support/formatters/test_metrics_formatter_spec.rb (renamed from qa/spec/support/formatters/test_stats_formatter_spec.rb)50
-rw-r--r--qa/spec/support/loglinking_spec.rb62
-rw-r--r--qa/spec/support/repeater_spec.rb302
-rw-r--r--qa/spec/tools/ci/qa_changes_spec.rb8
-rw-r--r--qa/spec/tools/ci/test_metrics_spec.rb54
-rw-r--r--qa/spec/tools/test_resources_data_processor_spec.rb2
-rw-r--r--qa/tasks/ci.rake37
-rw-r--r--qa/tasks/knapsack.rake20
253 files changed, 2268 insertions, 1325 deletions
diff --git a/qa/Dockerfile b/qa/Dockerfile
index 341732ab56f..7f236a25288 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -1,8 +1,9 @@
ARG DOCKER_VERSION=20.10.14
-ARG CHROME_VERSION=103
+ARG CHROME_VERSION=106
ARG QA_BUILD_TARGET=qa
+ARG RUBY_VERSION=2.7
-FROM registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-2.7:bundler-2.3-git-2.33-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23 AS qa
+FROM registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23 AS qa
LABEL maintainer="GitLab Quality Department <quality@gitlab.com>"
ENV DEBIAN_FRONTEND="noninteractive"
diff --git a/qa/Gemfile b/qa/Gemfile
index 12e5d66fc6b..b84a22883d1 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,31 +2,30 @@
source 'https://rubygems.org'
-gem 'gitlab-qa', '~> 8', '>= 8.8.0', require: 'gitlab/qa'
+gem 'gitlab-qa', '~> 8', '>= 8.11.0', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
-gem 'allure-rspec', '~> 2.18.0'
-gem 'capybara', '~> 3.37.1'
+gem 'allure-rspec', '~> 2.19.0'
+gem 'capybara', '~> 3.38.0'
gem 'capybara-screenshot', '~> 1.0.26'
-gem 'rake', '~> 13'
-gem 'rspec', '~> 3.11'
-gem 'selenium-webdriver', '~> 4.5'
+gem 'rake', '~> 13', '>= 13.0.6'
+gem 'rspec', '~> 3.12'
+gem 'selenium-webdriver', '~> 4.6', '>= 4.6.1'
gem 'airborne', '~> 0.3.7', require: false # airborne is messing with rspec sandboxed mode so not requiring by default
gem 'rest-client', '~> 2.1.0'
-gem 'rspec-retry', '~> 0.6.1', require: 'rspec/retry'
+gem 'rspec-retry', '~> 0.6.2', require: 'rspec/retry'
gem 'rspec_junit_formatter', '~> 0.6.0'
-gem 'faker', '~> 2.23'
+gem 'faker', '~> 3.0'
gem 'knapsack', '~> 4.0'
-gem 'parallel_tests', '~> 3.13'
-gem 'rotp', '~> 6.2.0'
-gem 'timecop', '~> 0.9.5'
-gem 'parallel', '~> 1.19'
-gem 'rainbow', '~> 3.0.0'
+gem 'parallel_tests', '~> 4.0'
+gem 'rotp', '~> 6.2.1'
+gem 'parallel', '~> 1.22', '>= 1.22.1'
+gem 'rainbow', '~> 3.1.1'
gem 'rspec-parameterized', '~> 0.5.2'
-gem 'octokit', '~> 5.6.1'
+gem 'octokit', '~> 6.0.0'
gem "faraday-retry", "~> 2.0"
gem 'webdrivers', '~> 5.2'
gem 'zeitwerk', '~> 2.4'
-gem 'influxdb-client', '~> 1.17'
+gem 'influxdb-client', '~> 2.8'
gem 'terminal-table', '~> 3.0.2', require: false
gem 'slack-notifier', '~> 2.4', require: false
gem 'fog-google', '~> 1.19', require: false
@@ -36,7 +35,7 @@ gem "warning", "~> 1.3"
gem 'confiner', '~> 0.3'
gem 'chemlab', '~> 0.10'
-gem 'chemlab-library-www-gitlab-com', '~> 0.1'
+gem 'chemlab-library-www-gitlab-com', '~> 0.1', '>= 0.1.1'
# dependencies for jenkins client
gem 'nokogiri', '~> 1.13', '>= 1.13.9'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 23f82f553f1..3ccc5fe9be3 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -15,10 +15,10 @@ GEM
rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8)
- allure-rspec (2.18.0)
- allure-ruby-commons (= 2.18.0)
+ allure-rspec (2.19.0)
+ allure-ruby-commons (= 2.19.0)
rspec-core (>= 3.8, < 4)
- allure-ruby-commons (2.18.0)
+ allure-ruby-commons (2.19.0)
mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4)
require_all (>= 2, < 4)
@@ -27,7 +27,7 @@ GEM
binding_ninja (0.2.3)
builder (3.2.4)
byebug (11.1.3)
- capybara (3.37.1)
+ capybara (3.38.0)
addressable
matrix
mini_mime (>= 0.1.3)
@@ -61,7 +61,7 @@ GEM
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
excon (0.92.4)
- faker (2.23.0)
+ faker (3.0.0)
i18n (>= 1.8.11, < 2)
faraday (2.5.2)
faraday-net_http (>= 2.0, < 3.1)
@@ -100,14 +100,13 @@ GEM
gitlab (4.18.0)
httparty (~> 0.18)
terminal-table (>= 1.5.1)
- gitlab-qa (8.8.0)
+ gitlab-qa (8.11.0)
activesupport (~> 6.1)
gitlab (~> 4.18.0)
http (~> 5.0)
nokogiri (~> 1.10)
rainbow (>= 3, < 4)
table_print (= 1.5.7)
- toxiproxy (~> 2.0.2)
zeitwerk (>= 2, < 3)
google-apis-compute_v1 (0.51.0)
google-apis-core (>= 0.7.2, < 2.a)
@@ -156,7 +155,7 @@ GEM
httpclient (2.8.3)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
- influxdb-client (1.17.0)
+ influxdb-client (2.8.0)
jwt (2.5.0)
knapsack (4.0.0)
rake
@@ -182,13 +181,13 @@ GEM
nokogiri (1.13.9)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
- octokit (5.6.1)
+ octokit (6.0.0)
faraday (>= 1, < 3)
sawyer (~> 0.9)
- oj (3.13.21)
+ oj (3.13.23)
os (1.1.4)
- parallel (1.19.2)
- parallel_tests (3.13.0)
+ parallel (1.22.1)
+ parallel_tests (4.0.0)
parallel
parser (3.1.2.1)
ast (~> 2.4.1)
@@ -207,7 +206,7 @@ GEM
rack (2.2.3.1)
rack-test (1.1.0)
rack (>= 1.0, < 3)
- rainbow (3.0.0)
+ rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.1.1)
representable (3.2.0)
@@ -222,19 +221,19 @@ GEM
netrc (~> 0.8)
retriable (3.1.2)
rexml (3.2.5)
- rotp (6.2.0)
- rspec (3.11.0)
- rspec-core (~> 3.11.0)
- rspec-expectations (~> 3.11.0)
- rspec-mocks (~> 3.11.0)
- rspec-core (3.11.0)
- rspec-support (~> 3.11.0)
- rspec-expectations (3.11.1)
+ rotp (6.2.1)
+ rspec (3.12.0)
+ rspec-core (~> 3.12.0)
+ rspec-expectations (~> 3.12.0)
+ rspec-mocks (~> 3.12.0)
+ rspec-core (3.12.0)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.11.0)
- rspec-mocks (3.11.1)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.11.0)
+ rspec-support (~> 3.12.0)
rspec-parameterized (0.5.2)
binding_ninja (>= 0.2.3)
parser
@@ -243,7 +242,7 @@ GEM
unparser
rspec-retry (0.6.2)
rspec-core (> 3.3)
- rspec-support (3.11.1)
+ rspec-support (3.12.0)
rspec_junit_formatter (0.6.0)
rspec-core (>= 2, < 4, != 2.12.0)
ruby-debug-ide (0.7.3)
@@ -253,7 +252,7 @@ GEM
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
- selenium-webdriver (4.5.0)
+ selenium-webdriver (4.6.1)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
@@ -268,8 +267,6 @@ GEM
table_print (1.5.7)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
- timecop (0.9.5)
- toxiproxy (2.0.2)
trailblazer-option (0.1.2)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
@@ -303,41 +300,40 @@ PLATFORMS
DEPENDENCIES
activesupport (~> 6.1.4.7)
airborne (~> 0.3.7)
- allure-rspec (~> 2.18.0)
- capybara (~> 3.37.1)
+ allure-rspec (~> 2.19.0)
+ capybara (~> 3.38.0)
capybara-screenshot (~> 1.0.26)
chemlab (~> 0.10)
- chemlab-library-www-gitlab-com (~> 0.1)
+ chemlab-library-www-gitlab-com (~> 0.1, >= 0.1.1)
confiner (~> 0.3)
deprecation_toolkit (~> 2.0.0)
- faker (~> 2.23)
+ faker (~> 3.0)
faraday-retry (~> 2.0)
fog-core (= 2.1.0)
fog-google (~> 1.19)
- gitlab-qa (~> 8, >= 8.8.0)
- influxdb-client (~> 1.17)
+ gitlab-qa (~> 8, >= 8.11.0)
+ influxdb-client (~> 2.8)
knapsack (~> 4.0)
nokogiri (~> 1.13, >= 1.13.9)
- octokit (~> 5.6.1)
- parallel (~> 1.19)
- parallel_tests (~> 3.13)
+ octokit (~> 6.0.0)
+ parallel (~> 1.22, >= 1.22.1)
+ parallel_tests (~> 4.0)
pry-byebug (~> 3.10.1)
- rainbow (~> 3.0.0)
- rake (~> 13)
+ rainbow (~> 3.1.1)
+ rake (~> 13, >= 13.0.6)
rest-client (~> 2.1.0)
- rotp (~> 6.2.0)
- rspec (~> 3.11)
+ rotp (~> 6.2.1)
+ rspec (~> 3.12)
rspec-parameterized (~> 0.5.2)
- rspec-retry (~> 0.6.1)
+ rspec-retry (~> 0.6.2)
rspec_junit_formatter (~> 0.6.0)
ruby-debug-ide (~> 0.7.3)
- selenium-webdriver (~> 4.5)
+ selenium-webdriver (~> 4.6, >= 4.6.1)
slack-notifier (~> 2.4)
terminal-table (~> 3.0.2)
- timecop (~> 0.9.5)
warning (~> 1.3)
webdrivers (~> 5.2)
zeitwerk (~> 2.4)
BUNDLED WITH
- 2.3.24
+ 2.3.25
diff --git a/qa/lib/gitlab/page/group/settings/usage_quotas.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.rb
index a1ab345bf1e..8540bce3da8 100644
--- a/qa/lib/gitlab/page/group/settings/usage_quotas.rb
+++ b/qa/lib/gitlab/page/group/settings/usage_quotas.rb
@@ -7,6 +7,11 @@ module Gitlab
class UsageQuotas < Chemlab::Page
# Seats section
link :seats_tab
+ div :seats_in_use
+ p :seats_used
+ p :seats_owed
+ table :subscription_users
+ button :remove_user
# Pipelines section
link :pipelines_tab
diff --git a/qa/lib/gitlab/page/group/settings/usage_quota.stub.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb
index 2a5d9a6bb5e..6c38625bb3b 100644
--- a/qa/lib/gitlab/page/group/settings/usage_quota.stub.rb
+++ b/qa/lib/gitlab/page/group/settings/usage_quotas.stub.rb
@@ -4,7 +4,7 @@ module Gitlab
module Page
module Group
module Settings
- module UsageQuota
+ module UsageQuotas
# @note Defined as +link :seats_tab+
# Clicks +seats_tab+
def seats_tab
@@ -12,8 +12,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.seats_tab_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.seats_tab_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
def seats_tab_element
@@ -21,14 +21,134 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_seats_tab
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_seats_tab
# end
# @return [Boolean] true if the +seats_tab+ element is present on the page
def seats_tab?
# This is a stub, used for indexing. The method is dynamically generated.
end
+ # @note Defined as +div :seats_in_use+
+ # @return [String] The text content or value of +seats_in_use+
+ def seats_in_use
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.seats_in_use_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def seats_in_use_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_seats_in_use
+ # end
+ # @return [Boolean] true if the +seats_in_use+ element is present on the page
+ def seats_in_use?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +p :seats_used+
+ # @return [String] The text content or value of +seats_used+
+ def seats_used
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.seats_used_element).to exist
+ # end
+ # @return [Watir::P] The raw +P+ element
+ def seats_used_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_seats_used
+ # end
+ # @return [Boolean] true if the +seats_used+ element is present on the page
+ def seats_used?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +p :seats_owed+
+ # @return [String] The text content or value of +seats_owed+
+ def seats_owed
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.seats_owed_element).to exist
+ # end
+ # @return [Watir::P] The raw +P+ element
+ def seats_owed_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_seats_owed
+ # end
+ # @return [Boolean] true if the +seats_owed+ element is present on the page
+ def seats_owed?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +table :subscription_users+
+ # @return [String] The text content or value of +subscription_users+
+ def subscription_users
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.subscription_users_element).to exist
+ # end
+ # @return [Watir::Table] The raw +Table+ element
+ def subscription_users_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_subscription_users
+ # end
+ # @return [Boolean] true if the +subscription_users+ element is present on the page
+ def subscription_users?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +button :remove_user+
+ # Clicks +remove_user+
+ def remove_user
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.remove_user_element).to exist
+ # end
+ # @return [Watir::Button] The raw +Button+ element
+ def remove_user_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_remove_user
+ # end
+ # @return [Boolean] true if the +remove_user+ element is present on the page
+ def remove_user?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
# @note Defined as +link :pipelines_tab+
# Clicks +pipelines_tab+
def pipelines_tab
@@ -36,8 +156,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.pipelines_tab_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.pipelines_tab_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
def pipelines_tab_element
@@ -45,8 +165,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_pipelines_tab
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_pipelines_tab
# end
# @return [Boolean] true if the +pipelines_tab+ element is present on the page
def pipelines_tab?
@@ -60,8 +180,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.buy_ci_minutes_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.buy_ci_minutes_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
def buy_ci_minutes_element
@@ -69,8 +189,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_buy_ci_minutes
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_buy_ci_minutes
# end
# @return [Boolean] true if the +buy_ci_minutes+ element is present on the page
def buy_ci_minutes?
@@ -84,8 +204,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.plan_ci_minutes_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.plan_ci_minutes_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def plan_ci_minutes_element
@@ -93,8 +213,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_plan_ci_minutes
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_plan_ci_minutes
# end
# @return [Boolean] true if the +plan_ci_minutes+ element is present on the page
def plan_ci_minutes?
@@ -108,8 +228,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.additional_ci_minutes_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.additional_ci_minutes_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def additional_ci_minutes_element
@@ -117,8 +237,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_additional_ci_minutes
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_additional_ci_minutes
# end
# @return [Boolean] true if the +additional_ci_minutes+ element is present on the page
def additional_ci_minutes?
@@ -132,8 +252,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.ci_purchase_successful_alert_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.ci_purchase_successful_alert_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def ci_purchase_successful_alert_element
@@ -141,8 +261,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_ci_purchase_successful_alert
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_ci_purchase_successful_alert
# end
# @return [Boolean] true if the +ci_purchase_successful_alert+ element is present on the page
def ci_purchase_successful_alert?
@@ -156,8 +276,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.storage_tab_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.storage_tab_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
def storage_tab_element
@@ -165,35 +285,35 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_storage_tab
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_storage_tab
# end
# @return [Boolean] true if the +storage_tab+ element is present on the page
def storage_tab?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +link :buy_storage+
- # Clicks +buy_storage+
- def buy_storage
+ # @note Defined as +link :purchase_more_storage+
+ # Clicks +purchase_more_storage+
+ def purchase_more_storage
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.buy_storage_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.purchase_more_storage_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
- def buy_storage_element
+ def purchase_more_storage_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_buy_storage
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_purchase_more_storage
# end
- # @return [Boolean] true if the +buy_storage+ element is present on the page
- def buy_storage?
+ # @return [Boolean] true if the +purchase_more_storage+ element is present on the page
+ def purchase_more_storage?
# This is a stub, used for indexing. The method is dynamically generated.
end
@@ -204,8 +324,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.used_storage_message_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.used_storage_message_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def used_storage_message_element
@@ -213,8 +333,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_used_storage_message
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_used_storage_message
# end
# @return [Boolean] true if the +used_storage_message+ element is present on the page
def used_storage_message?
@@ -228,8 +348,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.group_usage_message_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.group_usage_message_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def group_usage_message_element
@@ -237,8 +357,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_group_usage_message
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_group_usage_message
# end
# @return [Boolean] true if the +group_usage_message+ element is present on the page
def group_usage_message?
@@ -252,8 +372,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.dependency_proxy_usage_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.dependency_proxy_usage_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def dependency_proxy_usage_element
@@ -261,8 +381,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_dependency_proxy_usage
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_dependency_proxy_usage
# end
# @return [Boolean] true if the +dependency_proxy_usage+ element is present on the page
def dependency_proxy_usage?
@@ -276,8 +396,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.dependency_proxy_size_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.dependency_proxy_size_element).to exist
# end
# @return [Watir::Span] The raw +Span+ element
def dependency_proxy_size_element
@@ -285,8 +405,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_dependency_proxy_size
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_dependency_proxy_size
# end
# @return [Boolean] true if the +dependency_proxy_size+ element is present on the page
def dependency_proxy_size?
@@ -300,8 +420,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.container_registry_usage_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.container_registry_usage_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def container_registry_usage_element
@@ -309,8 +429,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_container_registry_usage
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_container_registry_usage
# end
# @return [Boolean] true if the +container_registry_usage+ element is present on the page
def container_registry_usage?
@@ -324,8 +444,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.project_storage_used_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.project_storage_used_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def project_storage_used_element
@@ -333,8 +453,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_project_storage_used
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_project_storage_used
# end
# @return [Boolean] true if the +project_storage_used+ element is present on the page
def project_storage_used?
@@ -348,8 +468,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.project_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.project_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def project_element
@@ -357,8 +477,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_project
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_project
# end
# @return [Boolean] true if the +project+ element is present on the page
def project?
@@ -372,8 +492,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.storage_type_legend_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.storage_type_legend_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def storage_type_legend_element
@@ -381,8 +501,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_storage_type_legend
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_storage_type_legend
# end
# @return [Boolean] true if the +storage_type_legend+ element is present on the page
def storage_type_legend?
@@ -396,8 +516,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.container_registry_size_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.container_registry_size_element).to exist
# end
# @return [Watir::Span] The raw +Span+ element
def container_registry_size_element
@@ -405,8 +525,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_container_registry_size
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_container_registry_size
# end
# @return [Boolean] true if the +container_registry_size+ element is present on the page
def container_registry_size?
@@ -420,8 +540,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.purchased_usage_total_free_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.purchased_usage_total_free_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def purchased_usage_total_free_element
@@ -429,8 +549,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_purchased_usage_total_free
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_purchased_usage_total_free
# end
# @return [Boolean] true if the +purchased_usage_total_free+ element is present on the page
def purchased_usage_total_free?
@@ -444,8 +564,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.purchased_usage_total_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.purchased_usage_total_element).to exist
# end
# @return [Watir::Span] The raw +Span+ element
def purchased_usage_total_element
@@ -453,8 +573,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_purchased_usage_total
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_purchased_usage_total
# end
# @return [Boolean] true if the +purchased_usage_total+ element is present on the page
def purchased_usage_total?
@@ -468,8 +588,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.storage_purchase_successful_alert_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.storage_purchase_successful_alert_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
def storage_purchase_successful_alert_element
@@ -477,8 +597,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_storage_purchase_successful_alert
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_storage_purchase_successful_alert
# end
# @return [Boolean] true if the +storage_purchase_successful_alert+ element is present on the page
def storage_purchase_successful_alert?
@@ -492,8 +612,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.storage_available_alert_element).to exist
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas.storage_available_alert_element).to exist
# end
# @return [Watir::H2] The raw +H2+ element
def storage_available_alert_element
@@ -501,8 +621,8 @@ module Gitlab
end
# @example
- # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_storage_available_alert
+ # Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
+ # expect(usage_quotas).to be_storage_available_alert
# end
# @return [Boolean] true if the +storage_available_alert+ element is present on the page
def storage_available_alert?
diff --git a/qa/qa/fixtures/package_managers/helm/helm_install_package.yaml.erb b/qa/qa/fixtures/package_managers/helm/helm_install_package.yaml.erb
index 786b0592153..590120ce7b2 100644
--- a/qa/qa/fixtures/package_managers/helm/helm_install_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/helm/helm_install_package.yaml.erb
@@ -1,7 +1,6 @@
pull:
- image: alpine:3
+ image: dtzar/helm-kubectl:latest
script:
- - apk add helm --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing
- helm repo add --username <%= username %> --password <%= access_token %> gitlab_qa ${CI_API_V4_URL}/projects/<%= package_project.id %>/packages/helm/stable
- helm repo update
- helm pull gitlab_qa/<%= package_name %>
diff --git a/qa/qa/fixtures/package_managers/helm/helm_upload_package.yaml.erb b/qa/qa/fixtures/package_managers/helm/helm_upload_package.yaml.erb
index b3e907b50f4..b1c275cd96a 100644
--- a/qa/qa/fixtures/package_managers/helm/helm_upload_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/helm/helm_upload_package.yaml.erb
@@ -1,7 +1,6 @@
deploy:
- image: alpine:3
+ image: dtzar/helm-kubectl:latest
script:
- - apk add helm --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing
- apk add curl
- helm create <%= package_name %>
- cp ./Chart.yaml <%= package_name %>
diff --git a/qa/qa/flow/sign_up.rb b/qa/qa/flow/sign_up.rb
index 52c92293bad..abaab064a73 100644
--- a/qa/qa/flow/sign_up.rb
+++ b/qa/qa/flow/sign_up.rb
@@ -37,7 +37,9 @@ module QA
Page::Main::Menu.perform(&:not_signed_in?)
end
- raise "Failed user registration attempt. Registration was expected to #{user.expect_fabrication_success ? 'succeed' : 'fail'} but #{success ? 'succeeded' : 'failed'}." unless success
+ return if success
+
+ raise "Failed user registration attempt. Registration was expected to #{user.expect_fabrication_success ? 'succeed' : 'fail'} but #{success ? 'succeeded' : 'failed'}."
end
def disable_sign_ups
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index f132d7b7885..35c5262e767 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -305,11 +305,12 @@ module QA
prefix = "-o merge_request"
opts.each_with_object([]) do |(key, value), options|
- if value.is_a?(Array)
+ case value
+ when Array
value.each do |item|
options << "#{prefix}.#{key}=\"#{item}\""
end
- elsif value == true
+ when true
options << "#{prefix}.#{key}"
else
options << "#{prefix}.#{key}=\"#{value}\""
diff --git a/qa/qa/mobile/page/base.rb b/qa/qa/mobile/page/base.rb
new file mode 100644
index 00000000000..8bc7e5f25ab
--- /dev/null
+++ b/qa/qa/mobile/page/base.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module QA
+ module Mobile
+ module Page
+ module Base
+ prepend Support::Page::Logging
+
+ def fill_element(name, content)
+ # We need to bypass click_element_cooridinates as it does not work on mobile devices
+ find_element(name).set(content)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/admin/overview/users/index.rb b/qa/qa/page/admin/overview/users/index.rb
index 2ad45e4a0fa..f46ae30498c 100644
--- a/qa/qa/page/admin/overview/users/index.rb
+++ b/qa/qa/page/admin/overview/users/index.rb
@@ -28,6 +28,10 @@ module QA
click_link(username)
end
end
+
+ def has_username?(username)
+ has_element?(:user_row_content, text: username, wait: 1)
+ end
end
end
end
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 81c518bb4c6..f59b06b4e75 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -6,6 +6,7 @@ module QA
module Page
class Base
prepend Support::Page::Logging
+ prepend Mobile::Page::Base if QA::Runtime::Env.remote_mobile_device_name
include Capybara::DSL
include Scenario::Actable
@@ -39,7 +40,8 @@ module QA
def inspect
# For prettier failure messages
# Eg.: "expected QA::Page::File::Show not to have file "QA Test - File name"
- # Instead of "expected #<QA::Page::File::Show:0x000055c6511e07b8 @retry_later_backoff=60> not to have file "QA Test - File name"
+ # Instead of "expected #<QA::Page::File::Show:0x000055c6511e07b8 @retry_later_backoff=60>
+ # not to have file "QA Test - File name"
self.class.to_s
end
@@ -158,16 +160,17 @@ module QA
all(element_selector_css(name), **kwargs)
end
- def check_element(name, click_by_js = false, visibility = false)
- if find_element(name, visible: visibility).checked?
+ def check_element(name, click_by_js = false, **kwargs)
+ kwargs[:visible] = false unless kwargs.key?(:visible)
+ if find_element(name, **kwargs).checked?
QA::Runtime::Logger.debug("#{name} is already checked")
return
end
retry_until(sleep_interval: 1) do
- click_checkbox_or_radio(name, click_by_js, visibility)
- checked = find_element(name, visible: visibility).checked?
+ click_checkbox_or_radio(name, click_by_js, **kwargs)
+ checked = find_element(name, **kwargs).checked?
QA::Runtime::Logger.debug(checked ? "#{name} was checked" : "#{name} was not checked")
@@ -175,16 +178,17 @@ module QA
end
end
- def uncheck_element(name, click_by_js = false, visibility = false)
- unless find_element(name, visible: visibility).checked?
+ def uncheck_element(name, click_by_js = false, **kwargs)
+ kwargs[:visible] = false unless kwargs.key?(:visible)
+ unless find_element(name, **kwargs).checked?
QA::Runtime::Logger.debug("#{name} is already unchecked")
return
end
retry_until(sleep_interval: 1) do
- click_checkbox_or_radio(name, click_by_js, visibility)
- unchecked = !find_element(name, visible: visibility).checked?
+ click_checkbox_or_radio(name, click_by_js, **kwargs)
+ unchecked = !find_element(name, **kwargs).checked?
QA::Runtime::Logger.debug(unchecked ? "#{name} was unchecked" : "#{name} was not unchecked")
@@ -193,16 +197,17 @@ module QA
end
# Method for selecting radios
- def choose_element(name, click_by_js = false, visibility = false)
- if find_element(name, visible: visibility).checked?
+ def choose_element(name, click_by_js = false, **kwargs)
+ kwargs[:visible] = false unless kwargs.key?(:visible)
+ if find_element(name, **kwargs).checked?
QA::Runtime::Logger.debug("#{name} is already selected")
return
end
retry_until(sleep_interval: 1) do
- click_checkbox_or_radio(name, click_by_js, visibility)
- selected = find_element(name, visible: visibility).checked?
+ click_checkbox_or_radio(name, click_by_js, **kwargs)
+ selected = find_element(name, **kwargs).checked?
QA::Runtime::Logger.debug(selected ? "#{name} was selected" : "#{name} was not selected")
@@ -368,19 +373,15 @@ module QA
sleep 1
end
- def within_element(name, **kwargs)
+ def within_element(name, **kwargs, &block)
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) do
- yield
- end
+ page.within(element_selector_css(name, kwargs), text: text, &block)
end
- def within_element_by_index(name, index)
- page.within all_elements(name, minimum: index + 1)[index] do
- yield
- end
+ def within_element_by_index(name, index, &block)
+ page.within(all_elements(name, minimum: index + 1)[index], &block)
end
def scroll_to_element(name, *kwargs)
@@ -407,15 +408,14 @@ module QA
def wait_if_retry_later
return if @retry_later_backoff > QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME * 5
+ return unless has_css?('body', text: 'Retry later', wait: 0)
- if has_css?('body', text: 'Retry later', wait: 0)
- QA::Runtime::Logger.warn("`Retry later` error occurred. Sleeping for #{@retry_later_backoff} seconds...")
- sleep @retry_later_backoff
- refresh
- @retry_later_backoff += QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME
+ QA::Runtime::Logger.warn("`Retry later` error occurred. Sleeping for #{@retry_later_backoff} seconds...")
+ sleep @retry_later_backoff
+ refresh
+ @retry_later_backoff += QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME
- wait_if_retry_later
- end
+ wait_if_retry_later
end
def current_host
@@ -458,6 +458,10 @@ module QA
true
end
+ def click_by_javascript(element)
+ page.execute_script("arguments[0].click();", element)
+ end
+
class DSL
attr_reader :views
@@ -474,13 +478,18 @@ module QA
private
- def click_checkbox_or_radio(name, click_by_js, visibility)
- box = find_element(name, visible: visibility)
+ def click_checkbox_or_radio(name, click_by_js, **kwargs)
+ box = find_element(name, **kwargs)
# Some checkboxes and radio buttons are hidden by their labels and cannot be clicked directly
click_by_js ? page.execute_script("arguments[0].click();", box) : box.click
end
- def feature_flag_controlled_element(feature_flag, element_when_flag_enabled, element_when_flag_disabled, visibility = true)
+ def feature_flag_controlled_element(
+ feature_flag,
+ element_when_flag_enabled,
+ element_when_flag_disabled,
+ visibility = true
+ )
# Feature flags can change the UI elements shown, but we need admin access to get feature flag values, which
# prevents us running the tests on production. Instead we detect the UI element that should be shown when the
# feature flag is enabled and otherwise use the element that should be displayed when the feature flag is
diff --git a/qa/qa/page/component/access_tokens.rb b/qa/qa/page/component/access_tokens.rb
index 3c8a608cdc2..586f69b8a64 100644
--- a/qa/qa/page/component/access_tokens.rb
+++ b/qa/qa/page/component/access_tokens.rb
@@ -18,27 +18,24 @@ module QA
element :expiry_date_field
end
- base.view 'app/views/shared/access_tokens/_created_container.html.haml' do
- element :created_access_token_field
- end
-
base.view 'app/views/shared/access_tokens/_form.html.haml' do
element :access_token_name_field
element :create_token_button
end
- base.view 'app/views/shared/access_tokens/_table.html.haml' do
- element :revoke_button
- end
-
base.view 'app/views/shared/tokens/_scopes_form.html.haml' do
element :api_label, '#{scope}_label' # rubocop:disable QA/ElementWithPattern, Lint/InterpolationCheck
end
base.view 'app/assets/javascripts/access_tokens/components/new_access_token_app.vue' do
+ element :access_token_section
element :created_access_token_field
end
+ base.view 'app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue' do
+ element :toggle_visibility_button
+ end
+
base.view 'app/assets/javascripts/access_tokens/components/access_token_table_app.vue' do
element :revoke_button
end
@@ -57,7 +54,10 @@ module QA
end
def created_access_token
- find_element(:created_access_token_field, wait: 30).value
+ within_element(:access_token_section) do
+ click_element(:toggle_visibility_button, wait: 30)
+ find_element(:created_access_token_field).value
+ end
end
def fill_expiry_date(date)
diff --git a/qa/qa/page/component/delete_modal.rb b/qa/qa/page/component/delete_modal.rb
new file mode 100644
index 00000000000..18bb2b1bb1b
--- /dev/null
+++ b/qa/qa/page/component/delete_modal.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Component
+ module DeleteModal
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.view 'app/assets/javascripts/projects/components/shared/delete_button.vue' do
+ element :confirm_name_field
+ element :confirm_delete_button
+ end
+ end
+
+ def fill_confirmation_path(text)
+ fill_element(:confirm_name_field, text)
+ end
+
+ def wait_for_delete_button_enabled
+ wait_until(reload: false) do
+ !find_element(:confirm_delete_button).disabled?
+ end
+ end
+
+ def confirm_delete
+ wait_for_delete_button_enabled
+ click_element(:confirm_delete_button)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/component/groups_filter.rb b/qa/qa/page/component/groups_filter.rb
index 28b8ece918d..ec59d010718 100644
--- a/qa/qa/page/component/groups_filter.rb
+++ b/qa/qa/page/component/groups_filter.rb
@@ -16,6 +16,10 @@ module QA
base.view 'app/assets/javascripts/groups/components/groups.vue' do
element :groups_list_tree_container
end
+
+ base.view 'app/views/dashboard/_groups_head.html.haml' do
+ element :public_groups_tab
+ end
end
private
@@ -28,9 +32,24 @@ module QA
# groups_list_tree_container means we have the complete filtered list
# of groups
has_element?(:groups_list_tree_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
-
# If there are no groups we'll know immediately because we filtered the list
- return false if page.has_text?('No groups or projects matched your search', wait: 0)
+ if page.has_text?('No groups or projects matched your search',
+wait: 0) || page.has_text?('No groups matched your search', wait: 0)
+ return false unless has_element?(:public_groups_tab)
+
+ # Try for public groups
+ click_element(:public_groups_tab)
+ # Filter and submit to reload the page and only retrieve the filtered results
+ find_element(:groups_filter_field).set(name).send_keys(:return)
+
+ # Since we submitted after filtering, the presence of
+ # groups_list_tree_container means we have the complete filtered list
+ # of groups
+ has_element?(:groups_list_tree_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
+
+ return false if page.has_text?('No groups or projects matched your search',
+wait: 0) || page.has_text?('No groups matched your search', wait: 0)
+ end
# The name will be present as filter input so we check for a link, not text
page.has_link?(name, wait: 0)
diff --git a/qa/qa/page/component/issuable/sidebar.rb b/qa/qa/page/component/issuable/sidebar.rb
index 71a69576c06..fb2e7478684 100644
--- a/qa/qa/page/component/issuable/sidebar.rb
+++ b/qa/qa/page/component/issuable/sidebar.rb
@@ -86,6 +86,24 @@ module QA
end
end
+ def has_reviewer?(username)
+ wait_reviewers_block_finish_loading do
+ has_text?(username)
+ end
+ end
+
+ def has_no_reviewer?(username)
+ wait_reviewers_block_finish_loading do
+ has_no_text?(username)
+ end
+ end
+
+ def has_no_reviewers?
+ wait_reviewers_block_finish_loading do
+ has_text?('None')
+ end
+ end
+
def has_avatar_image_count?(count)
wait_assignees_block_finish_loading do
all_elements(:avatar_image, count: count)
@@ -133,6 +151,53 @@ module QA
click_element(:more_assignees_link)
end
+ def toggle_reviewers_edit
+ click_element(:reviewers_edit_button)
+ end
+
+ def suggested_reviewer_usernames
+ within_element(:reviewers_block_container) do
+ wait_for_requests
+
+ click_element(:reviewers_edit_button)
+ wait_for_requests
+
+ list = find_element(:dropdown_list_content)
+ suggested_reviewers = list.find_all('li[data-user-suggested="true"')
+ raise ElementNotFound, 'No suggested reviewers found' if suggested_reviewers.nil?
+
+ suggested_reviewers.map do |reviewer|
+ info = reviewer.text.split('@')
+ {
+ name: info[0].chomp,
+ username: info[1].chomp
+ }
+ end.compact
+ end
+ end
+
+ def unassign_reviewers
+ within_element(:reviewers_block_container) do
+ wait_for_requests
+
+ click_element(:reviewers_edit_button)
+ wait_for_requests
+ end
+
+ select_reviewer('Unassigned')
+ end
+
+ def select_reviewer(username)
+ within_element(:reviewers_block_container) do
+ within_element(:dropdown_list_content) do
+ click_on username
+ end
+
+ click_element(:reviewers_edit_button)
+ wait_for_requests
+ end
+ end
+
private
def wait_assignees_block_finish_loading
@@ -144,6 +209,15 @@ module QA
end
end
+ def wait_reviewers_block_finish_loading
+ within_element(:reviewers_block_container) do
+ wait_until(reload: false, max_duration: 10, sleep_interval: 1) do
+ finished_loading_block?
+ yield
+ end
+ end
+ end
+
def wait_labels_block_finish_loading
within_element(:labels_block) do
wait_until(reload: false, max_duration: 10, sleep_interval: 1) do
diff --git a/qa/qa/page/component/lazy_loader.rb b/qa/qa/page/component/lazy_loader.rb
index 2123431fc55..1b166efbbff 100644
--- a/qa/qa/page/component/lazy_loader.rb
+++ b/qa/qa/page/component/lazy_loader.rb
@@ -9,8 +9,8 @@ module QA
def self.included(base)
super
- base.view 'app/assets/javascripts/lazy_loader.js' do
- element :js_lazy_loaded
+ base.view 'app/views/layouts/_img_loader.html.haml' do
+ element :js_lazy_loaded_content
end
end
end
diff --git a/qa/qa/page/component/legacy_clone_panel.rb b/qa/qa/page/component/legacy_clone_panel.rb
index ee372a3f9aa..8c3c25f6e41 100644
--- a/qa/qa/page/component/legacy_clone_panel.rb
+++ b/qa/qa/page/component/legacy_clone_panel.rb
@@ -28,7 +28,7 @@ module QA
end
def repository_location
- Git::Location.new(find_element(:clone_url_content).text)
+ Git::Location.new(find_element(:clone_url_content).value)
end
private
diff --git a/qa/qa/page/component/namespace_select.rb b/qa/qa/page/component/namespace_select.rb
index 9b483162f1b..8fb0bb79ab3 100644
--- a/qa/qa/page/component/namespace_select.rb
+++ b/qa/qa/page/component/namespace_select.rb
@@ -9,7 +9,7 @@ module QA
def self.included(base)
super
- base.view "app/assets/javascripts/vue_shared/components/namespace_select/namespace_select_deprecated.vue" do
+ base.view "app/assets/javascripts/groups_projects/components/transfer_locations.vue" do
element :namespaces_list
element :namespaces_list_groups
element :namespaces_list_item
@@ -20,14 +20,15 @@ module QA
def select_namespace(item)
click_element :namespaces_list
- wait_for_requests
-
within_element(:namespaces_list) do
fill_element(:namespaces_list_search, item)
wait_for_requests
- find_element(:namespaces_list_item, text: item).click
+ # Click element by JS in case dropdown changes position mid-click
+ # Workaround for issue https://gitlab.com/gitlab-org/gitlab/-/issues/381376
+ namespace = find_element(:namespaces_list_item, text: item, visible: false)
+ click_by_javascript(namespace)
end
end
end
diff --git a/qa/qa/page/component/users_select.rb b/qa/qa/page/component/users_select.rb
deleted file mode 100644
index f88d6450a33..00000000000
--- a/qa/qa/page/component/users_select.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Component
- module UsersSelect
- def select_user(element, username)
- find("#{element_selector_css(element)} input").set(username)
- find('.ajax-users-dropdown .user-username', text: "@#{username}").click
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/component/wiki.rb b/qa/qa/page/component/wiki.rb
index ffd31f8d7b7..ed68052f997 100644
--- a/qa/qa/page/component/wiki.rb
+++ b/qa/qa/page/component/wiki.rb
@@ -38,7 +38,7 @@ module QA
# webdriver to miss the hit so we wait for the svg to load before
# clicking the button.
within_element(:svg_content) do
- has_element?(:js_lazy_loaded)
+ has_element?(:js_lazy_loaded_content)
end
click_element(:create_first_page_link)
diff --git a/qa/qa/page/file/edit.rb b/qa/qa/page/file/edit.rb
index d2b8c8260fd..b9b676ee3c4 100644
--- a/qa/qa/page/file/edit.rb
+++ b/qa/qa/page/file/edit.rb
@@ -12,10 +12,6 @@ module QA
element :editor_toolbar_button
end
- view 'app/views/projects/blob/_editor.html.haml' do
- element :source_editor_preview_container
- end
-
def has_markdown_preview?(component, content)
within_element(:source_editor_preview_container) do
has_css?(component, exact_text: content)
diff --git a/qa/qa/page/file/form.rb b/qa/qa/page/file/form.rb
index bb8934db498..2e0f8c59213 100644
--- a/qa/qa/page/file/form.rb
+++ b/qa/qa/page/file/form.rb
@@ -11,7 +11,7 @@ module QA
include Shared::Editor
view 'app/views/projects/blob/_editor.html.haml' do
- element :file_name, "text_field_tag 'file_name'" # rubocop:disable QA/ElementWithPattern
+ element :file_name_field
end
view 'app/views/projects/blob/_template_selectors.html.haml' do
@@ -23,7 +23,7 @@ module QA
end
def add_name(name)
- fill_in 'file_name', with: name
+ fill_element(:file_name_field, with: name)
end
def select_template(template_type, template)
diff --git a/qa/qa/page/file/shared/editor.rb b/qa/qa/page/file/shared/editor.rb
index dab02c1e34f..f392d52747e 100644
--- a/qa/qa/page/file/shared/editor.rb
+++ b/qa/qa/page/file/shared/editor.rb
@@ -11,7 +11,7 @@ module QA
super
base.view 'app/views/projects/blob/_editor.html.haml' do
- element :editor
+ element :source_editor_preview_container
end
end
@@ -30,7 +30,7 @@ module QA
private
def text_area
- within_element :editor do
+ within_element :source_editor_preview_container do
find('textarea', visible: false)
end
end
diff --git a/qa/qa/page/group/members.rb b/qa/qa/page/group/members.rb
index 58febaddfa0..39003eb03c1 100644
--- a/qa/qa/page/group/members.rb
+++ b/qa/qa/page/group/members.rb
@@ -5,7 +5,6 @@ module QA
module Group
class Members < Page::Base
include Page::Component::InviteMembersModal
- include Page::Component::UsersSelect
include Page::Component::MembersFilter
view 'app/assets/javascripts/members/components/modals/remove_member_modal.vue' do
diff --git a/qa/qa/page/group/new.rb b/qa/qa/page/group/new.rb
index 1f17b470ada..47fda787085 100644
--- a/qa/qa/page/group/new.rb
+++ b/qa/qa/page/group/new.rb
@@ -31,7 +31,7 @@ module QA
end
def create
- click_button 'Create group'
+ click_element(:create_group_button)
end
def create_subgroup
diff --git a/qa/qa/page/issuable/new.rb b/qa/qa/page/issuable/new.rb
index f3e6a84ef54..b74dc705888 100644
--- a/qa/qa/page/issuable/new.rb
+++ b/qa/qa/page/issuable/new.rb
@@ -12,9 +12,8 @@ module QA
element :issuable_form_description_field
end
- view 'app/views/shared/issuable/_milestone_dropdown.html.haml' do
+ view 'app/assets/javascripts/sidebar/components/milestone/milestone_dropdown.vue' do
element :issuable_milestone_dropdown
- element :issuable_milestone_dropdown_content
end
view 'app/views/shared/issuable/_label_dropdown.html.haml' do
@@ -38,9 +37,9 @@ module QA
end
def choose_milestone(milestone)
- click_element :issuable_milestone_dropdown
- within_element(:issuable_milestone_dropdown_content) do
- click_on milestone.title
+ within_element(:issuable_milestone_dropdown) do
+ click_button 'Select milestone'
+ click_button milestone.title
end
end
diff --git a/qa/qa/page/label/index.rb b/qa/qa/page/label/index.rb
index e19bc0838c9..70df2e4dc9e 100644
--- a/qa/qa/page/label/index.rb
+++ b/qa/qa/page/label/index.rb
@@ -23,7 +23,7 @@ module QA
# This can cause webdriver to miss the hit so we wait for the svg to load (implicitly with has_element?)
# before clicking the button.
within_element(:label_svg_content) do
- has_element?(:js_lazy_loaded)
+ has_element?(:js_lazy_loaded_content)
end
click_element :create_new_label_button
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index 2f618224a73..ecd71e7c2f4 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -64,12 +64,7 @@ module QA
def go_to_groups
within_groups_menu do
- # Remove if statement once :remove_extra_primary_submenu_options ff is enabled by default
- if has_element?(:menu_item_link, title: 'Your groups')
- click_element(:menu_item_link, title: 'Your groups')
- else
- click_element(:menu_item_link, title: 'View all groups')
- end
+ click_element(:menu_item_link, title: 'View all groups')
end
end
@@ -80,12 +75,7 @@ module QA
def go_to_projects
within_projects_menu do
- # Remove if statement once :remove_extra_primary_submenu_options ff is enabled by default
- if has_element?(:menu_item_link, title: 'Your projects')
- click_element(:menu_item_link, title: 'Your projects')
- else
- click_element(:menu_item_link, title: 'View all projects')
- end
+ click_element(:menu_item_link, title: 'View all projects')
end
end
diff --git a/qa/qa/page/profile/two_factor_auth.rb b/qa/qa/page/profile/two_factor_auth.rb
index 63593bf0482..16aa60262d8 100644
--- a/qa/qa/page/profile/two_factor_auth.rb
+++ b/qa/qa/page/profile/two_factor_auth.rb
@@ -23,7 +23,14 @@ module QA
end
def click_configure_it_later_button
+ # TO DO: Investigate why button does not appear sometimes:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/382698
+ return unless has_element?(:configure_it_later_button)
+
click_element :configure_it_later_button
+ wait_until(max_duration: 10, message: "Waiting for create a group page") do
+ has_text?("Welcome to GitLab") && has_text?("Create a group")
+ end
end
def otp_secret_content
diff --git a/qa/qa/page/project/branches/show.rb b/qa/qa/page/project/branches/show.rb
index 4bf8abb555b..7163bc7464d 100644
--- a/qa/qa/page/project/branches/show.rb
+++ b/qa/qa/page/project/branches/show.rb
@@ -5,8 +5,6 @@ module QA
module Project
module Branches
class Show < Page::Base
- include Page::Component::ConfirmModal
-
view 'app/assets/javascripts/branches/components/delete_branch_button.vue' do
element :delete_branch_button
end
@@ -16,22 +14,24 @@ module QA
end
view 'app/views/projects/branches/_branch.html.haml' do
- element :branch_name
+ element :badge_content
+ element :branch_container
+ element :branch_link
end
view 'app/views/projects/branches/_panel.html.haml' do
- element :all_branches
+ element :all_branches_container
end
- view 'app/views/projects/branches/index.html.haml' do
- element :delete_merged_branches
+ view 'app/assets/javascripts/branches/components/delete_merged_branches.vue' do
+ element :delete_merged_branches_button
+ element :delete_merged_branches_input
+ element :delete_merged_branches_confirmation_button
end
def delete_branch(branch_name)
- within_element(:all_branches) do
- within(".js-branch-#{branch_name}") do
- click_element(:delete_branch_button)
- end
+ within_element(:branch_container, name: branch_name) do
+ click_element(:delete_branch_button)
end
click_element(:delete_branch_confirmation_button)
@@ -41,23 +41,23 @@ module QA
def has_no_branch?(branch_name, reload: false)
wait_until(reload: reload) do
- within_element(:all_branches) do
- has_no_element?(:branch_name, text: branch_name)
+ within_element(:all_branches_container) do
+ has_no_element?(:branch_link, text: branch_name)
end
end
end
def has_branch_with_badge?(branch_name, badge)
- within_element(:all_branches) do
- within(".js-branch-#{branch_name} .badge") do
- has_text?(badge)
- end
+ within_element(:branch_container, name: branch_name) do
+ has_element?(:badge_content, text: badge)
end
end
- def delete_merged_branches
- click_element(:delete_merged_branches)
- click_confirmation_ok_button
+ def delete_merged_branches(branches_length)
+ click_element(:delete_merged_branches_button)
+ fill_element(:delete_merged_branches_input, branches_length)
+ click_element(:delete_merged_branches_confirmation_button)
+ finished_loading?
end
end
end
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index 89d044bac8d..75468c74814 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -85,8 +85,15 @@ module QA
end
end
end
-
alias_method :wait_for_success, :has_imported_project?
+
+ # Select advanced github import option
+ #
+ # @param [Symbol] option_name
+ # @return [void]
+ def select_advanced_option(option_name)
+ check_element(:advanced_settings_checkbox, true, option_name: option_name)
+ end
end
end
end
diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb
index fd650d8ca20..f7434656be3 100644
--- a/qa/qa/page/project/new.rb
+++ b/qa/qa/page/project/new.rb
@@ -64,6 +64,8 @@ module QA
end
def add_description(description)
+ return unless has_element?(:project_description, wait: 1)
+
fill_in 'project_description', with: description
end
diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb
index 06d154f5178..33ba27a788a 100644
--- a/qa/qa/page/project/pipeline/show.rb
+++ b/qa/qa/page/project/pipeline/show.rb
@@ -35,10 +35,6 @@ module QA
element :status_icon, 'ci-status-icon-${status}' # rubocop:disable QA/ElementWithPattern
end
- view 'app/views/projects/pipelines/_info.html.haml' do
- element :pipeline_badges
- end
-
view 'app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue' do
element :job_dropdown_container
element :jobs_dropdown_menu
@@ -68,12 +64,6 @@ module QA
has_no_element?(:job_link, text: job_name)
end
- def has_tag?(tag_name)
- within_element(:pipeline_badges) do
- has_selector?('.badge', text: tag_name)
- end
- end
-
def linked_pipelines
all_elements(:linked_pipeline_container, minimum: 1)
end
diff --git a/qa/qa/page/project/pipeline_editor/show.rb b/qa/qa/page/project/pipeline_editor/show.rb
index 70c0c5abb52..8fa20aa57cf 100644
--- a/qa/qa/page/project/pipeline_editor/show.rb
+++ b/qa/qa/page/project/pipeline_editor/show.rb
@@ -91,6 +91,8 @@ module QA
def write_to_editor(text)
find_element(:source_editor_container).fill_in(with: text)
+
+ wait_for_requests
end
def submit_changes
@@ -140,6 +142,10 @@ module QA
all_elements(:job_container, minimum: 1).any? { |item| item.text.match(/#{name}/i) }
end
+ def has_no_alert?
+ has_no_css?('.gl-alert-body')
+ end
+
def tab_alert_message
within_element(:file_editor_container) do
find('.gl-alert-body').text
@@ -174,9 +180,13 @@ module QA
within_element(:file_editor_container) do
find('.nav-item', text: name).click
end
+
+ wait_for_requests
end
end
end
end
end
end
+
+QA::Page::Project::PipelineEditor::Show.prepend_mod_with('Page::Project::PipelineEditor::Show', namespace: QA)
diff --git a/qa/qa/page/project/settings/advanced.rb b/qa/qa/page/project/settings/advanced.rb
index 9d8ed132ffd..fcfcecdc183 100644
--- a/qa/qa/page/project/settings/advanced.rb
+++ b/qa/qa/page/project/settings/advanced.rb
@@ -6,10 +6,11 @@ module QA
module Settings
class Advanced < Page::Base
include QA::Page::Component::ConfirmModal
+ include QA::Page::Component::DeleteModal
include Component::NamespaceSelect
- view 'app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger.vue' do
- element :confirm_danger_button
+ view 'app/assets/javascripts/projects/components/shared/delete_button.vue' do
+ element :delete_button
end
view 'app/views/projects/edit.html.haml' do
@@ -20,7 +21,6 @@ module QA
view 'app/views/projects/settings/_archive.html.haml' do
element :archive_project_link
element :unarchive_project_link
- element :archive_project_content
end
view 'app/views/projects/_export.html.haml' do
@@ -29,6 +29,14 @@ module QA
element :export_project_content
end
+ view 'app/views/projects/_transfer.html.haml' do
+ element :transfer_project_content
+ end
+
+ view 'app/assets/javascripts/projects/settings/components/transfer_project_form.vue' do
+ element :transfer_project_button
+ end
+
def update_project_path_to(path)
fill_project_path(path)
click_change_path_button
@@ -45,13 +53,16 @@ module QA
def transfer_project!(project_name, namespace)
QA::Runtime::Logger.info "Transferring project: #{project_name} to namespace: #{namespace}"
- click_element_coordinates(:archive_project_content)
+ scroll_to_transfer_project_content
# Workaround for a failure to search when there are no spaces around the /
# https://gitlab.com/gitlab-org/gitlab/-/issues/218965
select_namespace(namespace.gsub(%r{([^\s])/([^\s])}, '\1 / \2'))
- click_element(:confirm_danger_button)
+ wait_for_enabled_transfer_project_button
+
+ click_element :transfer_project_button
+
fill_confirmation_text(project_name)
confirm_transfer
end
@@ -77,6 +88,29 @@ module QA
click_element :unarchive_project_link
click_confirmation_ok_button
end
+
+ def delete_project!(project_name)
+ click_element :delete_button
+ fill_confirmation_path(project_name)
+ wait_for_delete_button_enabled
+ confirm_delete
+ end
+
+ private
+
+ def scroll_to_transfer_project_content
+ retry_until(sleep_interval: 1, message: 'Waiting for transfer project content to display') do
+ has_element?(:transfer_project_content, wait: 3)
+ end
+
+ scroll_to_element :transfer_project_content
+ end
+
+ def wait_for_enabled_transfer_project_button
+ retry_until(sleep_interval: 1, message: 'Waiting for transfer project button to be enabled') do
+ has_element?(:transfer_project_button, disabled: false, wait: 3)
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/settings/ci_variables.rb b/qa/qa/page/project/settings/ci_variables.rb
index 7ee015ceb98..316920ffa90 100644
--- a/qa/qa/page/project/settings/ci_variables.rb
+++ b/qa/qa/page/project/settings/ci_variables.rb
@@ -14,13 +14,6 @@ module QA
element :ci_variable_delete_button
end
- view 'app/assets/javascripts/ci_variable_list/components/legacy_ci_variable_table.vue' do
- element :ci_variable_table_content
- element :add_ci_variable_button
- element :edit_ci_variable_button
- element :reveal_ci_variable_value_button
- end
-
def fill_variable(key, value, masked = false)
within_element(:ci_variable_key_field) { find('input').set key }
fill_element :ci_variable_value_field, value
diff --git a/qa/qa/page/project/settings/default_branch.rb b/qa/qa/page/project/settings/default_branch.rb
index 575f9006c84..69ac45ce72d 100644
--- a/qa/qa/page/project/settings/default_branch.rb
+++ b/qa/qa/page/project/settings/default_branch.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class DefaultBranch < Page::Base
- view 'app/views/projects/default_branch/_show.html.haml' do
+ view 'app/views/projects/branch_defaults/_show.html.haml' do
element :save_changes_button
end
@@ -18,8 +18,8 @@ module QA
end
def set_default_branch(branch)
- click_button :default_branch_dropdown
- fill_in :ref_selector_searchbox, with: branch
+ find_element(:default_branch_dropdown, visible: false).click
+ find_element(:ref_selector_searchbox, visible: false).fill_in(with: branch)
click_button branch
end
diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb
index f55faff19e7..61ee3e4f03c 100644
--- a/qa/qa/page/project/settings/mirroring_repositories.rb
+++ b/qa/qa/page/project/settings/mirroring_repositories.rb
@@ -6,25 +6,25 @@ module QA
module Settings
class MirroringRepositories < Page::Base
view 'app/views/projects/mirrors/_authentication_method.html.haml' do
- element :authentication_method
- element :password
+ element :authentication_method_field
+ element :password_field
end
view 'app/views/projects/mirrors/_mirror_repos.html.haml' do
- element :mirror_repository_url_input
+ element :mirror_repository_url_field
element :mirror_repository_button
end
view 'app/views/projects/mirrors/_mirror_repos_list.html.haml' do
- element :mirror_repository_url_cell
- element :mirror_last_update_at_cell
- element :mirror_error_badge
- element :mirrored_repository_row
+ element :mirror_repository_url_content
+ element :mirror_last_update_at_content
+ element :mirror_error_badge_content
+ element :mirrored_repository_row_container
element :copy_public_key_button
end
view 'app/views/projects/mirrors/_mirror_repos_form.html.haml' do
- element :mirror_direction
+ element :mirror_direction_field
end
view 'app/views/shared/_remote_mirror_update_button.html.haml' do
@@ -37,28 +37,23 @@ module QA
element :fingerprints_list
end
- view 'app/views/projects/mirrors/_authentication_method.html.haml' do
- element :authentication_method
- element :password
- end
-
def repository_url=(value)
- fill_element :mirror_repository_url_input, value
+ fill_element :mirror_repository_url_field, value
end
def password=(value)
- fill_element :password, value
+ fill_element :password_field, value
end
def mirror_direction=(value)
raise ArgumentError, "Mirror direction must be 'Push' or 'Pull'" unless %w[Push Pull].include?(value)
- select_element(:mirror_direction, value)
+ select_element(:mirror_direction_field, value)
# Changing the mirror direction causes the fields below to change,
# and that change is animated, so we need to wait for the animation
# to complete otherwise changes to those fields could fail
- wait_for_animated_element :authentication_method
+ wait_for_animated_element :authentication_method_field
end
def authentication_method=(value)
@@ -66,13 +61,13 @@ module QA
raise ArgumentError, "Authentication method must be 'SSH public key', 'Password', or 'None'"
end
- select_element(:authentication_method, value)
+ select_element(:authentication_method_field, value)
end
def public_key(url)
row_index = find_repository_row_index url
- within_element_by_index(:mirrored_repository_row, row_index) do
+ within_element_by_index(:mirrored_repository_row_container, row_index) do
find_element(:copy_public_key_button)['data-clipboard-text']
end
end
@@ -92,7 +87,7 @@ module QA
def update(url)
row_index = find_repository_row_index(url)
- within_element_by_index(:mirrored_repository_row, row_index) do
+ within_element_by_index(:mirrored_repository_row_container, row_index) do
# When a repository is first mirrored, the update process might
# already be started, so the button is already "clicked"
click_element :update_now_button unless has_element? :updating_button
@@ -105,16 +100,16 @@ module QA
row_index = find_repository_row_index(url)
wait_until(sleep_interval: 1) do
- within_element_by_index(:mirrored_repository_row, row_index) do
- last_update = find_element(:mirror_last_update_at_cell, wait: 0)
+ within_element_by_index(:mirrored_repository_row_container, row_index) do
+ last_update = find_element(:mirror_last_update_at_content, wait: 0)
last_update.has_text?('just now') || last_update.has_text?('seconds')
end
end
# Fail early if the page still shows that there has been no update
- within_element_by_index(:mirrored_repository_row, row_index) do
- find_element(:mirror_last_update_at_cell, wait: 0).assert_no_text('Never')
- assert_no_element(:mirror_error_badge)
+ within_element_by_index(:mirrored_repository_row_container, row_index) do
+ find_element(:mirror_last_update_at_content, wait: 0).assert_no_text('Never')
+ assert_no_element(:mirror_error_badge_content)
end
end
@@ -122,7 +117,7 @@ module QA
def find_repository_row_index(target_url)
wait_until(max_duration: 5, reload: false) do
- all_elements(:mirror_repository_url_cell, minimum: 1).index do |url|
+ all_elements(:mirror_repository_url_content, minimum: 1).index do |url|
# The url might be a sanitized url but the target_url won't be so
# we compare just the paths instead of the full url
URI.parse(url.text).path == target_url.path
diff --git a/qa/qa/page/project/settings/protected_branches.rb b/qa/qa/page/project/settings/protected_branches.rb
index a78d8a6ccf4..4fbf656210f 100644
--- a/qa/qa/page/project/settings/protected_branches.rb
+++ b/qa/qa/page/project/settings/protected_branches.rb
@@ -6,8 +6,8 @@ module QA
module Settings
class ProtectedBranches < Page::Base
view 'app/views/projects/protected_branches/shared/_dropdown.html.haml' do
- element :protected_branch_select
element :protected_branch_dropdown
+ element :protected_branch_dropdown_content
end
view 'app/views/projects/protected_branches/_create_protected_branch.html.haml' do
@@ -22,9 +22,9 @@ module QA
end
def select_branch(branch_name)
- click_element :protected_branch_select
+ click_element :protected_branch_dropdown
- within_element(:protected_branch_dropdown) do
+ within_element(:protected_branch_dropdown_content) do
click_on branch_name
end
end
diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb
index de5b4f37076..bf1c3130485 100644
--- a/qa/qa/page/project/settings/repository.rb
+++ b/qa/qa/page/project/settings/repository.rb
@@ -58,7 +58,7 @@ module QA
end
def expand_default_branch(&block)
- within('#default-branch-settings') do
+ within('#branch-defaults-settings') do
find('.btn-default').click do
DefaultBranch.perform(&block)
end
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index 26c2da07b34..a82fa7f5cf3 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -32,7 +32,7 @@ module QA
end
view 'app/views/projects/_last_push.html.haml' do
- element :create_merge_request
+ element :create_merge_request_button
end
view 'app/views/projects/_home_panel.html.haml' do
@@ -54,7 +54,7 @@ module QA
end
view 'app/views/projects/empty.html.haml' do
- element :quick_actions
+ element :quick_actions_container
end
view 'app/assets/javascripts/repository/components/breadcrumbs.vue' do
@@ -72,7 +72,7 @@ module QA
end
view 'app/views/projects/blob/viewers/_loading.html.haml' do
- element :spinner
+ element :spinner_placeholder
end
view 'app/views/projects/buttons/_download.html.haml' do
@@ -80,11 +80,11 @@ module QA
end
def wait_for_viewers_to_load
- has_no_element?(:spinner, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
+ has_no_element?(:spinner_placeholder, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
end
def create_first_new_file!
- within_element(:quick_actions) do
+ within_element(:quick_actions_container) do
click_link_with_text 'New file'
end
end
@@ -122,7 +122,7 @@ module QA
end
def has_create_merge_request_button?
- has_css?(element_selector_css(:create_merge_request))
+ has_css?(element_selector_css(:create_merge_request_button))
end
def has_file?(name)
@@ -152,7 +152,7 @@ module QA
has_create_merge_request_button?
end
- click_element :create_merge_request
+ click_element :create_merge_request_button
end
def open_web_ide!
diff --git a/qa/qa/page/project/sub_menus/ci_cd.rb b/qa/qa/page/project/sub_menus/ci_cd.rb
index c8c90df2c1f..4ae51798e54 100644
--- a/qa/qa/page/project/sub_menus/ci_cd.rb
+++ b/qa/qa/page/project/sub_menus/ci_cd.rb
@@ -43,3 +43,5 @@ module QA
end
end
end
+
+QA::Page::Project::SubMenus::CiCd.prepend_mod_with('Page::Project::SubMenus::CiCd', namespace: QA)
diff --git a/qa/qa/page/project/sub_menus/issues.rb b/qa/qa/page/project/sub_menus/issues.rb
index 48cdf9791f8..7fa19063653 100644
--- a/qa/qa/page/project/sub_menus/issues.rb
+++ b/qa/qa/page/project/sub_menus/issues.rb
@@ -74,3 +74,5 @@ module QA
end
end
end
+
+QA::Page::Project::SubMenus::Issues.prepend_mod_with('Page::Project::SubMenus::Issues', namespace: QA)
diff --git a/qa/qa/resource/approval_configuration.rb b/qa/qa/resource/approval_configuration.rb
new file mode 100644
index 00000000000..89b8201d7d2
--- /dev/null
+++ b/qa/qa/resource/approval_configuration.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ # Helper for approval configuration which exists on project and mr level
+ module ApprovalConfiguration
+ include ApiFabricator
+
+ def api_approval_configuration_path
+ "#{api_get_path}/approvals"
+ end
+
+ def api_approval_rules_path
+ "#{api_get_path}/approval_rules"
+ end
+
+ # Approval configuration
+ #
+ # @return [Hash]
+ def approval_configuration
+ parse_body(api_get_from(api_approval_configuration_path))
+ end
+
+ # Update approvals configuration
+ # MR: https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration
+ # Project: https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-configuration
+ #
+ # @param [Hash] configuration
+ # @return [Hash]
+ def update_approval_configuration(configuration)
+ api_post_to(api_approval_configuration_path, configuration)
+ end
+
+ # Approval rules
+ #
+ # @return [Array<Hash>]
+ def fetch_approval_rules
+ parse_body(api_get_from(api_approval_rules_path))
+ end
+
+ # Create approval rules
+ #
+ # @return [Hash]
+ def create_approval_rules
+ raise("Trying to create approval rules but no rules set!") unless approval_rules
+
+ rule = { approvals_required: 1, name: "Approval rule for mr #{title}" }
+ rule[:user_ids] = approval_rules[:users].map(&:id) if approval_rules[:users]
+ rule[:group_ids] = approval_rules[:group].map(&:full_path) if approval_rules[:groups]
+
+ api_post_to(api_approvals_path, rule)
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb
index 6025dd6ec40..4a1a60f4da1 100644
--- a/qa/qa/resource/base.rb
+++ b/qa/qa/resource/base.rb
@@ -22,8 +22,20 @@ module QA
new.tap(&prepare_block)
end
+ def fabricate_via_api_unless_fips!
+ if QA::Support::FIPS.enabled?
+ fabricate!
+ else
+ fabricate_via_api!
+ end
+ end
+
def fabricate!(*args, &prepare_block)
- fabricate_via_api!(*args, &prepare_block)
+ if QA::Support::FIPS.enabled?
+ fabricate_via_browser_ui!(*args, &prepare_block)
+ else
+ fabricate_via_api!(*args, &prepare_block)
+ end
rescue NotImplementedError
fabricate_via_browser_ui!(*args, &prepare_block)
end
@@ -95,7 +107,7 @@ module QA
Support::FabricationTracker.save_fabrication(:"#{fabrication_method}_fabrication", fabrication_time)
- unless resource.retrieved_from_cache
+ unless resource.retrieved_from_cache || QA::Support::FIPS.enabled?
Tools::TestResourceDataProcessor.collect(
resource: resource,
info: resource.identifier,
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index 84416c0600d..9d1a6868562 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -18,8 +18,14 @@ module QA
end
attribute :sandbox do
- Sandbox.fabricate_via_api! do |sandbox|
- sandbox.api_client = api_client
+ if QA::Support::FIPS.enabled?
+ Resource::Sandbox.fabricate! do |sandbox|
+ sandbox.path = Runtime::Namespace.sandbox_name
+ end
+ else
+ Sandbox.fabricate_via_api! do |sandbox|
+ sandbox.api_client = api_client
+ end
end
end
diff --git a/qa/qa/resource/members.rb b/qa/qa/resource/members.rb
index d9300f80f5d..4bf9c2bed6b 100644
--- a/qa/qa/resource/members.rb
+++ b/qa/qa/resource/members.rb
@@ -10,8 +10,8 @@ module QA
def add_member(user, access_level = AccessLevel::DEVELOPER)
Support::Retrier.retry_until do
QA::Runtime::Logger.info(%(Adding user #{user.username} to #{full_path} #{self.class.name}))
-
- response = post Runtime::API::Request.new(api_client, api_members_path).url, { user_id: user.id, access_level: access_level }
+ response = post Runtime::API::Request.new(api_client, api_members_path).url,
+{ user_id: user.id, access_level: access_level }
break true if response.code == QA::Support::API::HTTP_STATUS_CREATED
break true if response.body.include?('Member already exists')
end
@@ -31,7 +31,8 @@ module QA
Support::Retrier.retry_until do
QA::Runtime::Logger.info(%(Sharing #{self.class.name} with #{group.name}))
- response = post Runtime::API::Request.new(api_client, api_share_path).url, { group_id: group.id, group_access: access_level }
+ response = post Runtime::API::Request.new(api_client, api_share_path).url,
+{ group_id: group.id, group_access: access_level }
response.code == QA::Support::API::HTTP_STATUS_CREATED
end
end
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index 5d6dc12ac9c..fcfda106523 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -3,6 +3,8 @@
module QA
module Resource
class MergeRequest < Issuable
+ include ApprovalConfiguration
+
attr_accessor :approval_rules,
:source_branch,
:target_new_branch,
@@ -11,7 +13,8 @@ module QA
:milestone,
:labels,
:file_name,
- :file_content
+ :file_content,
+ :reviewer_ids
attr_writer :no_preparation,
:wait_for_merge,
@@ -22,7 +25,8 @@ module QA
:description,
:merge_when_pipeline_succeeds,
:merge_status,
- :state
+ :state,
+ :reviewers
attribute :project do
Project.fabricate_via_api! do |resource|
@@ -121,12 +125,21 @@ module QA
"/projects/#{project.id}/merge_requests"
end
+ def api_reviewers_path
+ "#{api_get_path}/reviewers"
+ end
+
+ def api_approve_path
+ "#{api_get_path}/approve"
+ end
+
def api_post_body
{
description: description,
source_branch: source_branch,
target_branch: target_branch,
- title: title
+ title: title,
+ reviewer_ids: reviewer_ids
}
end
@@ -152,6 +165,17 @@ module QA
end
end
+ # Approve merge request
+ #
+ # Due to internal implementation of api client, project needs to have
+ # setting 'Prevent approval by author' set to false since we use same user that created merge request which
+ # is set through approval configuration
+ #
+ # @return [void]
+ def approve
+ api_post_to(api_approve_path, {})
+ end
+
def fabricate_large_merge_request
@project = Resource::ImportProject.fabricate_via_browser_ui!
# Setting the name here, since otherwise some tests will look for an existing file in
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index e5df95f1fa5..3cbc002fa86 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -7,6 +7,7 @@ module QA
include Integrations::Project
include Members
include Visibility
+ include ApprovalConfiguration
attr_accessor :initialize_with_readme,
:auto_devops_enabled,
@@ -479,6 +480,16 @@ module QA
end
end
+ def remove_via_browser_ui!
+ Page::Project::Menu.perform(&:go_to_general_settings)
+
+ Page::Project::Settings::Main.perform(&:expand_advanced_settings)
+
+ Page::Project::Settings::Advanced.perform do |advanced|
+ advanced.delete_project!(full_path)
+ end
+ end
+
# Calls the API endpoint that triggers the backend service that performs repository housekeeping (garbage
# collection and similar tasks).
def perform_housekeeping
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index 9ba9723f0cc..1e6b2ff620e 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -18,6 +18,11 @@ module QA
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(github_personal_access_token)
+
+ import_page.select_advanced_option(:single_endpoint_issue_events_import) if issue_events_import
+ import_page.select_advanced_option(:single_endpoint_notes_import) if full_notes_import
+ import_page.select_advanced_option(:attachments_import) if attachments_import
+
import_page.import!(github_repository_path, group.full_path, name)
import_page.wait_for_success(github_repository_path, wait: 240)
end
diff --git a/qa/qa/resource/sandbox.rb b/qa/qa/resource/sandbox.rb
index 2080e279e99..18526448b00 100644
--- a/qa/qa/resource/sandbox.rb
+++ b/qa/qa/resource/sandbox.rb
@@ -10,7 +10,9 @@ module QA
class << self
# Force top level group creation via UI if test is executed on dot_com environment
def fabricate!(*args, &prepare_block)
- return fabricate_via_browser_ui!(*args, &prepare_block) if Specs::Helpers::ContextSelector.dot_com?
+ if Specs::Helpers::ContextSelector.dot_com? || QA::Support::FIPS.enabled?
+ return fabricate_via_browser_ui!(*args, &prepare_block)
+ end
fabricate_via_api!(*args, &prepare_block)
rescue NotImplementedError
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index 71a5e1c8930..c8babbc0b16 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -79,11 +79,22 @@ module QA
defined?(@username) && defined?(@password)
end
+ def has_user?(user)
+ Flow::Login.while_signed_in_as_admin do
+ Page::Main::Menu.perform(&:go_to_admin_area)
+ Page::Admin::Menu.perform(&:go_to_users_overview)
+ Page::Admin::Overview::Users::Index.perform do |index|
+ index.search_user(user.username)
+ index.has_username?(user.username)
+ end
+ end
+ end
+
def fabricate!
# Don't try to log-out if we're not logged-in
Page::Main::Menu.perform(&:sign_out) if Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
- if credentials_given?
+ if credentials_given? || has_user?(self)
Page::Main::Login.perform do |login|
login.sign_in_using_credentials(user: self)
end
@@ -144,7 +155,7 @@ module QA
end
def self.fabricate_or_use(username = nil, password = nil)
- if Runtime::Env.signup_disabled?
+ if Runtime::Env.signup_disabled? || !QA::Support::FIPS.enabled?
fabricate_via_api! do |user|
user.username = username
user.password = password
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
index 10f47ca56ba..a9152a5555c 100644
--- a/qa/qa/runtime/allure_report.rb
+++ b/qa/qa/runtime/allure_report.rb
@@ -96,9 +96,14 @@ module QA
return {} unless Env.admin_personal_access_token || Env.personal_access_token
client = Env.admin_personal_access_token ? API::Client.as_admin : API::Client.new
- response = get(API::Request.new(client, '/version').url)
+ response = get(API::Request.new(client, '/metadata').url)
- JSON.parse(response.body, symbolize_names: true)
+ JSON.parse(response.body, symbolize_names: true).then do |metadata|
+ {
+ **metadata.slice(:version, :revision),
+ kas_version: metadata.dig(:kas, :version)
+ }.compact
+ end
rescue StandardError, ArgumentError => e
Logger.error("Failed to attach version info to allure report: #{e}")
{}
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index 0dbc3cdf09d..d2ddaf86353 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -111,6 +111,7 @@ module QA
if QA::Runtime::Env.remote_mobile_device_name
capabilities['platformName'] = 'Android'
+ capabilities['appium:automationName'] = 'UiAutomator2'
capabilities['appium:deviceName'] = QA::Runtime::Env.remote_mobile_device_name
capabilities['appium:platformVersion'] = 'latest'
else
@@ -120,6 +121,7 @@ module QA
when :safari
if QA::Runtime::Env.remote_mobile_device_name
capabilities['platformName'] = 'iOS'
+ capabilities['appium:automationName'] = 'XCUITest'
capabilities['appium:deviceName'] = QA::Runtime::Env.remote_mobile_device_name
capabilities['appium:platformVersion'] = 'latest'
end
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 782ba1cf2fa..7cb7625118e 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -443,7 +443,11 @@ module QA
end
def export_metrics?
- running_in_ci? && enabled?(ENV['QA_EXPORT_TEST_METRICS'], default: true)
+ enabled?(ENV['QA_EXPORT_TEST_METRICS'], default: false)
+ end
+
+ def save_metrics_json?
+ enabled?(ENV['QA_SAVE_TEST_METRICS'], default: false)
end
def ee_activation_code
diff --git a/qa/qa/runtime/key/ed25519.rb b/qa/qa/runtime/key/ed25519.rb
index 3a3567d55da..f59d7b3688d 100644
--- a/qa/qa/runtime/key/ed25519.rb
+++ b/qa/qa/runtime/key/ed25519.rb
@@ -4,8 +4,8 @@ module QA
module Runtime
module Key
class ED25519 < Base
- def initialize
- super('ed25519', 256)
+ def initialize(bits = 256)
+ super('ed25519', bits)
end
end
end
diff --git a/qa/qa/scenario/bootable.rb b/qa/qa/scenario/bootable.rb
index 8eedfab3cff..c6050798e22 100644
--- a/qa/qa/scenario/bootable.rb
+++ b/qa/qa/scenario/bootable.rb
@@ -19,7 +19,8 @@ module QA
options.to_a.each do |opt|
# The argument for the --set-feature-flags option should look something like "flag1=enabled,flag2=disabled"
# Here we translate that string into a hash, e.g.: { 'flag1' => 'enabled', 'flag2' => "disabled" }
- if opt.name == :set_feature_flags
+ case opt.name
+ when :set_feature_flags
parser.on(opt.arg, opt.desc) do |flags|
value = flags.split(',').each_with_object({}) do |pair, hash|
flag_name, flag_value = pair.split('=')
@@ -31,7 +32,7 @@ module QA
end
next
- elsif opt.name == :count_examples_only || opt.name == :test_metadata_only
+ when :count_examples_only, :test_metadata_only
parser.on(opt.arg, opt.desc) do |value|
QA::Runtime::Env.dry_run = true
Runtime::Scenario.define(opt.name, value)
diff --git a/qa/qa/scenario/test/instance/gitlab_pages.rb b/qa/qa/scenario/test/instance/gitlab_pages.rb
new file mode 100644
index 00000000000..487fd739626
--- /dev/null
+++ b/qa/qa/scenario/test/instance/gitlab_pages.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Instance
+ class GitlabPages < All
+ tags :gitlab_pages
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb
index 2058d58d5d6..8bbef4ae429 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Systems' do
+ RSpec.describe 'Systems', product_group: :gitaly do
context 'with Gitaly automatic failover and recovery', :orchestrated, :gitaly_cluster do
# Variables shared between contexts. They're used and shared between
# contexts so they can't be `let` variables.
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb
index 0b4bdf550f8..1abc7b8a912 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Systems' do
+ RSpec.describe 'Systems', product_group: :gitaly do
describe 'Gitaly backend node recovery', :orchestrated, :gitaly_cluster, :skip_live_env do
let(:praefect_manager) { Service::PraefectManager.new }
let(:project) do
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 18ec8e0a8b4..01c50c0cd6a 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Systems' do
+ RSpec.describe 'Systems', product_group: :gitaly do
describe 'Changing Gitaly repository storage', :requires_admin, except: { job: 'review-qa-*' } do
praefect_manager = Service::PraefectManager.new
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb
index 692297e40ce..397fdb909ac 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb
@@ -3,7 +3,7 @@
require 'parallel'
module QA
- RSpec.describe 'Systems' do
+ RSpec.describe 'Systems', product_group: :gitaly do
describe 'Gitaly distributed reads', :orchestrated, :gitaly_cluster, :skip_live_env, :requires_admin do
let(:number_of_reads_per_loop) { 9 }
let(:praefect_manager) { Service::PraefectManager.new }
@@ -45,7 +45,11 @@ module QA
end
it 'does not read from the unhealthy node',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347834' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347834',
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/378174',
+ type: :flaky
+ } do
pre_read_data = praefect_manager.query_read_distribution
read_from_project(project, number_of_reads_per_loop * 10)
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb
index a4b39554453..48d08136d28 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Systems' do
- describe 'Gitaly using mTLS', :orchestrated, :mtls do
+ describe 'Gitaly using mTLS', :orchestrated, :mtls, product_group: :gitaly do
let(:intial_commit_message) { 'Initial commit' }
let(:first_added_commit_message) { 'commit over git' }
let(:second_added_commit_message) { 'commit over api' }
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb
index f25b50f584d..bd00b3781f7 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Systems' do
- describe 'Praefect connectivity commands', :orchestrated, :gitaly_cluster do
+ describe 'Praefect connectivity commands', :orchestrated, :gitaly_cluster, product_group: :gitaly do
praefect_manager = Service::PraefectManager.new
before do
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb
index 944c58ebc83..6ba192a9dd6 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Systems' do
- describe 'Praefect dataloss commands', :orchestrated, :gitaly_cluster do
+ describe 'Praefect dataloss commands', :orchestrated, :gitaly_cluster, product_group: :gitaly do
let(:praefect_manager) { Service::PraefectManager.new }
let(:project) do
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb
index f4efcf74956..94bae38c5c8 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb
@@ -3,7 +3,7 @@
require 'parallel'
module QA
- RSpec.describe 'Systems' do
+ RSpec.describe 'Systems', product_group: :gitaly do
describe 'Gitaly Cluster replication queue', :orchestrated, :gitaly_cluster, :skip_live_env do
let(:praefect_manager) { Service::PraefectManager.new }
let(:project) do
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb
index 064743ae469..40fc6bf2637 100644
--- a/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb
+++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Systems' do
- describe 'Praefect repository commands', :orchestrated, :gitaly_cluster do
+ describe 'Praefect repository commands', :orchestrated, :gitaly_cluster, product_group: :gitaly do
let(:praefect_manager) { Service::PraefectManager.new }
let(:repo1) do
diff --git a/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb b/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb
index bf95a215c8e..e0db758dde3 100644
--- a/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Group access token' do
+ describe 'Group access token', product_group: :authentication_and_authorization do
let(:group_access_token) { QA::Resource::GroupAccessToken.fabricate_via_api! }
let(:api_client) { Runtime::API::Client.new(:gitlab, personal_access_token: group_access_token.token) }
let(:project) do
diff --git a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
index c3e41e9298b..ab50e02c790 100644
--- a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
@@ -1,165 +1,197 @@
# frozen_string_literal: true
module QA
- # Spec uses real github.com, which means outage of github.com can actually block deployment
- # Keep spec in reliable bucket but don't run in blocking pipelines
- RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do
- describe 'Project import', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353583' do
- let!(:api_client) { Runtime::API::Client.as_admin }
- let!(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
- let!(:user) do
- Resource::User.fabricate_via_api! do |resource|
- resource.api_client = api_client
- resource.hard_delete_on_api_removal = true
+ # https://github.com/gitlab-qa-github/import-test <- project under test
+ #
+ RSpec.describe 'Manage', product_group: :import do
+ describe 'GitHub import', :reliable do
+ include_context 'with github import'
+
+ context 'when imported via api' do
+ it 'imports project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do
+ imported_project.reload! # import the project
+
+ expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
+ .within(max_duration: 240, sleep_interval: 1)
+
+ aggregate_failures do
+ verify_status_data
+ verify_repository_import
+ verify_protected_branches_import
+ verify_commits_import
+ verify_labels_import
+ verify_issues_import
+ verify_milestones_import
+ verify_wikis_import
+ verify_merge_requests_import
+ verify_release_import
+ end
end
- end
- let(:imported_project) do
- Resource::ProjectImportedFromGithub.fabricate_via_api! do |project|
- project.name = 'imported-project'
- project.group = group
- project.github_personal_access_token = Runtime::Env.github_access_token
- project.github_repository_path = 'gitlab-qa-github/import-test'
- project.api_client = Runtime::API::Client.new(user: user)
- project.issue_events_import = true
- project.full_notes_import = true
+ def verify_status_data
+ stats = imported_project.project_import_status.dig(:stats, :imported)
+ expect(stats).to include(
+ issue: 1,
+ label: 9,
+ milestone: 1,
+ note: 3,
+ pull_request: 1,
+ pull_request_review: 1,
+ diff_note: 1,
+ release: 1
+ )
end
- end
-
- before do
- group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
- end
- after do
- user.remove_via_api!
- end
-
- it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do
- imported_project.reload! # import the project
-
- expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
- .within(max_duration: 240, sleep_interval: 1)
-
- aggregate_failures do
- verify_status_data
- verify_repository_import
- verify_protected_branches_import
- verify_commits_import
- verify_labels_import
- verify_issues_import
- verify_milestones_import
- verify_wikis_import
- verify_merge_requests_import
+ def verify_repository_import
+ expect(imported_project.reload!.description).to eq('Project for github import test')
+ expect(imported_project.api_response[:import_error]).to be_nil
end
- end
- def verify_status_data
- stats = imported_project.project_import_status.dig(:stats, :imported)
- expect(stats).to include(
- issue: 1,
- label: 9,
- milestone: 1,
- note: 3,
- pull_request: 1,
- pull_request_review: 1,
- diff_note: 1,
- release: 1
- )
- end
+ def verify_protected_branches_import
+ imported_branches = imported_project.protected_branches.map do |branch|
+ branch.slice(:name, :allow_force_push)
+ end
+ actual_branches = [
+ {
+ name: 'main',
+ allow_force_push: false
+ },
+ {
+ name: 'release',
+ allow_force_push: true
+ }
+ ]
- def verify_repository_import
- expect(imported_project.reload!.description).to eq('Project for github import test')
- expect(imported_project.api_response[:import_error]).to be_nil
- end
+ expect(imported_branches).to match_array(actual_branches)
+ end
- def verify_protected_branches_import
- branches = imported_project.protected_branches.map do |branch|
- branch.slice(:name, :allow_force_push, :code_owner_approval_required)
+ def verify_commits_import
+ expect(imported_project.commits.length).to eq(2)
end
- expect(branches.first).to include(
- {
- name: 'main'
- # TODO: Add validation once https://gitlab.com/groups/gitlab-org/-/epics/8585 is closed
- # At the moment both options are always set to false regardless of state in github
- # allow_force_push: true,
- # code_owner_approval_required: true
- }
- )
- end
- def verify_commits_import
- expect(imported_project.commits.length).to eq(2)
- end
+ def verify_labels_import
+ labels = imported_project.labels.map { |label| label.slice(:name, :color) }
+
+ expect(labels).to include(
+ { name: 'bug', color: '#d73a4a' },
+ { name: 'documentation', color: '#0075ca' },
+ { name: 'duplicate', color: '#cfd3d7' },
+ { name: 'enhancement', color: '#a2eeef' },
+ { name: 'good first issue', color: '#7057ff' },
+ { name: 'help wanted', color: '#008672' },
+ { name: 'invalid', color: '#e4e669' },
+ { name: 'question', color: '#d876e3' },
+ { name: 'wontfix', color: '#ffffff' }
+ )
+ end
- def verify_labels_import
- labels = imported_project.labels.map { |label| label.slice(:name, :color) }
-
- expect(labels).to include(
- { name: 'bug', color: '#d73a4a' },
- { name: 'documentation', color: '#0075ca' },
- { name: 'duplicate', color: '#cfd3d7' },
- { name: 'enhancement', color: '#a2eeef' },
- { name: 'good first issue', color: '#7057ff' },
- { name: 'help wanted', color: '#008672' },
- { name: 'invalid', color: '#e4e669' },
- { name: 'question', color: '#d876e3' },
- { name: 'wontfix', color: '#ffffff' }
- )
- end
+ def verify_milestones_import
+ milestones = imported_project.milestones
- def verify_issues_import
- issues = imported_project.issues
+ expect(milestones.length).to eq(1)
+ expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active')
+ end
- expect(issues.length).to eq(1)
- expect(issues.first).to include(
- title: 'Test issue',
- description: "*Created by: gitlab-qa-github*\n\nTest issue description",
- labels: ['good first issue', 'help wanted', 'question'],
- user_notes_count: 2
- )
- end
+ def verify_wikis_import
+ wikis = imported_project.wikis
- def verify_milestones_import
- milestones = imported_project.milestones
+ expect(wikis.length).to eq(1)
+ expect(wikis.first).to include(title: 'Home', format: 'markdown')
+ end
- expect(milestones.length).to eq(1)
- expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active')
- end
+ def verify_issues_import
+ issues = imported_project.issues
+ issue = Resource::Issue.init do |resource|
+ resource.project = imported_project
+ resource.iid = issues.first[:iid]
+ resource.api_client = user_api_client
+ end.reload!
+ comments, events = fetch_events_and_comments(issue)
+
+ expect(issues.length).to eq(1)
+ expect(issue.api_resource).to include(
+ title: 'Test issue',
+ description: "*Created by: gitlab-qa-github*\n\nTest issue description",
+ labels: ['good first issue', 'help wanted', 'question']
+ )
+ expect(comments).to match_array(
+ [
+ "*Created by: gitlab-qa-github*\n\nSome test comment",
+ "*Created by: gitlab-qa-github*\n\nAnother test comment"
+ ]
+ )
+ expect(events).to match_array(
+ [
+ { name: "add_label", label: "question" },
+ { name: "add_label", label: "good first issue" },
+ { name: "add_label", label: "help wanted" },
+ { name: "add_milestone", label: "0.0.1" },
+ { name: "closed" },
+ { name: "reopened" }
+ ]
+ )
+ end
- def verify_wikis_import
- wikis = imported_project.wikis
+ def verify_merge_requests_import
+ merge_requests = imported_project.merge_requests
+ merge_request = Resource::MergeRequest.init do |mr|
+ mr.project = imported_project
+ mr.iid = merge_requests.first[:iid]
+ mr.api_client = user_api_client
+ end.reload!
+ comments, events = fetch_events_and_comments(merge_request)
+
+ expect(merge_requests.length).to eq(1)
+ expect(merge_request.api_resource).to include(
+ title: 'Test pull request',
+ state: 'opened',
+ target_branch: 'main',
+ source_branch: 'gitlab-qa-github-patch-1',
+ labels: %w[documentation],
+ description: "*Created by: gitlab-qa-github*\n\nTest pull request body"
+ )
+ expect(comments).to match_array(
+ [
+ "*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement",
+ "*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```",
+ "*Created by: gitlab-qa-github*\n\nSome test PR comment"
+ ]
+ )
+ expect(events).to match_array(
+ [
+ { name: "add_label", label: "documentation" },
+ { name: "add_milestone", label: "0.0.1" }
+ ]
+ )
+ end
- expect(wikis.length).to eq(1)
- expect(wikis.first).to include(title: 'Home', format: 'markdown')
- end
+ def verify_release_import
+ releases = imported_project.releases
+
+ expect(releases.length).to eq(1)
+ expect(releases.first).to include(
+ tag_name: "0.0.1",
+ name: "0.0.1",
+ description: "Initial release",
+ created_at: "2022-03-07T07:59:22.000Z",
+ released_at: "2022-03-07T08:02:09.000Z"
+ )
+ end
- def verify_merge_requests_import
- merge_requests = imported_project.merge_requests
- merge_request = Resource::MergeRequest.init do |mr|
- mr.project = imported_project
- mr.iid = merge_requests.first[:iid]
- mr.api_client = api_client
- end.reload!
- mr_comments = merge_request.comments.map { |comment| comment[:body] }
-
- expect(merge_requests.length).to eq(1)
- expect(merge_request.api_resource).to include(
- title: 'Test pull request',
- state: 'opened',
- target_branch: 'main',
- source_branch: 'gitlab-qa-github-patch-1',
- labels: %w[documentation],
- description: <<~DSC.strip
- *Created by: gitlab-qa-github*\n\nTest pull request body
- DSC
- )
- expect(mr_comments).to match_array(
- [
- "*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement",
- "*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```",
- "*Created by: gitlab-qa-github*\n\nSome test PR comment"
+ # Fetch events and comments from issue or mr
+ #
+ # @param [QA::Resource::Issuable] issuable
+ # @return [Array]
+ def fetch_events_and_comments(issuable)
+ comments = issuable.comments.map { |comment| comment[:body] }
+ events = [
+ *issuable.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } },
+ *issuable.state_events.map { |e| { name: e[:state] } },
+ *issuable.milestone_events.map { |e| { name: "#{e[:action]}_milestone", label: e.dig(:milestone, :title) } }
]
- )
+
+ [comments, events]
+ end
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
index c1f11b15068..887eeda51e3 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative 'gitlab_project_migration_common'
-
module QA
RSpec.describe 'Manage' do
describe 'Gitlab migration', product_group: :import do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
index 5689fa169ce..116a00f8385 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
@@ -98,12 +98,17 @@ module QA
let(:mrs) { fetch_mrs(imported_project, target_api_client) }
let(:issues) { fetch_issues(imported_project, target_api_client) }
+ let(:import_failures) { imported_group.import_details.sum([]) { |details| details[:failures] } }
+
before do
destination_group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
end
# rubocop:disable RSpec/InstanceVariable
after do |example|
+ # Log failures for easier debugging
+ Runtime::Logger.error("Import failures: #{import_failures}") if example.exception && !import_failures.empty?
+
next unless defined?(@import_time)
# save data for comparison notification creation
@@ -112,7 +117,7 @@ module QA
{
importer: :gitlab,
import_time: @import_time,
- errors: imported_group.import_details.sum([]) { |details| details[:failures] },
+ errors: import_failures,
source: {
name: "GitLab Source",
project_name: source_project.path_with_namespace,
@@ -154,7 +159,7 @@ module QA
end
# rubocop:enable RSpec/InstanceVariable
- it "migrates large gitlab group via api", testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358842' do
+ it "migrates large gitlab group via api", testcase: "https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/358842" do
start = Time.now
# trigger import and log imported group path
@@ -165,7 +170,11 @@ module QA
# wait for import to finish and save import time
logger.info("== Waiting for import to be finished ==")
- expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
+ expect { imported_group.import_status }.not_to eventually_eq("started").within(import_wait_duration)
+ # finished status actually means success, don't wait for finished status explicitly
+ # because test would wait full duration if returned status is "failed"
+ expect(imported_group.import_status).to eq("finished")
+
@import_time = Time.now - start
aggregate_failures do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
index aa4d3becbe7..07e54ead9c8 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative 'gitlab_project_migration_common'
-
module QA
RSpec.describe 'Manage' do
describe 'Gitlab migration', product_group: :import do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
index 92cba005832..f44786939dc 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
@@ -1,49 +1,66 @@
# frozen_string_literal: true
-require_relative 'gitlab_project_migration_common'
-
module QA
RSpec.describe 'Manage' do
describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
- context 'with merge request' do
- let!(:source_project_with_readme) { true }
-
- let!(:other_user) do
- Resource::User
- .fabricate_via_api! { |usr| usr.api_client = admin_api_client }
- .tap do |usr|
- usr.set_public_email
- source_project.add_member(usr, Resource::Members::AccessLevel::MAINTAINER)
- end
- end
+ let!(:source_project_with_readme) { true }
- let!(:source_mr) do
- Resource::MergeRequest.fabricate_via_api! do |mr|
- mr.project = source_project
- mr.api_client = Runtime::API::Client.new(user: other_user)
+ # We create additional user so that object being migrated is not owned by the user doing migration
+ let!(:other_user) do
+ Resource::User
+ .fabricate_via_api! { |usr| usr.api_client = admin_api_client }
+ .tap do |usr|
+ usr.set_public_email
+ source_project.add_member(usr, Resource::Members::AccessLevel::MAINTAINER)
end
+ end
+
+ let!(:source_mr) do
+ Resource::MergeRequest.fabricate_via_api! do |mr|
+ mr.project = source_project
+ mr.api_client = Runtime::API::Client.new(user: other_user)
+ mr.reviewer_ids = [other_user.id]
end
+ end
- let!(:source_comment) { source_mr.add_comment('This is a test comment!') }
+ let!(:source_comment) { source_mr.add_comment(body: 'This is a test comment!') }
- let(:imported_mrs) { imported_project.merge_requests }
- let(:imported_mr_comments) { imported_mr.comments.map { |note| note.except(:id, :noteable_id) } }
- let(:source_mr_comments) { source_mr.comments.map { |note| note.except(:id, :noteable_id) } }
+ let(:imported_mrs) { imported_project.merge_requests }
+ let(:imported_mr_comments) { imported_mr.comments.map { |note| note.except(:id, :noteable_id) } }
+ let(:source_mr_comments) { source_mr.comments.map { |note| note.except(:id, :noteable_id) } }
- let(:imported_mr) do
- Resource::MergeRequest.init do |mr|
- mr.project = imported_project
- mr.iid = imported_mrs.first[:iid]
- mr.api_client = api_client
- end
+ let(:imported_mr) do
+ Resource::MergeRequest.init do |mr|
+ mr.project = imported_project
+ mr.iid = imported_mrs.first[:iid]
+ mr.api_client = api_client
end
+ end
- after do
- other_user.remove_via_api!
+ let(:imported_mr_reviewers) { imported_mr.reviewers.map { |r| r.slice(:name, :username) } }
+ let(:source_mr_reviewers) { [{ name: other_user.name, username: other_user.username }] }
+
+ let(:imported_mr_approvers) do
+ imported_mr.approval_configuration[:approved_by].map do |usr|
+ { username: usr.dig(:user, :username), name: usr.dig(:user, :name) }
end
+ end
+
+ before do
+ source_project.update_approval_configuration(
+ merge_requests_author_approval: true,
+ approvals_before_merge: 1
+ )
+ source_mr.approve
+ end
+ after do
+ other_user.remove_via_api!
+ end
+
+ context 'with merge request' do
it(
'successfully imports merge request',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348478'
@@ -54,7 +71,9 @@ module QA
aggregate_failures do
expect(imported_mr).to eq(source_mr.reload!)
- expect(imported_mr_comments).to eq(source_mr_comments)
+ expect(imported_mr_comments).to match_array(source_mr_comments)
+ expect(imported_mr_reviewers).to eq(source_mr_reviewers)
+ expect(imported_mr_approvers).to eq([{ username: other_user.username, name: other_user.name }])
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
index 3db4ff4351e..7b79e6967c7 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative 'gitlab_project_migration_common'
-
module QA
RSpec.describe 'Manage' do
describe 'Gitlab migration', product_group: :import 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 3e0df3d1e13..2b7818d1ed2 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
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative 'gitlab_project_migration_common'
-
module QA
RSpec.describe 'Manage' do
describe 'Gitlab migration', product_group: :import do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
index 91dcfe6a1a3..36036a2321e 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative 'gitlab_project_migration_common'
-
module QA
RSpec.describe 'Manage' do
describe 'Gitlab migration', product_group: :import do
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 756bbe2164a..e210ba882bb 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project access token' do
+ 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::ReusableProject.fabricate_via_api!
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 28c20344b29..b7d0d72297a 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin, :reliable do
+ describe 'User', :requires_admin, :reliable, product_group: :authentication_and_authorization do
before(:all) do
admin_api_client = Runtime::API::Client.as_admin
diff --git a/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb b/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb
index 073669f033c..6935f9de486 100644
--- a/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb
+++ b/qa/qa/specs/features/api/2_plan/closes_issue_via_pushing_a_commit_spec.rb
@@ -6,7 +6,7 @@ module QA
RSpec.describe 'Plan' do
include Support::API
- describe 'Issue' do
+ describe 'Issue', product_group: :project_management do
let(:issue) do
Resource::Issue.fabricate_via_api!
end
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 ab9af872753..a1060c1d890 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' do
+ describe 'Merge request push options', 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
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 6eb3060fb59..0a82c5d6736 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options' do
+ describe 'Merge request push options', 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
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 708dd7aa8af..11328c2f517 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options' do
+ describe 'Merge request push options', 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
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 97d461c5113..eb7d3da0f97 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options' do
+ describe 'Merge request push options', 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
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 9d534e9ea6b..dd297f47975 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request push options' do
+ describe 'Merge request push options', 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
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 df3b5a4e7fb..8c7a58be43a 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
@@ -46,6 +46,7 @@ module QA
local_size = Git::Repository.perform do |repository|
repository.uri = project.repository_http_location.uri
repository.use_default_credentials
+ repository.default_branch = project.default_branch
repository.clone
repository.configure_identity('GitLab QA', 'root@gitlab.com')
# These two commits add a total of 1mb, but half of that is the same as content that has already been added to
diff --git a/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb b/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb
index bfa408e1c92..60dace0938e 100644
--- a/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb
+++ b/qa/qa/specs/features/api/3_create/snippet/snippet_repository_storage_move_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Snippet repository storage', :requires_admin, :orchestrated, :repository_storage do
let(:source_storage) { { type: :gitaly, name: 'default' } }
let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.additional_repository_storage } }
diff --git a/qa/qa/specs/features/api/4_verify/api_variable_inheritance_with_forward_pipeline_variables_spec.rb b/qa/qa/specs/features/api/4_verify/api_variable_inheritance_with_forward_pipeline_variables_spec.rb
index 8ca0ae1f052..8890b3ff317 100644
--- a/qa/qa/specs/features/api/4_verify/api_variable_inheritance_with_forward_pipeline_variables_spec.rb
+++ b/qa/qa/specs/features/api/4_verify/api_variable_inheritance_with_forward_pipeline_variables_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Pipeline API defined variable inheritance' do
include_context 'variable inheritance test prep'
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 7c3fb9ebeba..a360c662cf8 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :requires_admin do
+ RSpec.describe 'Verify', :requires_admin, product_group: :pipeline_execution do
describe 'When user is blocked' do
let!(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user_api_client) { Runtime::API::Client.new(:gitlab, user: user) }
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 9722f62d5a7..4ae97f589cf 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
@@ -1,10 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner, feature_flag: {
- name: 'ci_stop_expanding_file_vars_for_runners',
- scope: :project
- } do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Pipeline with project file variables' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
@@ -14,7 +11,7 @@ module QA
end
end
- let(:runner) do
+ let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.project = project
runner.name = executor
@@ -60,59 +57,30 @@ module QA
end
end
- after do
- runner.remove_via_api!
+ before do
+ add_file_variables
+ add_ci_file
+ trigger_pipeline
+ wait_for_pipeline
end
- shared_examples 'variables are read correctly' do
- it 'shows in job log accordingly' do
- job = Resource::Job.fabricate_via_api! do |job|
- job.project = project
- job.id = project.job_by_name('test')[:id]
- end
-
- aggregate_failures do
- trace = job.trace
- expect(trace).to have_content('run something -f hello, this is test')
- expect(trace).to have_content('docker run --tlscacert="This is secret"')
- expect(trace).to have_content('run --output=This is secret.crt')
- expect(trace).to have_content('Will read private key from hello, this is test')
- end
- end
+ after do
+ runner.remove_via_api!
end
- # FF does not change current behavior
- # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94198#note_1057609893
- #
- # TODO: Remove when FF is removed
- # TODO: Archive testcase issue when FF is removed
- # Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/369907
- context 'when FF is on', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370787' do
- before do
- Runtime::Feature.enable(:ci_stop_expanding_file_vars_for_runners, project: project)
-
- runner
- add_file_variables
- add_ci_file
- trigger_pipeline
- wait_for_pipeline
+ it 'shows in job log accordingly', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370791' do
+ job = Resource::Job.fabricate_via_api! do |job|
+ job.project = project
+ job.id = project.job_by_name('test')[:id]
end
- it_behaves_like 'variables are read correctly'
- end
-
- # TODO: Refactor when FF is removed
- # TODO: Update testcase issue title and description to not refer to FF status
- context 'when FF is off', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370791' do
- before do
- runner
- add_file_variables
- add_ci_file
- trigger_pipeline
- wait_for_pipeline
+ aggregate_failures do
+ trace = job.trace
+ expect(trace).to have_content('run something -f hello, this is test')
+ expect(trace).to have_content('docker run --tlscacert="This is secret"')
+ expect(trace).to have_content('run --output=This is secret.crt')
+ expect(trace).to have_content('Will read private key from hello, this is test')
end
-
- it_behaves_like 'variables are read correctly'
end
private
diff --git a/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb b/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb
index 6e6198328e5..eb1b085c35c 100644
--- a/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb
+++ b/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :runner do
describe 'Runner removal' do
include Support::API
diff --git a/qa/qa/specs/features/api/5_package/container_registry_spec.rb b/qa/qa/specs/features/api/5_package/container_registry_spec.rb
index 8412c0b2872..0264b8b1ff2 100644
--- a/qa/qa/specs/features/api/5_package/container_registry_spec.rb
+++ b/qa/qa/specs/features/api/5_package/container_registry_spec.rb
@@ -3,7 +3,7 @@
require 'airborne'
module QA
- RSpec.describe 'Package', :reliable, only: { subdomain: %i[staging staging-canary pre] } do
+ RSpec.describe 'Package', :reliable, only: { subdomain: %i[staging staging-canary pre] }, product_group: :container_registry do
include Support::API
include Support::Helpers::MaskToken
diff --git a/qa/qa/specs/features/api/8_monitor/metrics_spec.rb b/qa/qa/specs/features/api/8_monitor/metrics_spec.rb
index 1235b996958..932d2a8e4f4 100644
--- a/qa/qa/specs/features/api/8_monitor/metrics_spec.rb
+++ b/qa/qa/specs/features/api/8_monitor/metrics_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'GitLab Metrics', :aggregate_failures, :orchestrated, :metrics do
+ RSpec.describe 'GitLab Metrics', :aggregate_failures, :orchestrated, :metrics, product_group: :observability do
let(:web_uri) { URI.parse(Runtime::Scenario.gitlab_address) }
let(:endpoint) do
"#{web_uri.scheme}://#{web_uri.host}:#{port}#{path}"
diff --git a/qa/qa/specs/features/browser_ui/14_analytics/performance_bar_spec.rb b/qa/qa/specs/features/browser_ui/14_analytics/performance_bar_spec.rb
index 867c54102ae..6dfc58fbfea 100644
--- a/qa/qa/specs/features/browser_ui/14_analytics/performance_bar_spec.rb
+++ b/qa/qa/specs/features/browser_ui/14_analytics/performance_bar_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Analytics' do
- describe 'Performance bar display', :requires_admin, :skip_live_env do
+ describe 'Performance bar display', :requires_admin, :skip_live_env, product_group: :product_analytics do
context 'when logged in as an admin user' do
# performance metrics: pg, gitaly, redis, rugged (feature flagged), total (not always provided)
let(:minimum_metrics_count) { 3 }
diff --git a/qa/qa/specs/features/browser_ui/14_analytics/service_ping_default_enabled_spec.rb b/qa/qa/specs/features/browser_ui/14_analytics/service_ping_default_enabled_spec.rb
index 7826aca3601..8e4b76cdb7c 100644
--- a/qa/qa/specs/features/browser_ui/14_analytics/service_ping_default_enabled_spec.rb
+++ b/qa/qa/specs/features/browser_ui/14_analytics/service_ping_default_enabled_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Analytics' do
- describe 'Service ping default enabled' do
+ describe 'Service ping default enabled', product_group: :product_intelligence do
context 'when using default enabled from gitlab.yml config', :requires_admin, except: { job: 'review-qa-*' } do
before do
Flow::Login.sign_in_as_admin
diff --git a/qa/qa/specs/features/browser_ui/14_analytics/service_ping_disabled_spec.rb b/qa/qa/specs/features/browser_ui/14_analytics/service_ping_disabled_spec.rb
index 8b30d6a7ad7..e25bba97288 100644
--- a/qa/qa/specs/features/browser_ui/14_analytics/service_ping_disabled_spec.rb
+++ b/qa/qa/specs/features/browser_ui/14_analytics/service_ping_disabled_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Analytics' do
+ RSpec.describe 'Analytics', product_group: :product_intelligence do
describe 'Service ping disabled', :orchestrated, :service_ping_disabled, :requires_admin do
context 'when disabled from gitlab.yml config' do
before do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/group_access_token_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/group_access_token_spec.rb
index 9f39d376baf..a35cde854a2 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/group_access_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/group_access_token_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Group access tokens' do
+ describe 'Group access tokens', product_group: :authentication_and_authorization do
let(:group_access_token) { QA::Resource::GroupAccessToken.fabricate_via_browser_ui! }
it(
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 f459c0c71eb..0f3d6a104a7 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage', :requires_admin, :skip_live_env, :reliable do
- describe '2FA' do
+ describe '2FA', product_group: :authentication_and_authorization do
let(:owner_user) do
Resource::User.fabricate_via_api! do |usr|
usr.api_client = admin_api_client
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb
index 6c69e4c59d9..9484f15f35d 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_ssh_recovery_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- context 'Manage', :reliable, :requires_admin, :skip_live_env do
+ context 'Manage', :reliable, :requires_admin, :skip_live_env, product_group: :authentication_and_authorization do
describe '2FA' do
let!(:user) { Resource::User.fabricate_via_api! }
let!(:user_api_client) { Runtime::API::Client.new(:gitlab, user: user) }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
index 98b5ecc8f0d..7b91156d926 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :smoke, :mobile do
+ RSpec.describe 'Manage', :smoke, :mobile, product_group: :authentication_and_authorization do
describe 'basic user login' do
it 'user logs in using basic credentials and logs out', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347880' do
Flow::Login.sign_in
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 56883917153..cf9282c1149 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 do
+ RSpec.describe 'Manage', :requires_admin, :skip_live_env, 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) }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
index 7ecad1101c9..3d2e8c13900 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :orchestrated, :ldap_no_tls, :ldap_tls do
+ RSpec.describe 'Manage', :orchestrated, :ldap_no_tls, :ldap_tls, product_group: :authentication_and_authorization do
describe 'LDAP login' do
it 'user logs into GitLab using LDAP credentials', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347892' do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
index 80e660c1c1d..388c9f6b486 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :orchestrated, :mattermost do
+ RSpec.describe 'Manage', :orchestrated, :mattermost, product_group: :authentication_and_authorization do
describe 'Mattermost login' do
it 'user logs into Mattermost using GitLab OAuth', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347891' do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb
index d6cb65c2788..ca10a3f3d65 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_instance_wide_saml_sso_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :orchestrated, :instance_saml do
+ RSpec.describe 'Manage', :orchestrated, :instance_saml, product_group: :authentication_and_authorization do
describe 'Instance wide SAML SSO' do
it(
'user logs in to gitlab with SAML SSO',
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb
index 1d30b915594..dd39b0c8835 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/maintain_log_in_mixed_env_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage', only: { subdomain: %i[staging staging-canary] }, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/344213', type: :stale } do
- describe 'basic user' do
+ describe 'basic user', product_group: :authentication_and_authorization do
it 'remains logged in when redirected from canary to non-canary node', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347626' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
index 295702aa328..e0242008785 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
@@ -13,7 +13,7 @@ module QA
end
end
- RSpec.describe 'Manage', :skip_signup_disabled, :requires_admin do
+ RSpec.describe 'Manage', :skip_signup_disabled, :requires_admin, product_group: :authentication_and_authorization do
describe 'while LDAP is enabled', :orchestrated, :ldap_no_tls, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347934' do
before do
# When LDAP is enabled, a previous test might have created a token for the LDAP 'tanuki' user who is not an admin
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
index 7c6b0d77219..686cc8fe11e 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
@@ -7,9 +7,6 @@ module QA
it 'creates a new project' do
Page::Project::Show.perform do |project_page|
expect(project_page).to have_content(project_name)
- expect(project_page).to have_content(
- /Project \S?#{project_name}\S+ was successfully created/
- )
expect(project_page).to have_content('The repository for this project is empty')
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
index 6ac11fea7e1..15563e3aa2a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
@@ -4,61 +4,89 @@ module QA
# Spec uses real github.com, which means outage of github can actually block deployment
# Keep spec in reliable bucket but don't run in blocking pipelines
RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do
- describe 'Project import' do
- let(:github_repo) { 'gitlab-qa-github/import-test' }
- let(:api_client) { Runtime::API::Client.as_admin }
- let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
- let(:user) do
- Resource::User.fabricate_via_api! do |resource|
- resource.api_client = api_client
- resource.hard_delete_on_api_removal = true
+ describe 'GitHub import' do
+ context 'when imported via UI' do
+ let(:github_repo) { 'gitlab-qa-github/import-test' }
+ let(:api_client) { Runtime::API::Client.as_admin }
+ let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
+ let(:user) do
+ Resource::User.fabricate_via_api! do |resource|
+ resource.api_client = api_client
+ resource.hard_delete_on_api_removal = true
+ end
end
- end
- let(:imported_project) do
- Resource::ProjectImportedFromGithub.init do |project|
- project.import = true
- project.group = group
- project.github_personal_access_token = Runtime::Env.github_access_token
- project.github_repository_path = github_repo
- project.api_client = api_client
+ let(:imported_project) do
+ Resource::ProjectImportedFromGithub.init do |project|
+ project.import = true
+ project.group = group
+ project.github_personal_access_token = Runtime::Env.github_access_token
+ project.github_repository_path = github_repo
+ project.api_client = api_client
+ end
end
- end
- before do
- group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
-
- Flow::Login.sign_in(as: user)
- Page::Main::Menu.perform(&:go_to_create_project)
- Page::Project::New.perform do |project_page|
- project_page.click_import_project
- project_page.click_github_link
+ let(:imported_issue) do
+ Resource::Issue.init do |resource|
+ resource.project = imported_project
+ resource.iid = imported_project.issues.first[:iid]
+ resource.api_client = api_client
+ end.reload!
end
- end
- after do
- user.remove_via_api!
- end
+ let(:imported_issue_events) do
+ imported_issue.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } }
+ end
- it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do
- Page::Project::Import::Github.perform do |import_page|
- import_page.add_personal_access_token(Runtime::Env.github_access_token)
- import_page.import!(github_repo, group.full_path, imported_project.name)
+ before do
+ group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
- aggregate_failures do
- expect(import_page).to have_imported_project(github_repo, wait: 240)
- # validate button is present instead of navigating to avoid dealing with multiple tabs
- # which makes the test more complicated
- expect(import_page).to have_go_to_project_button(github_repo)
+ Flow::Login.sign_in(as: user)
+ Page::Main::Menu.perform(&:go_to_create_project)
+ Page::Project::New.perform do |project_page|
+ project_page.click_import_project
+ project_page.click_github_link
end
end
- imported_project.reload!.visit!
- Page::Project::Show.perform do |project|
- aggregate_failures do
- expect(project).to have_content(imported_project.name)
- expect(project).to have_content('Project for github import test')
+ after do
+ user.remove_via_api!
+ end
+
+ it 'imports a project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do
+ Page::Project::Import::Github.perform do |import_page|
+ import_page.add_personal_access_token(Runtime::Env.github_access_token)
+
+ import_page.select_advanced_option(:single_endpoint_issue_events_import)
+ import_page.select_advanced_option(:single_endpoint_notes_import)
+ import_page.select_advanced_option(:attachments_import)
+
+ import_page.import!(github_repo, group.full_path, imported_project.name)
+
+ aggregate_failures do
+ expect(import_page).to have_imported_project(github_repo, wait: 240)
+ # validate button is present instead of navigating to avoid dealing with multiple tabs
+ # which makes the test more complicated
+ expect(import_page).to have_go_to_project_button(github_repo)
+ end
+ end
+
+ imported_project.reload!.visit!
+ Page::Project::Show.perform do |project|
+ aggregate_failures do
+ expect(project).to have_content(imported_project.name)
+ expect(project).to have_content('Project for github import test')
+ end
end
+
+ # Validate :single_endpoint_issue_events_import option was triggered correctly and imported the events
+ expect(imported_issue_events).to match_array(
+ [
+ { name: "add_label", label: "question" },
+ { name: "add_label", label: "good first issue" },
+ { name: "add_label", label: "help wanted" }
+ ]
+ )
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
index 63ae90aed9c..55f63845acd 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project access tokens', :reliable do
+ describe 'Project access tokens', :reliable, product_group: :authentication_and_authorization do
let(:project_access_token) { QA::Resource::ProjectAccessToken.fabricate_via_browser_ui! }
it(
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/impersonation_token_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/impersonation_token_spec.rb
index 5bcea1ff094..ce5d9307769 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/impersonation_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/impersonation_token_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Impersonation tokens', :requires_admin do
+ describe 'Impersonation tokens', :requires_admin, product_group: :authentication_and_authorization do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user) do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb
index 54f05f84dca..6bc695487ee 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb
@@ -12,11 +12,9 @@ module QA
end
let!(:group) do
- group = QA::Resource::Group.fabricate_via_api! do |group|
+ QA::Resource::Group.fabricate_via_api! do |group|
group.path = "group-to-test-access-termination-#{SecureRandom.hex(8)}"
end
- group.sandbox.add_member(user)
- group
end
let!(:project) do
@@ -27,24 +25,20 @@ module QA
end
end
- context 'for after parent group membership termination' do
+ context 'when parent group membership is terminated' do
before do
+ group.add_member(user)
+
Flow::Login.while_signed_in_as_admin do
- group.sandbox.visit!
+ group.visit!
- Page::Group::Menu.perform(&:click_group_members_item)
+ Page::Group::Menu.perform(&:click_subgroup_members_item)
Page::Group::Members.perform do |members_page|
members_page.remove_member(user.username)
end
end
end
- after do
- user.remove_via_api!
- project.remove_via_api!
- group.remove_via_api!
- end
-
it 'is not allowed to edit the project files',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347866' do
Flow::Login.sign_in(as: user)
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 b815186cd49..b70590e65c8 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :orchestrated, :smtp, :reliable do
+ RSpec.describe 'Plan', :orchestrated, :smtp, :reliable, product_group: :project_management do
describe 'Email Notification' do
include Support::API
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 1ba110a9602..2f177d12389 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
@@ -1,11 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
let!(:user) do
Resource::User.fabricate_via_api! do |user|
user.name = "QA User <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;"
- user.password = "test1234"
+ user.password = "pw_#{SecureRandom.hex(12)}"
user.api_client = Runtime::API::Client.as_admin
end
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
index 8e8112faa48..d446a773809 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/collapse_comments_in_discussions_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'collapse comments in issue discussions' do
let(:my_first_reply) { 'My first reply' }
let(:one_reply) { '1 reply' }
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 3b02093054d..f7dc9157275 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Issue comments' do
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index 7e4a391c390..45c3c264837 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -1,10 +1,19 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :smoke do
+ RSpec.describe 'Plan', :smoke, product_group: :project_management do
describe 'Issue creation' do
- let(:project) { Resource::Project.fabricate_via_api! }
- let(:closed_issue) { Resource::Issue.fabricate_via_api! { |issue| issue.project = project } }
+ let(:project) do
+ Resource::Project.fabricate_via_api_unless_fips! do |project|
+ project.name = "project-create-issue-#{SecureRandom.hex(8)}"
+ project.personal_namespace = Runtime::User.username
+ project.description = nil
+ end
+ end
+
+ let(:closed_issue) do
+ Resource::Issue.fabricate_via_api_unless_fips! { |issue| issue.project = project }
+ end
before do
Flow::Login.sign_in
@@ -55,7 +64,7 @@ module QA
end
before do
- Resource::Issue.fabricate_via_api! { |issue| issue.project = project }.visit!
+ Resource::Issue.fabricate_via_api_unless_fips! { |issue| issue.project = project }.visit!
end
# The following example is excluded from running in `review-qa-smoke` job
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 b2c612d38fe..bad312bb392 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Custom issue templates' do
let(:template_name) { 'custom_issue_template' }
let(:template_content) { 'This is a custom issue template test' }
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 e8c624e9554..61fd743f920 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Issues list' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
index d8fa7480f01..8af39cb6a82 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'filter issue comments activities' do
before do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
index 6bb338ae31f..45541939606 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'issue suggestions' do
let(:issue_title) { 'Issue Lists are awesome' }
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
index 96f5731ea65..36cfb9dfb6e 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :smoke do
+ RSpec.describe 'Plan', :smoke, product_group: :project_management do
describe 'mention' do
- let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
+ let(:user) do
+ 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|
+ Resource::Project.fabricate_via_api_unless_fips! do |project|
project.name = 'project-to-test-mention'
project.visibility = 'private'
end
@@ -14,14 +17,33 @@ module QA
before do
Flow::Login.sign_in
- project.add_member(user)
+ if QA::Support::FIPS.enabled?
+ # Ensure user exists
+ user
+ Flow::Login.sign_in_as_admin
+ project.visit!
+ Page::Project::Menu.perform(&:click_members)
+ Page::Project::Members.perform do |members|
+ members.add_member(user.username)
+ end
+ else
+ project.visit!
+ project.add_member(user)
+ end
- Resource::Issue.fabricate_via_api! do |issue|
- issue.project = project
- end.visit!
+ if QA::Support::FIPS.enabled?
+ Resource::Issue.fabricate_via_browser_ui! do |issue|
+ issue.project = project
+ end.visit!
+ else
+ Resource::Issue.fabricate_via_api! do |issue|
+ issue.project = project
+ end.visit!
+ end
end
- it 'mentions another user in an issue', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347988' do
+ it 'mentions another user in an issue',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347988' do
Page::Project::Issue::Show.perform do |show|
at_username = "@#{user.username}"
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 66e2309e173..060e52276a9 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan' do
+ RSpec.describe 'Plan', product_group: :project_management do
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) }
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 f116c690eec..83e178ae4c3 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ 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|
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 d6eab3c8dd0..56e110e6f61 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Milestones' do
include Support::Dates
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
index 22709e8fbc4..5febb6579df 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Group milestone' do
include Support::Dates
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb
index 8047f8aea4c..5b580a67f5b 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_project_milestone_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Project milestone' do
include Support::Dates
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 85011415177..197e283c93b 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
+ RSpec.describe 'Plan', :reliable, product_group: :project_management do
describe 'Related issues' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb
index a3fe1d655aa..878c4dea26e 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :transient do
+ RSpec.describe 'Plan', :transient, product_group: :project_management do
describe 'Discussion comments transient bugs' do
let(:user1) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
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 413c530116c..8f99644bd24 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Cherry picking from a merge request' 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'
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 d6e9c1a13df..111adf32a69 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Cherry picking a commit' do
+ describe 'Cherry picking a commit', product_group: :code_review do
let(:file_name) { "secret_file.md" }
let(:project) do
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 10d7e0b071f..509714fb5a4 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Create a new merge request from the event notification after a push' do
+ describe 'Create a new merge request from the event notification after a push', 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
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 25dec82b74c..1e08fc49066 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Create a new merge request' 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'
@@ -18,7 +18,7 @@ module QA
it(
'creates a basic merge request',
- :smoke,
+ :smoke, :skip_fips_env,
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347738'
) do
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
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 d975e18e962..1ce9430290f 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable do
+ RSpec.describe 'Create', :reliable, product_group: :code_review do
describe 'Merge request custom templates' do
let(:template_name) { 'custom_merge_request_template' }
let(:template_content) { 'This is a custom merge request template test' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
index 109cf7b73c3..d27ec32fdda 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request creation from fork' do
+ describe 'Merge request creation from fork', product_group: :code_review do
let(:merge_request) do
Resource::MergeRequestFromFork.fabricate_via_browser_ui! do |merge_request|
merge_request.fork_branch = 'feature-branch'
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 ac53357a86f..257021b158a 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :runner do
+ RSpec.describe 'Create', :runner, product_group: :code_review do
describe 'Merge requests' do
shared_examples 'merge when pipeline succeeds' do |repeat: 1|
let(:runner_name) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
index c7296b6eea2..330cae575e4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request rebasing' do
+ describe 'Merge request rebasing', product_group: :code_review do
let(:merge_request) { Resource::MergeRequest.fabricate_via_api! }
before do
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 205ff12ff03..a79c56bd051 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable do
+ RSpec.describe 'Create', :reliable, product_group: :code_review do
describe 'Reverting a commit' do
let(:file_name) { "secret_file.md" }
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 948aedf5aae..82e2136cd22 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merged merge request' do
+ describe 'Merged merge request', product_group: :code_review do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'revert'
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 fa129f39a4c..a127b846eb9 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request squashing' 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"
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 b20d0929e9c..829b7bab829 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable do
+ RSpec.describe 'Create', :reliable, product_group: :code_review do
context 'Add batch suggestions to a Merge Request' do
let(:project) do
Resource::Project.fabricate_via_api! do |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 aa637ac4d55..433ef90d9aa 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,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- context 'Add suggestions to a Merge Request' do
+ context 'Add suggestions to a Merge Request', product_group: :code_review do
let(:commit_message) { 'Applying suggested change for testing purposes.' }
let(:project) do
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 18aa6bfe78a..a969b48f0fc 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' do
+ describe 'Download merge request patch and diff', 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/pages/new_static_page_spec.rb b/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb
index 9c912080c5f..c35aa403bfa 100644
--- a/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
+
module QA
- RSpec.describe 'Create', :runner, only: { subdomain: :staging } do
+ RSpec.describe 'Create', :gitlab_pages, :orchestrated, except: { job: 'review-qa-*', subdomain: :production } do
# TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300906
- describe 'Pages' do
+ describe 'Pages', product_group: :editor do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'jekyll-pages-project'
@@ -21,7 +22,6 @@ module QA
before do
Flow::Login.sign_in
-
Resource::Runner.fabricate_via_api! do |runner|
runner.project = project
runner.executor = :docker
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb
index 37e737a4f84..feb0f28763c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Testing wiki content creation inside a project' do
let(:new_wiki_title) { "just_another_wiki_page" }
let(:new_wiki_content) { "this content is changed or added" }
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb
index a4bdb0193dd..dcac2ad3a9d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Testing wiki content manipulation inside a project' do
let(:new_wiki_title) { "just_another_wiki_page" }
let(:new_wiki_content) { "this content is changed or added" }
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb
index 0af964fc4bf..7edbb01a522 100644
--- a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'A project wiki' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:new_path) { "a/new/path-with-spaces" }
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb
index 361fc459d54..fbe662341c0 100644
--- a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable do
+ RSpec.describe 'Create', :reliable, product_group: :editor do
describe 'Testing project wiki file upload' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:page_title) { 'Content Editor Page' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb
index 5c9b97659a7..e0699bccff6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Project Wiki' do
let(:small_number_of_pages) { 5 }
let(:large_number_of_pages) { 15 }
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb
index 13e04180ab5..626f9a7d593 100644
--- a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Testing project wiki'
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
index 849022f5a93..866c6a146de 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
@@ -76,7 +76,7 @@ module QA
expect(branches_page).to have_no_branch(third_branch)
- branches_page.delete_merged_branches
+ branches_page.delete_merged_branches('delete')
expect(branches_page).to have_content(
'Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes.'
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
index a785e4ae764..0ec231ed66e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
@@ -2,8 +2,9 @@
module QA
RSpec.describe 'Create' do
- describe 'Git push over HTTP', :smoke, product_group: :source_code do
- it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347749' do
+ describe 'Git push over HTTP', :smoke, :skip_fips_env, product_group: :source_code do
+ it 'user using a personal access token pushes code to the repository',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347749' do
Flow::Login.sign_in
access_token = Resource::PersonalAccessToken.fabricate!.token
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 e8f7cb252a0..efa1f9fe2c9 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
@@ -3,7 +3,8 @@
module QA
RSpec.describe 'Create' do
describe 'Git push over HTTP', product_group: :source_code do
- it 'user pushes code to the repository', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347747' do
+ it 'user pushes code to the repository', :smoke, :skip_fips_env,
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347747' do
Flow::Login.sign_in
Resource::Repository::ProjectPush.fabricate! do |push|
@@ -18,7 +19,8 @@ module QA
end
end
- it 'pushes to a project using a specific Praefect repository storage', :smoke, :requires_admin, :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347789' do
+ it 'pushes to a project using a specific Praefect repository storage', :smoke, :skip_fips_env, :requires_admin,
+ :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|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
index 4fb52f1e54d..f281f441e8a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
@@ -26,7 +26,8 @@ module QA
Flow::Login.sign_in
end
- it 'pushes code to the repository via SSH', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347825' do
+ it 'pushes code to the repository via SSH', :smoke, :skip_fips_env,
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347825' do
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project
push.ssh_key = @key
@@ -41,7 +42,8 @@ module QA
end
end
- it 'pushes multiple branches and tags together', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347826' do
+ it 'pushes multiple branches and tags together', :smoke, :skip_fips_env,
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347826' do
branches = []
tags = []
Git::Repository.perform do |repository|
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb
index 1a7c64a363f..db180b729c8 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/add_comment_to_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Adding comments on snippets' do
let(:comment_author) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:comment_content) { 'Comment 123' }
@@ -23,11 +23,6 @@ module QA
Flow::Login.sign_in
end
- after do
- personal_snippet&.remove_via_api!
- project_snippet&.remove_via_api!
- end
-
shared_examples 'comments on snippets' do |snippet_type, testcase|
it "adds, edits, and deletes a comment on a #{snippet_type}", testcase: testcase do
send(snippet_type)
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb
index 8f05446ff70..20a4866baee 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/add_file_to_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Multiple file snippet' do
let(:personal_snippet) do
Resource::Snippet.fabricate_via_api! do |snippet|
@@ -23,11 +23,6 @@ module QA
Flow::Login.sign_in
end
- after do
- personal_snippet&.remove_via_api!
- project_snippet&.remove_via_api!
- end
-
shared_examples 'adding file to snippet' do |snippet_type, testcase|
it "adds second file to an existing #{snippet_type} to make it multi-file", testcase: testcase do
send(snippet_type).visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
index 8f22a28628f..833d3bd6126 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Version control for personal snippets' do
let(:new_file) { 'new_snippet_file' }
let(:changed_content) { 'changes' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
index 9a5fe44c927..a6bdac8c205 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Version control for project snippets' do
let(:new_file) { 'new_snippet_file' }
let(:changed_content) { 'changes' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb
index e4204776c46..1a614e538ea 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb
@@ -1,7 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable do
+ RSpec.describe 'Create', :reliable, product_group: :editor, quarantine: {
+ only: { subdomain: 'pre' },
+ type: :investigating,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/378697'
+ } do
describe 'Multiple file snippet' do
let(:first_file_content) { 'First file content' }
let(:second_file_content) { 'Second file content' }
@@ -54,11 +58,6 @@ module QA
Flow::Login.sign_in
end
- after do
- personal_snippet&.remove_via_api!
- project_snippet&.remove_via_api!
- end
-
shared_examples 'copying snippet file contents' do |snippet_type, testcase|
it "copies file contents of a multi-file #{snippet_type} to a comment and verifies them", testcase: testcase do
send(snippet_type).visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
index 620e6870b26..0e5fcea438d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :smoke do
+ RSpec.describe 'Create', :smoke, product_group: :editor do
describe 'Personal snippet creation' do
let(:snippet) do
Resource::Snippet.fabricate_via_browser_ui! do |snippet|
@@ -18,7 +18,12 @@ module QA
end
after do
- snippet.remove_via_api!
+ if QA::Support::FIPS.enabled?
+ snippet.visit!
+ Page::Dashboard::Snippet::Show.perform(&:click_delete_button)
+ else
+ snippet.remove_via_api!
+ end
end
it 'user creates a personal snippet', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347799' do
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
index 0560a5b125c..66376769419 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Multiple file snippet', :reliable do
+ describe 'Multiple file snippet', :reliable, product_group: :editor do
let(:snippet) do
Resource::Snippet.fabricate_via_browser_ui! do |snippet|
snippet.title = 'Personal snippet with multiple files'
@@ -22,10 +22,6 @@ module QA
Flow::Login.sign_in
end
- after do
- snippet.remove_via_api!
- end
-
it 'creates a personal snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347723' do
snippet
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
index 0f01a965e7b..0e10a9908f4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do # to be converted to a smoke test once proved to be stable
+ RSpec.describe 'Create', product_group: :editor do # to be converted to a smoke test once proved to be stable
describe 'Project snippet creation' do
let(:snippet) do
Resource::ProjectSnippet.fabricate_via_browser_ui! do |snippet|
@@ -17,10 +17,6 @@ module QA
Flow::Login.sign_in
end
- after do
- snippet.remove_via_api!
- end
-
it 'user creates a project snippet', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347798' do
snippet
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
index 77b3c4df7e1..3c94107950c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable do
+ RSpec.describe 'Create', :reliable, product_group: :editor do
describe 'Multiple file snippet' do
let(:snippet) do
Resource::ProjectSnippet.fabricate_via_browser_ui! do |snippet|
@@ -24,10 +24,6 @@ module QA
Flow::Login.sign_in
end
- after do
- snippet.remove_via_api!
- end
-
it 'creates a project snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347725' do
snippet
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb
index e9339342386..906ac6e09b7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/delete_file_from_snippet_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Multiple file snippet', :reliable do
+ describe 'Multiple file snippet', :reliable, product_group: :editor do
let(:personal_snippet) do
Resource::Snippet.fabricate_via_api! do |snippet|
snippet.title = 'Personal snippet to delete file from'
@@ -31,11 +31,6 @@ module QA
Flow::Login.sign_in
end
- after do
- personal_snippet&.remove_via_api!
- project_snippet&.remove_via_api!
- end
-
shared_examples 'deleting file from snippet' do |snippet_type, testcase|
it "deletes second file from an existing #{snippet_type} to make it single-file", testcase: testcase do
send(snippet_type).visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb
index 182a21a9377..b58b487531e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/share_snippet_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Sharing snippets', :reliable do
+ describe 'Sharing snippets', :reliable, product_group: :editor do
let(:snippet) do
Resource::Snippet.fabricate! do |snippet|
snippet.title = 'Shared snippet'
@@ -16,10 +16,6 @@ module QA
Flow::Login.sign_in
end
- after do
- snippet&.remove_via_api!
- end
-
context 'when the snippet is public' do
it 'can be shared with not signed-in users', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347836' do
snippet.visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb
index 97e42edfd01..63e9fdbb881 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Snippet index page' do
let(:personal_snippet_with_single_file) do
Resource::Snippet.fabricate_via_api! do |snippet|
@@ -49,13 +49,6 @@ module QA
Flow::Login.sign_in
end
- after do
- personal_snippet_with_single_file.remove_via_api!
- personal_snippet_with_multiple_files.remove_via_api!
- project_snippet_with_single_file.remove_via_api!
- project_snippet_with_multiple_files.remove_via_api!
- end
-
shared_examples 'displaying details on index page' do |snippet_type, testcase|
it "shows correct details of #{snippet_type} including file number", testcase: testcase do
send(snippet_type)
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 f95f624d59a..b8617de2e47 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
@@ -2,7 +2,7 @@
# tagged transient due to feature-flag caching flakiness. Remove tag along with feature flag removal.
module QA
RSpec.describe 'Create', feature_flag: { name: 'source_editor_toolbar', scope: :global } do
- describe 'Source editor toolbar preview' do
+ describe 'Source editor toolbar preview', product_group: :editor do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'empty-project-with-md'
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
index 19dd868744f..8ea65e17e13 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Web IDE file templates' do
include Runtime::Fixtures
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 561a5a2cc1c..1da9ed652fe 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Add a directory in Web IDE' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
index 948417458fc..1dfda1608f4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'First file using Web IDE' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
index 9c1d327f02c..56cf2a08bd9 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
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
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
index 046327f780b..820b47a3175 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Open a fork in Web IDE',
skip: {
issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/351696",
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
index f03c651992c..685cd2d4ad6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Open Web IDE from Diff Tab' do
files = [
{
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
index bd19d70ae5c..e4f29952f99 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/381530', type: :stale } do
describe 'Review a merge request in Web IDE' do
let(:new_file) { 'awesome_new_file.txt' }
let(:original_text) { 'Text' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb
index ac2d374b0ed..0972e4f3e3d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' } do
+ RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' }, product_group: :editor do
describe 'Git Server Hooks' do
let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', 'README.md')) }
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 3d9d5695d06..c0f65416a1c 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Upload a file in Web IDE' do
let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', file_name)) }
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
index 09459057992..f90676ee15a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
@@ -9,7 +9,8 @@ module QA
quarantine: {
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338179',
type: :bug
- }
+ },
+ product_group: :editor
) do
describe 'Web IDE web terminal' do
before do
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
index fa8d0d1501c..aec0da99a5c 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
@@ -2,9 +2,9 @@
module QA
RSpec.describe 'Verify' do
- describe 'Add or Remove CI variable via UI', :smoke do
+ describe 'Add or Remove CI variable via UI', :smoke, product_group: :pipeline_authoring do
let(:project) do
- Resource::Project.fabricate_via_api! do |project|
+ Resource::Project.fabricate_via_api_unless_fips! do |project|
project.name = 'project-with-ci-variables'
project.description = 'project with CI variables'
end
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 63801536c34..4a0a8be3659 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
@@ -2,7 +2,10 @@
module QA
RSpec.describe 'Verify', :runner do
- describe 'Pipeline with customizable variable' do
+ describe 'Pipeline with customizable variable', feature_flag: {
+ name: :run_pipeline_graphql,
+ scope: :project
+ } do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:pipeline_job_name) { 'customizable-variable' }
let(:variable_custom_value) { 'Custom Foo' }
@@ -45,43 +48,74 @@ module QA
end
end
- before do
- Flow::Login.sign_in
- project.visit!
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
- Page::Project::Pipeline::Index.perform do |index|
- index.click_run_pipeline_button
+ shared_examples 'pipeline with custom variable' do
+ before do
+ Flow::Login.sign_in
+
+ project.visit!
+ Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
+
+ # Sometimes the variables will not be prefilled because of reactive cache so we revisit the page again.
+ # TODO: Investigate alternatives to deal with cache implementation
+ # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/381233
+ page.refresh
end
- end
- after do
- [runner, project].each(&:remove_via_api!)
+ after do
+ runner&.remove_via_api!
+ end
+
+ it 'manually creates a pipeline and uses the defined custom variable value' do
+ Page::Project::Pipeline::New.perform do |new|
+ new.configure_variable(value: variable_custom_value)
+ new.click_run_pipeline_button
+ end
+
+ Page::Project::Pipeline::Show.perform do |show|
+ Support::Waiter.wait_until { show.passed? }
+ end
+
+ job = Resource::Job.fabricate_via_api! do |job|
+ job.id = project.job_by_name(pipeline_job_name)[:id]
+ job.name = pipeline_job_name
+ job.project = project
+ end
+
+ job.visit!
+
+ Page::Project::Job::Show.perform do |show|
+ expect(show.output).to have_content(variable_custom_value)
+ end
+ end
end
- it(
- 'manually creates a pipeline and uses the defined custom variable value',
+ # TODO: Clean up tests when run_pipeline_graphql is enabled
+ # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/372310
+ context(
+ 'with feature flag disabled',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/361814'
) do
- Page::Project::Pipeline::New.perform do |new|
- new.configure_variable(value: variable_custom_value)
- new.click_run_pipeline_button
+ before do
+ Runtime::Feature.disable(:run_pipeline_graphql, project: project)
end
- Page::Project::Pipeline::Show.perform do |show|
- Support::Waiter.wait_until { show.passed? }
- end
+ it_behaves_like 'pipeline with custom variable'
+ end
- job = Resource::Job.fabricate_via_api! do |job|
- job.id = project.job_by_name(pipeline_job_name)[:id]
- job.name = pipeline_job_name
- job.project = project
+ context(
+ 'with feature flag enabled',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/378975'
+ ) do
+ before do
+ Runtime::Feature.enable(:run_pipeline_graphql, project: project)
end
- job.visit!
-
- Page::Project::Job::Show.perform do |show|
- expect(show.output).to have_content(variable_custom_value)
+ after do
+ Runtime::Feature.disable(:run_pipeline_graphql, project: project)
end
+
+ it_behaves_like 'pipeline with custom variable'
end
end
end
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 5bb60e64da5..48d6ed8dc49 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
@@ -1,10 +1,10 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Pipeline with protected variable' do
- let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
- let(:protected_value) { Faker::Alphanumeric.alphanumeric(8) }
+ 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|
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 8352ad6aa33..c4ce916d47d 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
@@ -2,7 +2,10 @@
module QA
RSpec.describe 'Verify' do
- describe 'Pipeline with prefill variables' do
+ describe 'Pipeline with prefill variables', feature_flag: {
+ name: :run_pipeline_graphql,
+ scope: :project
+ } do
let(:prefill_variable_description1) { Faker::Lorem.sentence }
let(:prefill_variable_value1) { Faker::Lorem.word }
let(:prefill_variable_description2) { Faker::Lorem.sentence }
@@ -40,32 +43,62 @@ module QA
end
end
- before do
- Flow::Login.sign_in
- project.visit!
+ shared_examples 'pre-filled variables form' do
+ before do
+ Flow::Login.sign_in
- # Navigate to Run Pipeline page
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
- Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
+ project.visit!
+ # Navigate to Run Pipeline page
+ Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
+
+ # Sometimes the variables will not be prefilled because of reactive cache so we revisit the page again.
+ # TODO: Investigate alternatives to deal with cache implementation
+ # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/381233
+ page.refresh
+ end
+
+ it 'shows only variables with description as prefill variables on the run pipeline page' do
+ Page::Project::Pipeline::New.perform do |new|
+ aggregate_failures do
+ expect(new).to have_field('Input variable key', with: 'TEST1')
+ expect(new).to have_field('Input variable value', with: prefill_variable_value1)
+ expect(new).to have_content(prefill_variable_description1)
+
+ expect(new).to have_field('Input variable key', with: 'TEST2')
+ expect(new).to have_content(prefill_variable_description2)
+
+ expect(new).not_to have_field('Input variable key', with: 'TEST3')
+ expect(new).not_to have_field('Input variable key', with: 'TEST4')
+ end
+ end
+ end
end
- it(
- 'shows only variables with description as prefill variables on the run pipeline page',
+ # TODO: Clean up tests when run_pipeline_graphql is enabled
+ # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/372310
+ context(
+ 'with feature flag disabled',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/371204'
) do
- Page::Project::Pipeline::New.perform do |new|
- aggregate_failures do
- expect(new).to have_field('Input variable key', with: 'TEST1')
- expect(new).to have_field('Input variable value', with: prefill_variable_value1)
- expect(new).to have_content(prefill_variable_description1)
+ before do
+ Runtime::Feature.disable(:run_pipeline_graphql, project: project)
+ end
- expect(new).to have_field('Input variable key', with: 'TEST2')
- expect(new).to have_content(prefill_variable_description2)
+ it_behaves_like 'pre-filled variables form'
+ end
- expect(new).not_to have_field('Input variable key', with: 'TEST3')
- expect(new).not_to have_field('Input variable key', with: 'TEST4')
- end
+ context 'with feature flag enabled',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/378977' do
+ before do
+ Runtime::Feature.enable(:run_pipeline_graphql, project: project)
end
+
+ after do
+ Runtime::Feature.disable(:run_pipeline_graphql, project: project)
+ end
+
+ it_behaves_like 'pre-filled variables form'
end
end
end
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
new file mode 100644
index 00000000000..fe934e8c60f
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/raw_variables_defined_in_yaml_spec.rb
@@ -0,0 +1,148 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Verify', :runner do
+ describe 'Pipeline with raw variables in YAML', product_group: :pipeline_authoring, feature_flag: {
+ name: 'ci_raw_variables_in_yaml_config',
+ scope: :project
+ } 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!(:runner) do
+ Resource::Runner.fabricate! do |runner|
+ runner.project = project
+ runner.name = executor
+ runner.tags = [executor]
+ end
+ end
+
+ let(:commit_ci_file) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ variables:
+ VAR7:
+ value: "value 7 $CI_PIPELINE_ID"
+ expand: false
+ VAR8:
+ value: "value 8 $CI_PIPELINE_ID"
+ expand: false
+
+ #{pipeline_job_name}:
+ tags:
+ - #{executor}
+ script:
+ - echo "VAR1 is $VAR1"
+ - echo "VAR2 is $VAR2"
+ - echo "VAR3 is $VAR3"
+ - echo "VAR4 is $VAR4"
+ - echo "VAR5 is $VAR5"
+ - echo "VAR6 is $VAR6"
+ - echo "VAR7 is $VAR7"
+ - echo "VAR8 is $VAR8"
+ variables:
+ VAR1: "JOBID-$CI_JOB_ID"
+ VAR2: "PIPELINEID-$CI_PIPELINE_ID and $VAR1"
+ VAR3:
+ value: "PIPELINEID-$CI_PIPELINE_ID and $VAR1"
+ expand: false
+ VAR4:
+ value: "JOBID-$CI_JOB_ID"
+ expand: false
+ VAR5: "PIPELINEID-$CI_PIPELINE_ID and $VAR4"
+ VAR6:
+ value: "PIPELINEID-$CI_PIPELINE_ID and $VAR4"
+ expand: false
+ VAR7: "overridden value 7 $CI_PIPELINE_ID"
+ YAML
+ }
+ ]
+ )
+ end
+ end
+
+ let(:pipeline_id) { project.pipelines.first[:id] }
+ let(:job_id) { project.job_by_name(pipeline_job_name)[:id] }
+
+ def before_do
+ # TODO: Switch to use `let!` and remove this line when removing FF
+ commit_ci_file
+
+ Flow::Login.sign_in
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline(status: 'passed')
+ Page::Project::Pipeline::Show.perform do |show|
+ show.click_job(pipeline_job_name)
+ end
+ end
+
+ after do
+ runner&.remove_via_api!
+ end
+
+ context 'when FF is on', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/381487' do
+ before do
+ Runtime::Feature.enable(:ci_raw_variables_in_yaml_config, project: project)
+ sleep 60
+
+ before_do
+ end
+
+ it 'expands variables according to expand: true/false', :aggregate_failures do
+ Page::Project::Job::Show.perform do |show|
+ expect(show.output).to have_content("VAR1 is JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR2 is PIPELINEID-#{pipeline_id} and JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR3 is PIPELINEID-$CI_PIPELINE_ID and $VAR1")
+ expect(show.output).to have_content("VAR4 is JOBID-$CI_JOB_ID")
+ expect(show.output).to have_content("VAR5 is PIPELINEID-#{pipeline_id} and JOBID-$CI_JOB_ID")
+ expect(show.output).to have_content("VAR6 is PIPELINEID-$CI_PIPELINE_ID and $VAR4")
+ expect(show.output).to have_content("VAR7 is overridden value 7 #{pipeline_id}")
+ expect(show.output).to have_content("VAR8 is value 8 $CI_PIPELINE_ID")
+ end
+ end
+ end
+
+ # TODO: Remove this context when FF :ci_raw_variables_in_yaml_config is removed
+ # Also archive testcase and close related issue
+ context 'when FF is off',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/381486',
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/381806',
+ only: { pipeline: %w[staging staging-canary] },
+ type: :waiting_on
+ } do
+ before do
+ Runtime::Feature.disable(:ci_raw_variables_in_yaml_config, project: project)
+ sleep 60
+
+ before_do
+ end
+
+ it 'expands all variables', :aggregate_failures do
+ Page::Project::Job::Show.perform do |show|
+ expect(show.output).to have_content("VAR1 is JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR2 is PIPELINEID-#{pipeline_id} and JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR3 is PIPELINEID-#{pipeline_id} and JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR4 is JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR5 is PIPELINEID-#{pipeline_id} and JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR6 is PIPELINEID-#{pipeline_id} and JOBID-#{job_id}")
+ expect(show.output).to have_content("VAR7 is overridden value 7 #{pipeline_id}")
+ expect(show.output).to have_content("VAR8 is value 8 #{pipeline_id}")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb
index 7782c0240e9..a5ebd4004d2 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_inheritable_when_forward_pipeline_variables_true_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'UI defined variable' do
include_context 'variable inheritance test prep'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb
index 69a99483b38..f53454b801c 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/ui_variable_non_inheritable_when_forward_pipeline_variables_false_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'UI defined variable' do
include_context 'variable inheritance test prep'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
index 1bba5355790..b6270c11ef6 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :smoke, :runner, quarantine: {
+ RSpec.describe 'Verify', :smoke, :runner, product_group: :pipeline_execution, quarantine: {
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/356295',
type: :investigating
} do
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 b9b87ed29bb..027383550a7 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Include local config file paths with wildcard', :reliable 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'
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 2fa6b9179ef..d773d0f36d0 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
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Include multiple files from a project' do
- let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
+ let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:expected_text) { Faker::Lorem.sentence }
let(:unexpected_text) { Faker::Lorem.sentence }
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
index 3356d1274c8..ba1363d79c5 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner, :requires_admin do
+ RSpec.describe 'Verify', :runner, :requires_admin, product_group: :pipeline_insights do
describe 'Artifacts' do
context 'when locked' do
let(:file_name) { 'artifact.txt' }
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 d201627218e..34f548a0e69 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
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_execution do
context 'When pipeline is blocked' do
- let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
+ let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb
index 65561bbba29..e876bf3ab8b 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/mr_event_rule_pipeline_spec.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
context 'When job is configured to only run on merge_request_events' do
let(:mr_only_job_name) { 'mr_only_job' }
let(:non_mr_only_job_name) { 'non_mr_only_job' }
- let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
+ let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:project) do
Resource::Project.fabricate_via_api! do |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 9e3c29db9e7..a7ca7b82d1e 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner, :reliable do
+ 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|
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 bbcc71bade7..fca34fc1f8e 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
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) }
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb
index ac91a9dd2d3..30c71bc590c 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_branch_switcher_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Pipeline editor' do
+ describe 'Pipeline editor', product_group: :pipeline_authoring do
let(:random_test_string) { SecureRandom.hex(10) }
let(:project) do
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 931bb97ba32..1f7871b0900 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Pipeline editor' do
+ describe 'Pipeline editor', product_group: :pipeline_authoring do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pipeline-editor-project'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb
index bef15b46fcd..dbe24e2a2b2 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Pipeline editor', :reliable do
+ describe 'Pipeline editor', :reliable, product_group: :pipeline_authoring do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pipeline-editor-project'
@@ -36,6 +36,15 @@ module QA
end
end
+ let(:invalid_content) do
+ <<~YAML
+
+ job3:
+ stage: stage_foo
+ script: echo 'Done.'
+ YAML
+ end
+
before do
# Make sure a pipeline is created before visiting pipeline editor page.
# Otherwise, test might timeout before the page finishing fetching pipeline status.
@@ -80,7 +89,7 @@ module QA
invalid_msg = 'syntax is invalid'
Page::Project::PipelineEditor::Show.perform do |show|
- show.write_to_editor(SecureRandom.hex(10))
+ show.write_to_editor(invalid_content)
aggregate_failures do
show.go_to_visualize_tab
@@ -90,8 +99,14 @@ module QA
show.simulate_pipeline
expect(show.tab_alert_title).to have_content('Pipeline simulation completed with errors')
+ expect(show.ci_syntax_validate_message).to have_content('CI configuration is invalid')
+
show.go_to_view_merged_yaml_tab
- expect(show.tab_alert_message).to have_content(invalid_msg)
+
+ # TODO: remove this retry when
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/378536 is resolved
+ show.retry_until(max_attempts: 2, reload: true, sleep_interval: 1) { show.has_no_alert? }
+ expect(show).to have_source_editor
expect(show.ci_syntax_validate_message).to have_content('CI configuration is invalid')
end
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 f9113573295..b1ecce297c9 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
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('-')}" }
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 f36593218a9..e8ec01577b1 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Run pipeline', :reliable do
+ describe 'Run pipeline', :reliable, product_group: :pipeline_execution do
context 'with web only rule' do
let(:job_name) { 'test_job' }
let(:project) do
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 fb7e3a8437f..4223caaafef 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_execution do
describe 'Run pipeline with manual jobs' do
let(:executor) { "qa-runner-#{SecureRandom.hex(4)}" }
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 1c75beebb48..c1d996df925 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
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_execution do
describe "Trigger child pipeline with 'when:manual'" do
- let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
+ let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:project) do
Resource::Project.fabricate_via_api! do |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 205b4d1168a..83283c5d8e3 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
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_authoring do
describe 'Trigger matrix' do
- let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
+ let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
let(:project) do
Resource::Project.fabricate_via_api! do |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 d34df17c477..1f49c7a3663 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Update CI file with pipeline editor' do
+ describe 'Update CI file with pipeline editor', product_group: :pipeline_authoring do
let(:random_test_string) { SecureRandom.hex(10) }
let(:project) do
diff --git a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
index f8261bba342..24c49be13bb 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :runner do
describe 'Runner registration' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let!(:runner) do
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 adcf91a550c..0166c53ffd5 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
@@ -9,7 +9,7 @@ module QA
# pipeline created (Sidekiq read/write) ->
# runner picks up pipeline (API read/write) ->
# User views pipeline succeeds (Web read)
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_insights do
context 'Endpoint Coverage' do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb
index 122fb0fc1a0..2a4852a2b8b 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/testing/view_code_coverage_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_insights do
describe 'Code coverage statistics' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:runner) do
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
index fca14a55468..c57a5c27dd2 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :skip_live_env do
+ RSpec.describe 'Package', :orchestrated, :skip_live_env, product_group: :container_registry do
describe 'Self-managed Container Registry' do
include Support::Helpers::MaskToken
@@ -174,7 +174,7 @@ module QA
Page::Project::Registry::Show.perform do |registry|
expect(registry).to have_registry_repository(project.name)
- registry.click_on_image(project.path_with_namespace)
+ registry.click_on_image(project.name)
expect(registry).to have_tag('master')
end
end
@@ -232,7 +232,7 @@ module QA
Page::Project::Registry::Show.perform do |registry|
expect(registry).to have_registry_repository(project.name)
- registry.click_on_image(project.path_with_namespace)
+ registry.click_on_image(project.name)
expect(registry).to have_tag('master')
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb
index 5a29b44e8b3..680b722edb7 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Package' do
- describe 'Container Registry', only: { subdomain: %i[staging staging-canary pre] } do
+ describe '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'
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb
index 56e3ec82388..bf328a2bced 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package' do
+ RSpec.describe 'Package', product_group: :container_registry do
describe 'Container Registry Online Garbage Collection', :registry_gc, only: { subdomain: %i[pre] } do
let(:group) { Resource::Group.fabricate_via_api! }
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 ad820977747..978867d5cf1 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :registry, only: { pipeline: :main } do
+ RSpec.describe 'Package', :orchestrated, :registry, only: { pipeline: :main }, product_group: :container_registry do
describe 'Dependency Proxy' do
using RSpec::Parameterized::TableSyntax
include Support::Helpers::MaskToken
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 6ce395affc7..a80e154a969 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages do
+ RSpec.describe 'Package', :orchestrated, :packages, product_group: :package_registry do
describe 'Terraform Module Registry' do
include Runtime::Fixtures
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 d5ef9dce10d..ab4fb21f19a 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,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage, product_group: :package_registry do
describe 'Composer Repository' do
include Runtime::Fixtures
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 1840ae4e7f8..687d9f710fb 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,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage, quarantine: {
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage, product_group: :package_registry, quarantine: {
only: { job: 'object_storage' },
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/335981',
type: :bug
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 677b8970a75..820571593a6 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,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable do
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable, product_group: :package_registry do
describe 'Generic Repository' do
include Runtime::Fixtures
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 222d1993bf4..4c15b7c7f99 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage, product_group: :package_registry do
describe 'Helm Registry' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
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 690451f6147..aac8893ff2c 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable do
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage, :reliable, product_group: :package_registry do
describe 'Maven group level endpoint' do
include Runtime::Fixtures
include_context 'packages registry qa scenario'
@@ -131,7 +131,7 @@ module QA
Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled)
end
- it 'prevents users from publishing duplicates' do
+ it 'prevents users from publishing duplicates', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/377491' do
create_duplicated_package
push_duplicated_package
@@ -151,7 +151,7 @@ module QA
Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
end
- it 'allows users to publish duplicates' do
+ it 'allows users to publish duplicates', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/377492' do
create_duplicated_package
push_duplicated_package
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 324e881f160..8e1b0176f35 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,12 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable,
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage, :reliable,
feature_flag: {
name: 'maven_central_request_forwarding',
scope: :global
} do
- describe 'Maven project level endpoint' do
+ describe 'Maven project level endpoint', product_group: :package_registry do
include Runtime::Fixtures
let(:group_id) { 'com.gitlab.qa' }
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 22052aa4110..a9d66c93fac 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,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage, product_group: :package_registry do
describe 'Maven Repository with Gradle' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
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 124e7743728..e209fc55e35 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,7 +2,7 @@
module QA
RSpec.describe 'Package' do
- describe 'Package Registry', :orchestrated, :reliable, :packages, :object_storage do
+ describe 'Package Registry', :skip_live_env, :orchestrated, :reliable, :packages, :object_storage, product_group: :package_registry do
describe 'npm instance level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
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 59324c7338a..d1aaa05c85a 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,7 +2,7 @@
module QA
RSpec.describe 'Package' do
- describe 'Package Registry', :orchestrated, :reliable, :packages, :object_storage do
+ describe 'Package Registry', :skip_live_env, :orchestrated, :reliable, :packages, :object_storage, product_group: :package_registry do
describe 'npm project level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
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 e2a7006249d..d44bc8fa2ad 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,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable do
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage, :reliable, product_group: :package_registry do
describe 'NuGet group level endpoint' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
@@ -133,14 +133,14 @@ module QA
{
file_path: 'otherdotnet.csproj',
content: <<~EOF
- <Project Sdk="Microsoft.NET.Sdk">
+ <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
- </PropertyGroup>
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
- </Project>
+ </Project>
EOF
}
]
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 620bb7e4988..442deb1eb4e 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,7 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage,
+product_group: :package_registry do
describe 'NuGet project level endpoint' do
include Support::Helpers::MaskToken
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 012a03ca115..fddb7fb6ebc 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ RSpec.describe 'Package', :skip_live_env, :orchestrated, :packages, :object_storage, product_group: :package_registry do
describe 'PyPI Repository' do
include Runtime::Fixtures
include Support::Helpers::MaskToken
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 409a1c10943..63ab826e57b 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
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Package', :orchestrated, :packages, :object_storage,
feature_flag: { name: 'rubygem_packages', scope: :project } do
- describe 'RubyGems Repository' do
+ describe 'RubyGems Repository', product_group: :package_registry do
include Runtime::Fixtures
let(:project) do
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
index 8b7b827de91..05dfc0c572e 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Release' do
+ RSpec.describe 'Release', product_group: :release do
describe 'Deploy key creation' do
it 'user adds a deploy key', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348023' do
Flow::Login.sign_in
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 1f5a431938c..3f91d120fdd 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
@@ -3,7 +3,7 @@
require 'digest/sha1'
module QA
- RSpec.describe 'Release', :runner do
+ RSpec.describe 'Release', :runner, product_group: :release do
describe 'Git clone using a deploy key' do
let(:runner_name) { "qa-runner-#{SecureRandom.hex(4)}" }
let(:repository_location) { project.repository_ssh_location }
@@ -35,7 +35,7 @@ module QA
keys = [
['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348022', Runtime::Key::RSA, 8192, true],
['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348021', Runtime::Key::ECDSA, 521, true],
- ['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348020', Runtime::Key::ED25519, false]
+ ['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348020', Runtime::Key::ED25519, 256, false]
]
supported_keys =
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb
index 9811453605e..b0b1fa2b68d 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Release' do
+ RSpec.describe 'Release', product_group: :release do
describe 'Deploy token creation' do
it 'user adds a deploy token', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348028' do
Flow::Login.sign_in
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 608dd7e089f..42a64099a3d 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Configure' do
- describe 'AutoDevOps Templates', only: { subdomain: %i[staging staging-canary] } do
+ describe 'AutoDevOps Templates', only: { subdomain: %i[staging staging-canary] }, product_group: :configure do
using RSpec::Parameterized::TableSyntax
# specify jobs to be disabled in the pipeline.
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 b839855c500..057b4c15db1 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
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Configure', only: { subdomain: %i[staging staging-canary] } do
+ RSpec.describe 'Configure', only: { subdomain: %i[staging staging-canary] }, product_group: :configure do
describe 'Auto DevOps with a Kubernetes Agent' do
let!(:app_project) do
Resource::Project.fabricate_via_api! do |project|
@@ -98,7 +98,7 @@ module QA
content: <<~YAML
ci_access:
projects:
- - id: #{project.path_with_namespace}
+ - id: #{project.path_with_namespace}
YAML
}
]
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
new file mode 100644
index 00000000000..0a0c2a4a6df
--- /dev/null
+++ b/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.shared_context "with github import", :github, :skip_live_env, :requires_admin, quarantine: {
+ type: :broken,
+ issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/382166"
+ } do
+ 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
+ end
+
+ let!(:user) do
+ Resource::User.fabricate_via_api! do |resource|
+ resource.api_client = api_client
+ resource.hard_delete_on_api_removal = true
+ end
+ end
+
+ let!(:user_api_client) { Runtime::API::Client.new(user: user) }
+
+ let(:imported_project) do
+ Resource::ProjectImportedFromGithub.fabricate_via_api! do |project|
+ project.name = 'imported-project'
+ project.group = group
+ project.github_personal_access_token = Runtime::Env.github_access_token
+ project.github_repository_path = 'gitlab-qa-github/import-test'
+ project.api_client = user_api_client
+ project.issue_events_import = true
+ project.full_notes_import = true
+ end
+ end
+
+ before do
+ group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
+ end
+
+ after do
+ user.remove_via_api!
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb b/qa/qa/specs/features/shared_contexts/import/gitlab_project_migration_common.rb
index 9c80c088917..9c80c088917 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
+++ b/qa/qa/specs/features/shared_contexts/import/gitlab_project_migration_common.rb
diff --git a/qa/qa/specs/helpers/context_selector.rb b/qa/qa/specs/helpers/context_selector.rb
index 3608fa7c581..caa5ace430f 100644
--- a/qa/qa/specs/helpers/context_selector.rb
+++ b/qa/qa/specs/helpers/context_selector.rb
@@ -18,6 +18,7 @@ module QA
def context_matches?(*options)
return false unless Runtime::Scenario.attributes[:gitlab_address]
+ return false if Runtime::Scenario.attributes[:test_metadata_only]
opts = {}
opts[:domain] = '.+'
diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb
index c46b6300200..4eb799f34c1 100644
--- a/qa/qa/specs/runner.rb
+++ b/qa/qa/specs/runner.rb
@@ -23,6 +23,8 @@ module QA
def rspec_tags
tags_for_rspec = []
+ return tags_for_rspec if Runtime::Scenario.attributes[:test_metadata_only]
+
if tags.any?
tags.each { |tag| tags_for_rspec.push(['--tag', tag.to_s]) }
else
diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb
index 97901042883..a4721040683 100644
--- a/qa/qa/specs/spec_helper.rb
+++ b/qa/qa/specs/spec_helper.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require_relative '../../qa'
+require 'active_support/testing/time_helpers'
QA::Specs::QaDeprecationToolkitEnv.configure!
@@ -14,20 +15,18 @@ QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
# Enable zero monkey patching mode before loading any other RSpec code.
RSpec.configure(&:disable_monkey_patching!)
-Dir[::File.join(__dir__, "features/shared_examples/*.rb")].sort.each { |f| require f }
-Dir[::File.join(__dir__, "features/shared_contexts/*.rb")].sort.each { |f| require f }
-
# For JH additionally process when `jh/` exists
require_relative('../../../jh/qa/qa/specs/spec_helper') if GitlabEdition.jh?
RSpec.configure do |config|
+ config.include ActiveSupport::Testing::TimeHelpers
config.include QA::Support::Matchers::EventuallyMatcher
config.include QA::Support::Matchers::HaveMatcher
config.add_formatter QA::Support::Formatters::ContextFormatter
config.add_formatter QA::Support::Formatters::QuarantineFormatter
config.add_formatter QA::Support::Formatters::FeatureFlagFormatter
- config.add_formatter QA::Support::Formatters::TestStatsFormatter if QA::Runtime::Env.export_metrics?
+ config.add_formatter QA::Support::Formatters::TestMetricsFormatter if QA::Runtime::Env.running_in_ci?
config.before(:suite) do |suite|
QA::Resource::ReusableCollection.register_resource_classes do |collection|
@@ -149,3 +148,6 @@ RSpec.configure do |config|
end
end
end
+
+Dir[::File.join(__dir__, "features/shared_examples/**/*.rb")].sort.each { |f| require f }
+Dir[::File.join(__dir__, "features/shared_contexts/**/*.rb")].sort.each { |f| require f }
diff --git a/qa/qa/support/fips.rb b/qa/qa/support/fips.rb
index f5ebce4fa9c..0fed39e8109 100644
--- a/qa/qa/support/fips.rb
+++ b/qa/qa/support/fips.rb
@@ -5,7 +5,7 @@ module QA
module Support
class FIPS
def self.enabled?
- %(1 true yes).include?(ENV['FIPS'].to_s)
+ %w[1 true yes].include?(ENV['FIPS'].to_s)
end
end
end
diff --git a/qa/qa/support/formatters/allure_metadata_formatter.rb b/qa/qa/support/formatters/allure_metadata_formatter.rb
index d1baf87799a..02719536b17 100644
--- a/qa/qa/support/formatters/allure_metadata_formatter.rb
+++ b/qa/qa/support/formatters/allure_metadata_formatter.rb
@@ -39,6 +39,7 @@ module QA
add_failure_issues_link(example)
add_ci_job_link(example)
set_flaky_status(example)
+ set_behaviour_categories(example)
end
private
@@ -97,6 +98,19 @@ module QA
log(:error, "Failed to add spec pass rate data for example '#{example.description}', error: #{e}")
end
+ # Add behaviour categories to report
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [void]
+ def set_behaviour_categories(example)
+ file_path = example.file_path.gsub('./qa/specs/features', '')
+ devops_stage = file_path.match(%r{\d{1,2}_(\w+)/})&.captures&.first
+ product_group = example.metadata[:product_group]
+
+ example.epic(devops_stage) if devops_stage
+ example.feature(product_group) if product_group
+ end
+
# Flaky specs with pass rate below 98%
#
# @return [Array]
@@ -107,7 +121,7 @@ module QA
runs = records.count
failed = records.count { |r| r.values["status"] == "failed" }
- pass_rate = 100 - ((failed.to_f / runs.to_f) * 100)
+ pass_rate = 100 - ((failed.to_f / runs) * 100)
# Consider spec with a pass rate less than 98% as flaky
result[records.last.values["testcase"]] = pass_rate if pass_rate < 98
diff --git a/qa/qa/support/formatters/context_formatter.rb b/qa/qa/support/formatters/context_formatter.rb
index c8991561f45..11f6a182ebb 100644
--- a/qa/qa/support/formatters/context_formatter.rb
+++ b/qa/qa/support/formatters/context_formatter.rb
@@ -36,6 +36,7 @@ module QA
# @param [<RSpec::Core::ExampleGroup, RSpec::Core::Example>] example
# @return [void]
def set_skip_metadata(example)
+ return if Runtime::Scenario.attributes[:test_metadata_only]
return skip_only(example.metadata) if example.metadata.key?(:only)
return skip_except(example.metadata) if example.metadata.key?(:except)
end
diff --git a/qa/qa/support/formatters/test_stats_formatter.rb b/qa/qa/support/formatters/test_metrics_formatter.rb
index 2cde2d0928e..e84373a487d 100644
--- a/qa/qa/support/formatters/test_stats_formatter.rb
+++ b/qa/qa/support/formatters/test_metrics_formatter.rb
@@ -1,9 +1,11 @@
# frozen_string_literal: true
+require "active_support/core_ext/string/conversions"
+
module QA
module Support
module Formatters
- class TestStatsFormatter < RSpec::Core::Formatters::BaseFormatter
+ class TestMetricsFormatter < RSpec::Core::Formatters::BaseFormatter
include Support::InfluxdbTools
RSpec::Core::Formatters.register(self, :stop)
@@ -13,29 +15,43 @@ module QA
# @param [RSpec::Core::Notifications::ExamplesNotification] notification
# @return [void]
def stop(notification)
- push_test_stats(notification.examples)
- push_fabrication_stats
+ return log(:warn, "Missing run_type, skipping metrics export!") unless run_type
+
+ parse_execution_data(notification.examples)
+
+ if Runtime::Env.export_metrics?
+ push_test_metrics
+ push_fabrication_metrics
+ end
+
+ save_test_metrics if Runtime::Env.save_metrics_json?
end
private
- # Push test execution stats to influxdb
+ # Save execution data for the run
#
# @param [Array<RSpec::Core::Example>] examples
- # @return [void]
- def push_test_stats(examples)
- data = examples.map { |example| test_stats(example) }.compact
+ # @return [Array<Hash>]
+ def execution_data(examples = nil)
+ @execution_metrics ||= examples.map { |example| test_stats(example) }.compact
+ end
+ alias_method :parse_execution_data, :execution_data
- write_api.write(data: data)
- log(:debug, "Pushed #{data.length} test execution entries to influxdb")
+ # Push test execution metrics to influxdb
+ #
+ # @return [void]
+ def push_test_metrics
+ write_api.write(data: execution_data)
+ log(:debug, "Pushed #{execution_data.length} test execution entries to influxdb")
rescue StandardError => e
- log(:error, "Failed to push test execution stats to influxdb, error: #{e}")
+ log(:error, "Failed to push test execution metrics to influxdb, error: #{e}")
end
- # Push resource fabrication stats to influxdb
+ # Push resource fabrication metrics to influxdb
#
# @return [void]
- def push_fabrication_stats
+ def push_fabrication_metrics
data = Tools::TestResourceDataProcessor.resources.flat_map do |resource, values|
values.map { |v| fabrication_stats(resource: resource, **v) }
end
@@ -44,7 +60,16 @@ module QA
write_api.write(data: data)
log(:debug, "Pushed #{data.length} resource fabrication entries to influxdb")
rescue StandardError => e
- log(:error, "Failed to push fabrication stats to influxdb, error: #{e}")
+ log(:error, "Failed to push fabrication metrics to influxdb, error: #{e}")
+ end
+
+ # Save metrics in json file
+ #
+ # @return [void]
+ def save_test_metrics
+ File.write("tmp/test-metrics-#{env('CI_JOB_NAME_SLUG') || 'local'}.json", execution_data.to_json)
+ rescue StandardError => e
+ log(:error, "Failed to save test execution metrics, error: #{e}")
end
# Transform example to influxdb compatible metrics data
@@ -57,21 +82,25 @@ module QA
api_fabrication = ((example.metadata[:api_fabrication] || 0) * 1000).round
ui_fabrication = ((example.metadata[:browser_ui_fabrication] || 0) * 1000).round
+ # do not export results for tests that are not compatible with environment
+ return if incompatible_env?(example)
+
{
name: 'test-stats',
time: time,
tags: {
name: example.full_description,
file_path: file_path,
- status: example.execution_result.status,
+ status: status(example),
smoke: example.metadata.key?(:smoke).to_s,
reliable: example.metadata.key?(:reliable).to_s,
quarantined: quarantined(example.metadata),
- retried: ((example.metadata[:retry_attempts] || 0) > 0).to_s,
+ retried: (retry_attempts(example.metadata) > 0).to_s,
job_name: job_name,
merge_request: merge_request,
run_type: run_type,
stage: devops_stage(file_path),
+ product_group: example.metadata[:product_group],
testcase: example.metadata[:testcase]
},
fields: {
@@ -80,7 +109,7 @@ module QA
api_fabrication: api_fabrication,
ui_fabrication: ui_fabrication,
total_fabrication: api_fabrication + ui_fabrication,
- retry_attempts: example.metadata[:retry_attempts] || 0,
+ retry_attempts: retry_attempts(example.metadata),
job_url: QA::Runtime::Env.ci_job_url,
pipeline_url: env('CI_PIPELINE_URL'),
pipeline_id: env('CI_PIPELINE_ID'),
@@ -100,6 +129,7 @@ module QA
# @param [Symbol] fabrication_method
# @param [Symbol] http_method
# @param [Integer] fabrication_time
+ # @param [String] timestamp
# @return [Hash]
def fabrication_stats(resource:, info:, fabrication_method:, http_method:, fabrication_time:, timestamp:, **)
{
@@ -135,7 +165,7 @@ module QA
@time ||= begin
return Time.now unless env('CI_PIPELINE_CREATED_AT')
- DateTime.strptime(env('CI_PIPELINE_CREATED_AT')).to_time
+ env('CI_PIPELINE_CREATED_AT').to_time
end
end
@@ -157,6 +187,39 @@ module QA
(!Specs::Helpers::Quarantine.quarantined_different_context?(metadata[:quarantine])).to_s
end
+ # Return a more detailed status
+ #
+ # - if test is failed or pending, return rspec status
+ # - if test passed but had more than 1 attempt, consider test flaky
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [String]
+ def status(example)
+ rspec_status = example.execution_result.status
+ return rspec_status if [:pending, :failed].include?(rspec_status)
+
+ retry_attempts(example.metadata) > 0 ? :flaky : :passed
+ end
+
+ # Check if test was skipped due to context condition
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [Boolean]
+ def incompatible_env?(example)
+ return false unless example.execution_result.status == :pending
+ return false unless example.metadata[:skip]
+
+ !example.metadata[:skip].to_s.include?("quarantine") # rubocop:disable Rails/NegateInclude
+ end
+
+ # Retry attempts
+ #
+ # @param [Hash] metadata
+ # @return [Integer]
+ def retry_attempts(metadata)
+ metadata[:retry_attempts] || 0
+ end
+
# Print log message
#
# @param [Symbol] level
diff --git a/qa/qa/support/influxdb_tools.rb b/qa/qa/support/influxdb_tools.rb
index e53b843ca87..e817b096864 100644
--- a/qa/qa/support/influxdb_tools.rb
+++ b/qa/qa/support/influxdb_tools.rb
@@ -7,7 +7,11 @@ module QA
# Common tools for use with influxdb metrics setup
#
module InfluxdbTools
+ # @return [String] bucket for storing all test run metrics
INFLUX_TEST_METRICS_BUCKET = "e2e-test-stats"
+ # @return [String] bucket for storing metrics from main runs
+ INFLUX_MAIN_TEST_METRICS_BUCKET = "e2e-test-stats-main"
+ # @return [Array] live environment names
LIVE_ENVS = %w[staging staging-canary staging-ref canary preprod production].freeze
private
diff --git a/qa/qa/support/loglinking.rb b/qa/qa/support/loglinking.rb
index ceddd35da17..f24577ff313 100644
--- a/qa/qa/support/loglinking.rb
+++ b/qa/qa/support/loglinking.rb
@@ -9,15 +9,12 @@ module QA
PRE_PROD_ADDRESS = 'https://pre.gitlab.com'
SENTRY_ENVIRONMENTS = {
staging: 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg',
- staging_canary: 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny',
- staging_ref: 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=gstg-ref',
- pre: 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=pre',
- canary: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd',
- production: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd-cny'
+ staging_ref: 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=all',
+ pre: 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=all',
+ production: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd'
}.freeze
KIBANA_ENVIRONMENTS = {
staging: 'https://nonprod-log.gitlab.net/',
- staging_canary: 'https://nonprod-log.gitlab.net/',
canary: 'https://log.gprd.gitlab.net/',
production: 'https://log.gprd.gitlab.net/'
}.freeze
@@ -30,7 +27,7 @@ module QA
errors = ["Correlation Id: #{correlation_id}"]
errors << "Sentry Url: #{sentry_uri}&query=correlation_id%3A%22#{correlation_id}%22" if sentry_uri
- errors << "Kibana Url: #{kibana_uri}app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20#{correlation_id}'))&_g=(time:(from:now-24h%2Fh,to:now))" if kibana_uri
+ errors << "Kibana Url: #{kibana_uri}app/discover#/?_a=%28query%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20#{correlation_id}%27%29%29&_g=%28time%3A%28from%3Anow-24h%2Cto%3Anow%29%29" if kibana_uri
errors.join("\n")
end
@@ -53,11 +50,11 @@ module QA
case address
when STAGING_ADDRESS
- canary? ? :staging_canary : :staging
+ :staging
when STAGING_REF_ADDRESS
:staging_ref
when PRODUCTION_ADDRESS
- canary? ? :canary : :production
+ :production
when PRE_PROD_ADDRESS
:pre
else
@@ -68,19 +65,6 @@ module QA
def self.logging_environment?
!logging_environment.nil?
end
-
- def self.cookies
- browser_cookies = Capybara.current_session.driver.browser.manage.all_cookies
- # rubocop:disable Rails/IndexBy
- browser_cookies.each_with_object({}) do |cookie, memo|
- memo[cookie[:name]] = cookie
- end
- # rubocop:enable Rails/IndexBy
- end
-
- def self.canary?
- cookies.dig('gitlab_canary', :value) == 'true'
- end
end
end
end
diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb
index 6dfb348a347..79ea4a8d001 100644
--- a/qa/qa/support/page/logging.rb
+++ b/qa/qa/support/page/logging.rb
@@ -54,18 +54,25 @@ module QA
elements
end
- def check_element(name, click_by_js = nil)
- log("checking :#{highlight_element(name)}", :info)
+ def check_element(name, click_by_js = false, **kwargs)
+ log_by_js("checking", name, click_by_js, **kwargs)
super
end
- def uncheck_element(name, click_by_js = nil)
- log("unchecking :#{highlight_element(name)}", :info)
+ def uncheck_element(name, click_by_js = false, **kwargs)
+ log_by_js("unchecking", name, click_by_js, **kwargs)
super
end
+ def log_by_js(action, name, click_by_js, **kwargs)
+ msg = action
+ msg += " via JS" if click_by_js
+ msg += " :#{highlight_element(name)} with args #{kwargs}"
+ log(msg, :info)
+ end
+
def click_element_coordinates(name, **kwargs)
log(%(clicking the coordinates of :#{highlight_element(name)}), :info)
diff --git a/qa/qa/tools/ci/qa_changes.rb b/qa/qa/tools/ci/qa_changes.rb
index 784923714d6..1ab93b6dfbf 100644
--- a/qa/qa/tools/ci/qa_changes.rb
+++ b/qa/qa/tools/ci/qa_changes.rb
@@ -10,7 +10,7 @@ module QA
include Helpers
QA_PATTERN = %r{^qa/}.freeze
- SPEC_PATTERN = %r{^qa/qa/specs/features/}.freeze
+ SPEC_PATTERN = %r{^qa/qa/specs/features/\S+_spec\.rb}.freeze
DEPENDENCY_PATTERN = Regexp.union(
/_VERSION/,
/Gemfile\.lock/,
diff --git a/qa/qa/tools/ci/test_metrics.rb b/qa/qa/tools/ci/test_metrics.rb
new file mode 100644
index 00000000000..96df432374a
--- /dev/null
+++ b/qa/qa/tools/ci/test_metrics.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require "active_support/core_ext/string/conversions"
+
+module QA
+ module Tools
+ module Ci
+ class TestMetrics
+ include Helpers
+ include Support::InfluxdbTools
+
+ def initialize(metrics_file_glob)
+ @metrics_file_glob = metrics_file_glob
+ end
+
+ def self.export(metrics_file_glob)
+ new(metrics_file_glob).export
+ end
+
+ # Export metrics to main bucket
+ #
+ # @return [void]
+ def export
+ return logger.warn("No files matched pattern '#{metrics_file_glob}'") if metrics_files.empty?
+
+ logger.info("Exporting #{metrics_data.size} entries to influxdb")
+ influx_client.create_write_api.write(data: metrics_data, bucket: INFLUX_MAIN_TEST_METRICS_BUCKET)
+ end
+
+ private
+
+ attr_reader :metrics_file_glob
+
+ # Metrics data files
+ #
+ # @return [Array]
+ def metrics_files
+ @metrics_files ||= Dir.glob(metrics_file_glob)
+ end
+
+ # Test metrics data
+ #
+ # @return [Array<Hash>]
+ def metrics_data
+ @metrics_data ||= metrics_files
+ .flat_map { |file| JSON.parse(File.read(file), symbolize_names: true) }
+ .map { |entry| entry.merge(time: entry[:time].to_time) }
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/tools/delete_subgroups.rb b/qa/qa/tools/delete_subgroups.rb
index 355bd6bf10d..edf2f0ff5f0 100644
--- a/qa/qa/tools/delete_subgroups.rb
+++ b/qa/qa/tools/delete_subgroups.rb
@@ -1,70 +1,149 @@
# frozen_string_literal: true
# This script deletes all subgroups of a group specified by ENV['TOP_LEVEL_GROUP_NAME']
+#
# Required environment variables: GITLAB_QA_ACCESS_TOKEN and GITLAB_ADDRESS
-# Optional environment variable: TOP_LEVEL_GROUP_NAME (defaults to 'gitlab-qa-sandbox-group')
+# Optional environment variable: TOP_LEVEL_GROUP_NAME (defaults to 'gitlab-qa-sandbox-group-<current weekday #>')
+
+# Optional environment variable: PERMANENTLY_DELETE (defaults to false)
+# Set PERMANENTLY_DELETE to true if you would like to permanently delete subgroups on an environment with
+# deletion protection enabled. Otherwise, subgroups will remain available during the retention period specified
+# in admin settings. On environments with deletion protection disabled, subgroups will always be permanently deleted.
+#
# Run `rake delete_subgroups`
module QA
module Tools
class DeleteSubgroups
include Support::API
+ include Ci::Helpers
def initialize
raise ArgumentError, "Please provide GITLAB_ADDRESS" unless ENV['GITLAB_ADDRESS']
raise ArgumentError, "Please provide GITLAB_QA_ACCESS_TOKEN" unless ENV['GITLAB_QA_ACCESS_TOKEN']
@api_client = Runtime::API::Client.new(ENV['GITLAB_ADDRESS'], personal_access_token: ENV['GITLAB_QA_ACCESS_TOKEN'])
+ @failed_deletion_attempts = []
end
def run
- $stdout.puts 'Fetching subgroups for deletion...'
+ group_id = fetch_group_id
+ return logger.info('Top level group not found') if group_id.nil?
- sub_group_ids = fetch_subgroup_ids
- $stdout.puts "\nNumber of Sub Groups not already marked for deletion: #{sub_group_ids.length}"
+ subgroups = fetch_subgroups(group_id)
+ return logger.info('No subgroups available') if subgroups.empty?
- delete_subgroups(sub_group_ids) unless sub_group_ids.empty?
- $stdout.puts "\nDone"
- end
+ subgroups_marked_for_deletion = mark_for_deletion(subgroups)
- private
+ if ENV['PERMANENTLY_DELETE'] && !subgroups_marked_for_deletion.empty?
+ delete_permanently(subgroups_marked_for_deletion)
+ end
- def delete_subgroups(sub_group_ids)
- $stdout.puts "Deleting #{sub_group_ids.length} subgroups..."
- sub_group_ids.each do |subgroup_id|
- request_url = Runtime::API::Request.new(@api_client, "/groups/#{subgroup_id}").url
- path = parse_body(get(request_url))[:full_path]
- $stdout.puts "\nDeleting subgroup #{path}..."
+ print_failed_deletion_attempts
- delete_response = delete(request_url)
- dot_or_f = delete_response.code == 202 ? "\e[32m.\e[0m" : "\e[31mF - #{delete_response}\e[0m"
- print dot_or_f
- end
+ logger.info('Done')
end
+ private
+
def fetch_group_id
+ logger.info("Fetching top level group id...\n")
+
group_name = ENV['TOP_LEVEL_GROUP_NAME'] || "gitlab-qa-sandbox-group-#{Time.now.wday + 1}"
group_search_response = get Runtime::API::Request.new(@api_client, "/groups/#{group_name}" ).url
- JSON.parse(group_search_response.body)["id"]
+ JSON.parse(group_search_response.body)['id']
end
- def fetch_subgroup_ids
- group_id = fetch_group_id
- sub_groups_ids = []
+ def fetch_subgroups(group_id)
+ logger.info("Fetching subgroups...")
+
+ api_path = "/groups/#{group_id}/subgroups"
page_no = '1'
+ subgroups = []
- # When we reach the last page, the x-next-page header is a blank string
while page_no.present?
- $stdout.print '.'
+ subgroups_response = get Runtime::API::Request.new(@api_client, api_path, page: page_no, per_page: '100').url
+ subgroups.concat(JSON.parse(subgroups_response.body))
+
+ page_no = subgroups_response.headers[:x_next_page].to_s
+ end
+
+ subgroups
+ end
+
+ def subgroup_request(subgroup, **options)
+ Runtime::API::Request.new(@api_client, "/groups/#{subgroup['id']}", **options).url
+ end
+
+ def process_response_and_subgroup(response, subgroup, opts = {})
+ if response.code == 202
+ logger.info("Success\n")
+ opts[:save_successes_to] << subgroup if opts[:save_successes_to]
+ else
+ logger.error("Failed - #{response}\n")
+ @failed_deletion_attempts << { path: subgroup['full_path'], response: response }
+ end
+ end
+
+ def mark_for_deletion(subgroups)
+ subgroups_marked_for_deletion = []
+
+ logger.info("Marking #{subgroups.length} subgroups for deletion...\n")
+
+ subgroups.each do |subgroup|
+ path = subgroup['full_path']
+
+ if subgroup['marked_for_deletion_on'].nil?
+ logger.info("Marking subgroup #{path} for deletion...")
+ response = delete(subgroup_request(subgroup))
- sub_groups_response = get Runtime::API::Request.new(@api_client, "/groups/#{group_id}/subgroups", page: page_no, per_page: '100').url
- sub_groups_ids.concat(JSON.parse(sub_groups_response.body)
- .reject { |subgroup| !subgroup["marked_for_deletion_on"].nil? }.map { |subgroup| subgroup['id'] })
+ process_response_and_subgroup(response, subgroup, save_successes_to: subgroups_marked_for_deletion)
+ else
+ logger.info("Subgroup #{path} already marked for deletion\n")
+ subgroups_marked_for_deletion << subgroup
+ end
+ end
+
+ subgroups_marked_for_deletion
+ end
- page_no = sub_groups_response.headers[:x_next_page].to_s
+ def subgroup_exists?(subgroup)
+ response = get(subgroup_request(subgroup))
+
+ if response.code == 404
+ logger.info("Subgroup #{subgroup['full_path']} is no longer available\n")
+ false
+ else
+ true
end
+ end
- sub_groups_ids.uniq
+ def delete_permanently(subgroups)
+ logger.info("Permanently deleting #{subgroups.length} subgroups...\n")
+
+ subgroups.each do |subgroup|
+ path = subgroup['full_path']
+
+ next unless subgroup_exists?(subgroup)
+
+ logger.info("Permanently deleting subgroup #{path}...")
+ delete_subgroup_response = delete(subgroup_request(subgroup, { permanently_remove: true, full_path: path }))
+
+ process_response_and_subgroup(delete_subgroup_response, subgroup)
+ end
+ end
+
+ def print_failed_deletion_attempts
+ if @failed_deletion_attempts.empty?
+ logger.info('No failed deletion attempts to report!')
+ else
+ logger.info("There were #{@failed_deletion_attempts.length} failed deletion attempts:\n")
+
+ @failed_deletion_attempts.each do |attempt|
+ logger.info("Subgroup: #{attempt[:path]}")
+ logger.error("Response: #{attempt[:response]}\n")
+ end
+ end
end
end
end
diff --git a/qa/spec/resource/api_fabricator_spec.rb b/qa/spec/resource/api_fabricator_spec.rb
index 581236e5ac5..4cb6ef3c9b5 100644
--- a/qa/spec/resource/api_fabricator_spec.rb
+++ b/qa/spec/resource/api_fabricator_spec.rb
@@ -155,8 +155,8 @@ RSpec.describe QA::Resource::ApiFabricator do
expect(error.to_s).to eql(<<~ERROR.chomp)
Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.
Correlation Id: foobar
- Sentry Url: https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny&query=correlation_id%3A%22foobar%22
- Kibana Url: https://nonprod-log.gitlab.net/app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20foobar'))&_g=(time:(from:now-24h%2Fh,to:now))
+ Sentry Url: https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg&query=correlation_id%3A%22foobar%22
+ Kibana Url: https://nonprod-log.gitlab.net/app/discover#/?_a=%28query%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20foobar%27%29%29&_g=%28time%3A%28from%3Anow-24h%2Cto%3Anow%29%29
ERROR
end
end
diff --git a/qa/spec/resource/base_spec.rb b/qa/spec/resource/base_spec.rb
index 195e497f290..0ec27da7277 100644
--- a/qa/spec/resource/base_spec.rb
+++ b/qa/spec/resource/base_spec.rb
@@ -87,12 +87,46 @@ RSpec.describe QA::Resource::Base do
end
context 'when resource supports fabrication via the API' do
- it 'calls .fabricate_via_browser_ui!' do
+ it 'calls .fabricate_via_api!!' do
expect(described_class).to receive(:fabricate_via_api!)
described_class.fabricate!
end
end
+
+ context 'when FIPS mode is enabled' do
+ before do
+ stub_env('FIPS', '1')
+ end
+
+ it 'calls .fabricate_via_browser_ui!' do
+ expect(described_class).to receive(:fabricate_via_browser_ui!)
+
+ described_class.fabricate!
+ end
+ end
+ end
+
+ describe '.fabricate_via_api_unless_fips!' do
+ context 'when FIPS mode is not enabled' do
+ it 'calls .fabricate_via_api!!' do
+ expect(described_class).to receive(:fabricate_via_api!)
+
+ described_class.fabricate_via_api_unless_fips!
+ end
+ end
+
+ context 'when FIPS mode is enabled' do
+ before do
+ stub_env('FIPS', '1')
+ end
+
+ it 'calls .fabricate_via_browser_ui!' do
+ expect(described_class).to receive(:fabricate_via_browser_ui!)
+
+ described_class.fabricate_via_api_unless_fips!
+ end
+ end
end
describe '.fabricate_via_api!' do
diff --git a/qa/spec/resource/user_spec.rb b/qa/spec/resource/user_spec.rb
index d82dcc3b21e..d1fc02ff033 100644
--- a/qa/spec/resource/user_spec.rb
+++ b/qa/spec/resource/user_spec.rb
@@ -116,4 +116,31 @@ RSpec.describe QA::Resource::User do
expect(subject).to be_credentials_given
end
end
+
+ describe '#has_user?' do
+ let(:index_mock) do
+ instance_double(QA::Page::Admin::Overview::Users::Index)
+ end
+
+ users = [
+ ['foo', true],
+ ['bar', false]
+ ]
+
+ users.each do |(username, found)|
+ it "returns #{found} when has_username returns #{found}" do
+ subject.username = username
+
+ allow(QA::Flow::Login).to receive(:while_signed_in_as_admin).and_yield
+ allow(QA::Page::Main::Menu).to receive(:perform)
+ allow(QA::Page::Admin::Menu).to receive(:perform)
+ allow(QA::Page::Admin::Overview::Users::Index).to receive(:perform).and_yield(index_mock)
+
+ expect(index_mock).to receive(:search_user).with(username)
+ expect(index_mock).to receive(:has_username?).with(username).and_return(found)
+
+ expect(subject.has_user?(subject)).to eq(found)
+ end
+ end
+ end
end
diff --git a/qa/spec/specs/runner_spec.rb b/qa/spec/specs/runner_spec.rb
index dd013497367..cbe5699a306 100644
--- a/qa/spec/specs/runner_spec.rb
+++ b/qa/spec/specs/runner_spec.rb
@@ -111,7 +111,7 @@ RSpec.describe QA::Specs::Runner do
it 'sets the `--dry-run` flag' do
expect_rspec_runner_arguments(
- ['--dry-run'] + DEFAULT_SKIPPED_TAGS + ['--tag', '~geo', *described_class::DEFAULT_TEST_PATH_ARGS],
+ ['--dry-run', *described_class::DEFAULT_TEST_PATH_ARGS],
[$stderr, anything]
)
diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_metrics_formatter_spec.rb
index d0d89b5ee73..76bde98cc33 100644
--- a/qa/spec/support/formatters/test_stats_formatter_spec.rb
+++ b/qa/spec/support/formatters/test_metrics_formatter_spec.rb
@@ -3,7 +3,7 @@
require 'rspec/core/sandbox'
require 'active_support/testing/time_helpers'
-describe QA::Support::Formatters::TestStatsFormatter do
+describe QA::Support::Formatters::TestMetricsFormatter do
include QA::Support::Helpers::StubEnv
include QA::Specs::Helpers::RSpec
include ActiveSupport::Testing::TimeHelpers
@@ -28,6 +28,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
let(:api_fabrication) { 0 }
let(:fabrication_resources) { {} }
let(:testcase) { 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234' }
+ let(:product_group) { nil }
let(:influx_client_args) do
{
@@ -53,10 +54,11 @@ describe QA::Support::Formatters::TestStatsFormatter do
merge_request: 'false',
run_type: run_type,
stage: stage.match(%r{\d{1,2}_(\w+)}).captures.first,
+ product_group: product_group,
testcase: testcase
},
fields: {
- id: './spec/support/formatters/test_stats_formatter_spec.rb[1:1]',
+ id: './spec/support/formatters/test_metrics_formatter_spec.rb[1:1]',
run_time: 0,
api_fabrication: api_fabrication * 1000,
ui_fabrication: ui_fabrication * 1000,
@@ -131,6 +133,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
stub_env('CI_MERGE_REQUEST_IID', nil)
stub_env('TOP_UPSTREAM_MERGE_REQUEST_IID', nil)
stub_env('QA_RUN_TYPE', run_type)
+ stub_env('QA_EXPORT_TEST_METRICS', "true")
end
context 'with reliable spec' do
@@ -146,6 +149,19 @@ describe QA::Support::Formatters::TestStatsFormatter do
end
end
+ context 'with product group tag' do
+ let(:product_group) { :import }
+
+ it 'exports data to influxdb with correct reliable tag' do
+ run_spec do
+ it('spec', product_group: :import, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {}
+ end
+
+ expect(influx_write_api).to have_received(:write).once
+ expect(influx_write_api).to have_received(:write).with(data: [data])
+ end
+ end
+
context 'with smoke spec' do
let(:smoke) { 'true' }
@@ -189,6 +205,20 @@ describe QA::Support::Formatters::TestStatsFormatter do
end
end
+ context 'with skipped spec' do
+ it 'skips export' do
+ run_spec do
+ it(
+ 'spec',
+ skip: 'not compatible',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234'
+ ) {}
+ end
+
+ expect(influx_write_api).to have_received(:write).with(data: [])
+ end
+ end
+
context 'with staging full run' do
let(:run_type) { 'staging-full' }
@@ -286,5 +316,21 @@ describe QA::Support::Formatters::TestStatsFormatter do
expect(influx_write_api).to have_received(:write).with(data: [fabrication_data])
end
end
+
+ context 'with persisting metrics' do
+ before do
+ stub_env('QA_EXPORT_TEST_METRICS', "false")
+ stub_env('QA_SAVE_TEST_METRICS', "true")
+ stub_env('CI_JOB_NAME_SLUG', "test-job")
+
+ allow(File).to receive(:write)
+ end
+
+ it 'saves test metrics as json files' do
+ run_spec
+
+ expect(File).to have_received(:write).with("tmp/test-metrics-test-job.json", [data].to_json)
+ end
+ end
end
end
diff --git a/qa/spec/support/loglinking_spec.rb b/qa/spec/support/loglinking_spec.rb
index d1cc76bccc4..10865068e3d 100644
--- a/qa/spec/support/loglinking_spec.rb
+++ b/qa/spec/support/loglinking_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe QA::Support::Loglinking do
expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp)
Correlation Id: foo123
- Kibana Url: https://kibana.address/app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20foo123'))&_g=(time:(from:now-24h%2Fh,to:now))
+ Kibana Url: https://kibana.address/app/discover#/?_a=%28query%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20foo123%27%29%29&_g=%28time%3A%28from%3Anow-24h%2Cto%3Anow%29%29
ERROR
end
end
@@ -39,11 +39,9 @@ RSpec.describe QA::Support::Loglinking do
let(:url_hash) do
{
:staging => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg',
- :staging_canary => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny',
- :staging_ref => 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=gstg-ref',
- :pre => 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=pre',
- :canary => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd',
- :production => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd-cny',
+ :staging_ref => 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=all',
+ :pre => 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=all',
+ :production => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd',
:foo => nil,
nil => nil
}
@@ -62,10 +60,7 @@ RSpec.describe QA::Support::Loglinking do
let(:url_hash) do
{
:staging => 'https://nonprod-log.gitlab.net/',
- :staging_canary => 'https://nonprod-log.gitlab.net/',
:staging_ref => nil,
- :pre => nil,
- :canary => 'https://log.gprd.gitlab.net/',
:production => 'https://log.gprd.gitlab.net/',
:foo => nil,
nil => nil
@@ -90,37 +85,22 @@ RSpec.describe QA::Support::Loglinking do
[
{
address: staging_address,
- canary: false,
expected_env: :staging
},
{
- address: staging_address,
- canary: true,
- expected_env: :staging_canary
- },
- {
address: staging_ref_address,
- canary: true,
expected_env: :staging_ref
},
{
address: production_address,
- canary: false,
expected_env: :production
},
{
- address: production_address,
- canary: true,
- expected_env: :canary
- },
- {
address: pre_prod_address,
- canary: true,
expected_env: :pre
},
{
address: 'https://foo.com',
- canary: true,
expected_env: nil
}
]
@@ -129,7 +109,6 @@ RSpec.describe QA::Support::Loglinking do
it 'returns logging environment if environment found' do
logging_env_array.each do |logging_env_hash|
allow(QA::Runtime::Scenario).to receive(:attributes).and_return({ gitlab_address: logging_env_hash[:address] })
- allow(QA::Support::Loglinking).to receive(:canary?).and_return(logging_env_hash[:canary])
expect(QA::Support::Loglinking.logging_environment).to eq(logging_env_hash[:expected_env])
end
@@ -151,37 +130,4 @@ RSpec.describe QA::Support::Loglinking do
end
end
end
-
- describe '.cookies' do
- let(:cookies) { [{ name: 'Foo', value: 'Bar' }, { name: 'gitlab_canary', value: 'true' }] }
-
- it 'returns browser cookies' do
- allow(Capybara.current_session).to receive_message_chain(:driver, :browser, :manage, :all_cookies).and_return(cookies)
-
- expect(QA::Support::Loglinking.cookies).to eq({ "Foo" => { name: "Foo", value: "Bar" }, "gitlab_canary" => { name: "gitlab_canary", value: "true" } })
- end
- end
-
- describe '.canary?' do
- context 'gitlab_canary cookie is present' do
- it 'and true returns true' do
- allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'gitlab_canary' => { name: 'gitlab_canary', value: 'true' } })
-
- expect(QA::Support::Loglinking.canary?).to eq(true)
- end
-
- it 'and not true returns false' do
- allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'gitlab_canary' => { name: 'gitlab_canary', value: 'false' } })
-
- expect(QA::Support::Loglinking.canary?).to eq(false)
- end
- end
- context 'gitlab_canary cookie is not present' do
- it 'returns false' do
- allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'foo' => { name: 'foo', path: '/pathname' } })
-
- expect(QA::Support::Loglinking.canary?).to eq(false)
- end
- end
- end
end
diff --git a/qa/spec/support/repeater_spec.rb b/qa/spec/support/repeater_spec.rb
index 96e780fc9bd..9810456321e 100644
--- a/qa/spec/support/repeater_spec.rb
+++ b/qa/spec/support/repeater_spec.rb
@@ -1,17 +1,23 @@
# frozen_string_literal: true
require 'active_support/core_ext/integer/time'
+require 'active_support/testing/time_helpers'
RSpec.describe QA::Support::Repeater do
+ include ActiveSupport::Testing::TimeHelpers
+
subject do
Module.new do
extend QA::Support::Repeater
end
end
- let(:time_start) { Time.now }
let(:return_value) { "test passed" }
+ after do
+ travel_back
+ end
+
describe '.repeat_until' do
context 'when raise_on_failure is not provided (default: true)' do
context 'when retry_on_exception is not provided (default: false)' do
@@ -19,12 +25,7 @@ RSpec.describe QA::Support::Repeater do
context 'when max duration is reached' do
it 'raises an exception with default message' do
expect do
- Timecop.freeze do
- subject.repeat_until(max_duration: 1) do
- Timecop.travel(2)
- false
- end
- end
+ subject.repeat_until(max_duration: 1) { travel(2.seconds) && false }
end.to raise_error(QA::Support::Repeater::WaitExceededError, "Wait failed after 1 second")
end
@@ -32,12 +33,7 @@ RSpec.describe QA::Support::Repeater do
message = 'Some custom action'
expect do
- Timecop.freeze do
- subject.repeat_until(max_duration: 1, message: message) do
- Timecop.travel(2)
- false
- end
- end
+ subject.repeat_until(max_duration: 1, message: message) { travel(2.seconds) && false }
end.to raise_error(QA::Support::Repeater::WaitExceededError, "#{message} failed after 1 second")
end
@@ -45,16 +41,14 @@ RSpec.describe QA::Support::Repeater do
loop_counter = 0
expect(
- Timecop.freeze do
- subject.repeat_until(max_duration: 1) do
- loop_counter += 1
-
- if loop_counter > 3
- Timecop.travel(1)
- return_value
- else
- false
- end
+ subject.repeat_until(max_duration: 1) do
+ loop_counter += 1
+
+ if loop_counter > 3
+ travel(1.second)
+ return_value
+ else
+ false
end
end
).to eq(return_value)
@@ -64,13 +58,7 @@ RSpec.describe QA::Support::Repeater do
context 'when max duration is not reached' do
it 'returns value from block' do
- Timecop.freeze(time_start) do
- expect(
- subject.repeat_until(max_duration: 1) do
- return_value
- end
- ).to eq(return_value)
- end
+ expect(subject.repeat_until(max_duration: 10) { return_value }).to eq(return_value)
end
end
end
@@ -78,41 +66,31 @@ RSpec.describe QA::Support::Repeater do
context 'when max_attempts is provided' do
context 'when max_attempts is reached' do
it 'raises an exception with default message' do
- expect do
- Timecop.freeze do
- subject.repeat_until(max_attempts: 1) do
- false
- end
- end
- end.to raise_error(QA::Support::Repeater::RetriesExceededError, "Retry failed after 1 attempt")
+ expect { subject.repeat_until(max_attempts: 1) { false } }.to raise_error(
+ QA::Support::Repeater::RetriesExceededError, "Retry failed after 1 attempt"
+ )
end
it 'raises an exception with custom message' do
message = 'Some custom action'
- expect do
- Timecop.freeze do
- subject.repeat_until(max_attempts: 1, message: message) do
- false
- end
- end
- end.to raise_error(QA::Support::Repeater::RetriesExceededError, "#{message} failed after 1 attempt")
+ expect { subject.repeat_until(max_attempts: 1, message: message) { false } }.to raise_error(
+ QA::Support::Repeater::RetriesExceededError, "#{message} failed after 1 attempt"
+ )
end
it 'ignores duration' do
loop_counter = 0
expect(
- Timecop.freeze do
- subject.repeat_until(max_attempts: 2) do
- loop_counter += 1
- Timecop.travel(1.year)
-
- if loop_counter > 1
- return_value
- else
- false
- end
+ subject.repeat_until(max_attempts: 2) do
+ loop_counter += 1
+ travel(1.year)
+
+ if loop_counter > 1
+ return_value
+ else
+ false
end
end
).to eq(return_value)
@@ -122,13 +100,7 @@ RSpec.describe QA::Support::Repeater do
context 'when max_attempts is not reached' do
it 'returns value from block' do
- expect(
- Timecop.freeze do
- subject.repeat_until(max_attempts: 1) do
- return_value
- end
- end
- ).to eq(return_value)
+ expect(subject.repeat_until(max_attempts: 1) { return_value }).to eq(return_value)
end
end
end
@@ -136,31 +108,17 @@ RSpec.describe QA::Support::Repeater do
context 'when both max_attempts and max_duration are provided' do
context 'when max_attempts is reached first' do
it 'raises an exception' do
- loop_counter = 0
- expect do
- Timecop.freeze do
- subject.repeat_until(max_attempts: 1, max_duration: 2) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
- false
- end
- end
- end.to raise_error(QA::Support::Repeater::RetriesExceededError, "Retry failed after 1 attempt")
+ expect { subject.repeat_until(max_attempts: 1, max_duration: 2) { false } }.to(
+ raise_error(QA::Support::Repeater::RetriesExceededError, "Retry failed after 1 attempt")
+ )
end
end
context 'when max_duration is reached first' do
it 'raises an exception' do
- loop_counter = 0
- expect do
- Timecop.freeze do
- subject.repeat_until(max_attempts: 2, max_duration: 1) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
- false
- end
- end
- end.to raise_error(QA::Support::Repeater::WaitExceededError, "Wait failed after 1 second")
+ expect { subject.repeat_until(max_attempts: 2, max_duration: 1) { travel(10.seconds) && false } }.to(
+ raise_error(QA::Support::Repeater::WaitExceededError, "Wait failed after 1 second")
+ )
end
end
end
@@ -169,30 +127,26 @@ RSpec.describe QA::Support::Repeater do
context 'when retry_on_exception is true' do
context 'when max duration is reached' do
it 'raises an exception' do
- Timecop.freeze do
- expect do
- subject.repeat_until(max_duration: 1, retry_on_exception: true) do
- Timecop.travel(2)
+ expect do
+ subject.repeat_until(max_duration: 1, retry_on_exception: true) do
+ travel(10.seconds)
- raise "this should be raised"
- end
- end.to raise_error(RuntimeError, "this should be raised")
- end
+ raise "this should be raised"
+ end
+ end.to raise_error(RuntimeError, "this should be raised")
end
it 'does not raise an exception until max_duration is reached' do
loop_counter = 0
- Timecop.freeze(time_start) do
- expect do
- subject.repeat_until(max_duration: 2, retry_on_exception: true) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
+ expect do
+ subject.repeat_until(max_duration: 5, retry_on_exception: true) do
+ loop_counter += 1
+ travel(10.seconds) if loop_counter == 2
- raise "this should be raised"
- end
- end.to raise_error(RuntimeError, "this should be raised")
- end
+ raise "this should be raised"
+ end
+ end.to raise_error(RuntimeError, "this should be raised")
expect(loop_counter).to eq(2)
end
end
@@ -201,53 +155,18 @@ RSpec.describe QA::Support::Repeater do
it 'returns value from block' do
loop_counter = 0
- Timecop.freeze(time_start) do
- expect(
- subject.repeat_until(max_duration: 3, retry_on_exception: true) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
+ expect(
+ subject.repeat_until(max_duration: 3, retry_on_exception: true) do
+ loop_counter += 1
- raise "this should not be raised" if loop_counter == 1
+ raise "this should not be raised" if loop_counter == 1
- return_value
- end
- ).to eq(return_value)
- end
+ return_value
+ end
+ ).to eq(return_value)
expect(loop_counter).to eq(2)
end
end
-
- context 'when both max_attempts and max_duration are provided' do
- context 'when max_attempts is reached first' do
- it 'raises an exception' do
- loop_counter = 0
- expect do
- Timecop.freeze do
- subject.repeat_until(max_attempts: 1, max_duration: 2, retry_on_exception: true) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
- false
- end
- end
- end.to raise_error(QA::Support::Repeater::RetriesExceededError, "Retry failed after 1 attempt")
- end
- end
-
- context 'when max_duration is reached first' do
- it 'raises an exception' do
- loop_counter = 0
- expect do
- Timecop.freeze do
- subject.repeat_until(max_attempts: 2, max_duration: 1, retry_on_exception: true) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
- false
- end
- end
- end.to raise_error(QA::Support::Repeater::WaitExceededError, "Wait failed after 1 second")
- end
- end
- end
end
end
@@ -255,11 +174,9 @@ RSpec.describe QA::Support::Repeater do
context 'when retry_on_exception is not provided (default: false)' do
context 'when max duration is reached' do
def test_wait
- Timecop.freeze do
- subject.repeat_until(max_duration: 1, raise_on_failure: false) do
- Timecop.travel(2)
- return_value
- end
+ subject.repeat_until(max_duration: 1, raise_on_failure: false) do
+ travel(10.seconds)
+ return_value
end
end
@@ -274,23 +191,15 @@ RSpec.describe QA::Support::Repeater do
context 'when max duration is not reached' do
it 'returns the value from the block' do
- Timecop.freeze do
- expect(
- subject.repeat_until(max_duration: 1, raise_on_failure: false) do
- return_value
- end
- ).to eq(return_value)
- end
+ expect(subject.repeat_until(max_duration: 10, raise_on_failure: false) { return_value }).to eq(return_value)
end
it 'raises an exception' do
- Timecop.freeze do
- expect do
- subject.repeat_until(max_duration: 1, raise_on_failure: false) do
- raise "this should be raised"
- end
- end.to raise_error(RuntimeError, "this should be raised")
- end
+ expect do
+ subject.repeat_until(max_duration: 10, raise_on_failure: false) do
+ raise "this should be raised"
+ end
+ end.to raise_error(RuntimeError, "this should be raised")
end
end
@@ -300,12 +209,10 @@ RSpec.describe QA::Support::Repeater do
loop_counter = 0
expect(
- Timecop.freeze do
- subject.repeat_until(max_attempts: max_attempts, max_duration: max_duration, raise_on_failure: false) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
- false
- end
+ subject.repeat_until(max_attempts: max_attempts, max_duration: max_duration, raise_on_failure: false) do
+ loop_counter += 1
+ travel(max_attempts.seconds)
+ false
end
).to eq(false)
expect(loop_counter).to eq(1)
@@ -313,7 +220,7 @@ RSpec.describe QA::Support::Repeater do
end
context 'when max_attempts is reached first' do
- it_behaves_like 'repeat until', max_attempts: 1, max_duration: 2
+ it_behaves_like 'repeat until', max_attempts: 1, max_duration: 10
end
context 'when max_duration is reached first' do
@@ -325,11 +232,9 @@ RSpec.describe QA::Support::Repeater do
context 'when retry_on_exception is true' do
context 'when max duration is reached' do
def test_wait
- Timecop.freeze do
- subject.repeat_until(max_duration: 1, raise_on_failure: false, retry_on_exception: true) do
- Timecop.travel(2)
- return_value
- end
+ subject.repeat_until(max_duration: 1, raise_on_failure: false, retry_on_exception: true) do
+ travel(10.seconds)
+ return_value
end
end
@@ -341,61 +246,6 @@ RSpec.describe QA::Support::Repeater do
expect(test_wait).to eq(return_value)
end
end
-
- context 'when max duration is not reached' do
- before do
- @loop_counter = 0
- end
-
- def test_wait_with_counter
- Timecop.freeze(time_start) do
- subject.repeat_until(max_duration: 3, raise_on_failure: false, retry_on_exception: true) do
- @loop_counter += 1
- Timecop.travel(time_start + @loop_counter)
-
- raise "this should not be raised" if @loop_counter == 1
-
- return_value
- end
- end
- end
-
- it 'does not raise an exception' do
- expect { test_wait_with_counter }.not_to raise_error
- end
-
- it 'returns the value from the block' do
- expect(test_wait_with_counter).to eq(return_value)
- expect(@loop_counter).to eq(2)
- end
- end
-
- context 'when both max_attempts and max_duration are provided' do
- shared_examples 'repeat until' do |max_attempts:, max_duration:|
- it "returns when #{max_attempts < max_duration ? 'max_attempts' : 'max_duration'} is reached" do
- loop_counter = 0
-
- expect(
- Timecop.freeze do
- subject.repeat_until(max_attempts: max_attempts, max_duration: max_duration, raise_on_failure: false, retry_on_exception: true) do
- loop_counter += 1
- Timecop.travel(time_start + loop_counter)
- false
- end
- end
- ).to eq(false)
- expect(loop_counter).to eq(1)
- end
- end
-
- context 'when max_attempts is reached first' do
- it_behaves_like 'repeat until', max_attempts: 1, max_duration: 2
- end
-
- context 'when max_duration is reached first' do
- it_behaves_like 'repeat until', max_attempts: 2, max_duration: 1
- end
- end
end
end
diff --git a/qa/spec/tools/ci/qa_changes_spec.rb b/qa/spec/tools/ci/qa_changes_spec.rb
index d93d3cd9258..778a0ad33bb 100644
--- a/qa/spec/tools/ci/qa_changes_spec.rb
+++ b/qa/spec/tools/ci/qa_changes_spec.rb
@@ -49,6 +49,14 @@ RSpec.describe QA::Tools::Ci::QaChanges do
end
end
+ context "with shared example changes" do
+ let(:mr_diff) { [{ path: "qa/qa/specs/features/shared_context/some_context.rb", diff: "" }] }
+
+ it ".qa_tests do not return specific specs" do
+ expect(qa_changes.qa_tests).to be_nil
+ end
+ end
+
context "with non qa changes" do
let(:mr_diff) { [{ path: "Gemfile" }] }
diff --git a/qa/spec/tools/ci/test_metrics_spec.rb b/qa/spec/tools/ci/test_metrics_spec.rb
new file mode 100644
index 00000000000..4c1c4092d15
--- /dev/null
+++ b/qa/spec/tools/ci/test_metrics_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+RSpec.describe QA::Tools::Ci::TestMetrics do
+ include QA::Support::Helpers::StubEnv
+
+ let(:influx_client) { instance_double("InfluxDB2::Client", create_write_api: influx_write_api) }
+ let(:influx_write_api) { instance_double("InfluxDB2::WriteApi", write: nil) }
+ let(:logger) { instance_double("Logger", info: true, warn: true) }
+
+ let(:glob) { "metrics_glob/*.json" }
+ let(:paths) { ["/metrics_glob/metrics.json"] }
+ let(:timestamp) { "2022-11-11 07:54:11 +0000" }
+ let(:metrics_json) { metrics_data.to_json }
+
+ let(:metrics_data) do
+ [
+ {
+ time: timestamp.to_time,
+ name: "name",
+ tags: {},
+ fields: {}
+ }
+ ]
+ end
+
+ before do
+ allow(InfluxDB2::Client).to receive(:new) { influx_client }
+ allow(Gitlab::QA::TestLogger).to receive(:logger) { logger }
+ allow(Dir).to receive(:glob).with(glob) { paths }
+ allow(File).to receive(:read).with(paths.first) { metrics_json }
+
+ stub_env('QA_INFLUXDB_URL', "test")
+ stub_env('QA_INFLUXDB_TOKEN', "test")
+ end
+
+ context "with metrics files present" do
+ it "exports saved metrics to influxdb" do
+ described_class.export(glob)
+
+ expect(influx_write_api).to have_received(:write).with(data: metrics_data, bucket: "e2e-test-stats-main")
+ end
+ end
+
+ context "without metrics files present" do
+ let(:paths) { [] }
+
+ it "exits without error" do
+ described_class.export(glob)
+
+ expect(influx_write_api).not_to have_received(:write)
+ expect(logger).to have_received(:warn).with("No files matched pattern '#{glob}'")
+ end
+ end
+end
diff --git a/qa/spec/tools/test_resources_data_processor_spec.rb b/qa/spec/tools/test_resources_data_processor_spec.rb
index 2ae43974a0c..73fc2f6e853 100644
--- a/qa/spec/tools/test_resources_data_processor_spec.rb
+++ b/qa/spec/tools/test_resources_data_processor_spec.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-
require 'active_support/testing/time_helpers'
-
RSpec.describe QA::Tools::TestResourceDataProcessor do
include QA::Support::Helpers::StubEnv
include ActiveSupport::Testing::TimeHelpers
diff --git a/qa/tasks/ci.rake b/qa/tasks/ci.rake
index 435fe8ebb77..84a26e3e555 100644
--- a/qa/tasks/ci.rake
+++ b/qa/tasks/ci.rake
@@ -1,9 +1,8 @@
# frozen_string_literal: true
-require_relative "helpers/util"
-
-# rubocop:disable Rails/RakeEnvironment
namespace :ci do
+ require_relative "helpers/util"
+
include Task::Helpers::Util
desc "Detect changes and populate test variables for selective test execution and feature flag testing"
@@ -23,18 +22,20 @@ namespace :ci do
# skip running tests when only quarantine changes detected
if qa_changes.quarantine_changes?
logger.info(" merge request contains only quarantine changes, e2e test execution will be skipped!")
- append_to_file(env_file, <<~TXT)
- QA_SKIP_ALL_TESTS=true
- TXT
+ append_to_file(env_file, "QA_SKIP_ALL_TESTS=true")
next
end
- tests = qa_changes.qa_tests
- if qa_changes.framework_changes? # run all tests when framework changes detected
+ run_all_label_present = mr_labels.include?("pipeline:run-all-e2e")
+ # on run-all label of framework changes do not infer specific tests
+ tests = run_all_label_present || qa_changes.framework_changes? ? nil : qa_changes.qa_tests
+
+ if run_all_label_present
+ logger.info(" merge request has pipeline:run-all-e2e label, full test suite will be executed")
+ append_to_file(env_file, "QA_RUN_ALL_TESTS=true\n")
+ elsif qa_changes.framework_changes? # run all tests when framework changes detected
logger.info(" merge request contains qa framework changes, full test suite will be executed")
- append_to_file(env_file, <<~TXT)
- QA_FRAMEWORK_CHANGES=true
- TXT
+ append_to_file(env_file, "QA_FRAMEWORK_CHANGES=true\n")
elsif tests
logger.info(" detected following specs to execute: '#{tests}'")
else
@@ -44,20 +45,24 @@ namespace :ci do
# always check all test suites in case a suite is defined but doesn't have any runnable specs
suites = QA::Tools::Ci::NonEmptySuites.new(tests).fetch
append_to_file(env_file, <<~TXT)
- QA_TESTS='#{tests}'
QA_SUITES='#{suites}'
+ QA_TESTS='#{tests}'
TXT
# check if mr contains feature flag changes
feature_flags = QA::Tools::Ci::FfChanges.new(diff).fetch
- append_to_file(env_file, <<~TXT)
- QA_FEATURE_FLAGS='#{feature_flags}'
- TXT
+ append_to_file(env_file, "QA_FEATURE_FLAGS='#{feature_flags}'")
end
desc "Download test results from downstream pipeline"
task :download_test_results, [:trigger_name, :test_report_job_name, :report_path] do |_, args|
QA::Tools::Ci::TestResults.get(args[:trigger_name], args[:test_report_job_name], args[:report_path])
end
+
+ desc "Export test run metrics to influxdb"
+ task :export_test_metrics, [:glob] do |_, args|
+ raise("Metrics file glob pattern is required") unless args[:glob]
+
+ QA::Tools::Ci::TestMetrics.export(args[:glob])
+ end
end
-# rubocop:enable Rails/RakeEnvironment
diff --git a/qa/tasks/knapsack.rake b/qa/tasks/knapsack.rake
index c1225964aef..c502d1cbb4a 100644
--- a/qa/tasks/knapsack.rake
+++ b/qa/tasks/knapsack.rake
@@ -18,20 +18,20 @@ namespace :knapsack do
desc "Download latest knapsack reports for parallel jobs"
task :download, [:stage_name] do |_, args|
test_stage_name = args[:stage_name]
+ knapsack_reports = ENV["QA_KNAPSACK_REPORTS"]&.split(",")
+ ci_token = ENV["QA_GITLAB_CI_TOKEN"]
- # QA_KNAPSACK_REPORTS remains for changes to be backwards compatible
- # TODO: remove and only use automated detection once changes are merged
- unless ENV["QA_KNAPSACK_REPORTS"] || test_stage_name
- QA::Runtime::Logger.warn("Missing QA_KNAPSACK_REPORTS environment variable or test stage name for autodetection")
- next
- end
+ reports = if knapsack_reports
+ knapsack_reports
+ else
+ unless ci_token
+ QA::Runtime::Logger.error("Missing QA_GITLAB_CI_TOKEN for automatically detecting parallel jobs")
+ next
+ end
- reports = if test_stage_name
QA::Support::ParallelPipelineJobs
- .fetch(stage_name: test_stage_name, access_token: ENV["QA_GITLAB_CI_TOKEN"])
+ .fetch(stage_name: test_stage_name, access_token: ci_token)
.map { |job| job.tr(":", "-") }
- else
- ENV["QA_KNAPSACK_REPORTS"].split(",")
end
reports.each do |report_name|