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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 21:25:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 21:25:58 +0300
commita5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 (patch)
treefb69158581673816a8cd895f9d352dcb3c678b1e /qa
parentd16b2e8639e99961de6ddc93909f3bb5c1445ba1 (diff)
Add latest changes from gitlab-org/gitlab@14-0-stable-eev14.0.0-rc42
Diffstat (limited to 'qa')
-rw-r--r--qa/.gitignore1
-rw-r--r--qa/Dockerfile12
-rw-r--r--qa/Gemfile3
-rw-r--r--qa/Gemfile.lock38
-rw-r--r--qa/qa.rb35
-rw-r--r--qa/qa/flow/user.rb6
-rw-r--r--qa/qa/page/admin/overview/users/index.rb2
-rw-r--r--qa/qa/page/component/issuable/sidebar.rb6
-rw-r--r--qa/qa/page/component/issue_board/show.rb4
-rw-r--r--qa/qa/page/dashboard/snippet/index.rb3
-rw-r--r--qa/qa/page/group/members.rb2
-rw-r--r--qa/qa/page/group/menu.rb8
-rw-r--r--qa/qa/page/group/new.rb15
-rw-r--r--qa/qa/page/main/menu.rb96
-rw-r--r--qa/qa/page/project/branches/show.rb16
-rw-r--r--qa/qa/page/project/deployments/environments/index.rb (renamed from qa/qa/page/project/operations/environments/index.rb)2
-rw-r--r--qa/qa/page/project/deployments/environments/show.rb (renamed from qa/qa/page/project/operations/environments/show.rb)2
-rw-r--r--qa/qa/page/project/import/github.rb27
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/add.rb (renamed from qa/qa/page/project/operations/kubernetes/add.rb)2
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/add_existing.rb (renamed from qa/qa/page/project/operations/kubernetes/add_existing.rb)4
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/index.rb (renamed from qa/qa/page/project/operations/kubernetes/index.rb)2
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/show.rb (renamed from qa/qa/page/project/operations/kubernetes/show.rb)4
-rw-r--r--qa/qa/page/project/members.rb2
-rw-r--r--qa/qa/page/project/menu.rb25
-rw-r--r--qa/qa/page/project/monitor/incidents/index.rb (renamed from qa/qa/page/project/operations/incidents/index.rb)2
-rw-r--r--qa/qa/page/project/monitor/metrics/show.rb (renamed from qa/qa/page/project/operations/metrics/show.rb)4
-rw-r--r--qa/qa/page/project/settings/alerts.rb (renamed from qa/qa/page/project/settings/incidents.rb)4
-rw-r--r--qa/qa/page/project/settings/monitor.rb (renamed from qa/qa/page/project/settings/operations.rb)4
-rw-r--r--qa/qa/page/project/show.rb7
-rw-r--r--qa/qa/page/project/sub_menus/deployments.rb40
-rw-r--r--qa/qa/page/project/sub_menus/infrastructure.rb40
-rw-r--r--qa/qa/page/project/sub_menus/monitor.rb (renamed from qa/qa/page/project/sub_menus/operations.rb)32
-rw-r--r--qa/qa/page/project/sub_menus/project.rb6
-rw-r--r--qa/qa/page/project/sub_menus/settings.rb4
-rw-r--r--qa/qa/page/registration/sign_up.rb5
-rw-r--r--qa/qa/resource/group.rb39
-rw-r--r--qa/qa/resource/group_base.rb47
-rw-r--r--qa/qa/resource/group_label.rb25
-rw-r--r--qa/qa/resource/kubernetes_cluster/project_cluster.rb12
-rw-r--r--qa/qa/resource/label.rb61
-rw-r--r--qa/qa/resource/label_base.rb88
-rw-r--r--qa/qa/resource/project.rb138
-rw-r--r--qa/qa/resource/project_imported_from_github.rb14
-rw-r--r--qa/qa/resource/project_label.rb28
-rw-r--r--qa/qa/resource/sandbox.rb2
-rw-r--r--qa/qa/runtime/allure_report.rb85
-rw-r--r--qa/qa/runtime/env.rb7
-rw-r--r--qa/qa/runtime/scenario.rb8
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb57
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb143
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/snippet_index_page_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb34
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb2
-rw-r--r--qa/qa/tools/delete_projects.rb8
-rw-r--r--qa/qa/tools/delete_subgroups.rb8
-rw-r--r--qa/qa/tools/delete_test_ssh_keys.rb8
-rw-r--r--qa/qa/tools/generate_perf_testdata.rb28
-rw-r--r--qa/qa/tools/revoke_all_personal_access_tokens.rb4
-rw-r--r--qa/spec/spec_helper.rb5
-rw-r--r--qa/spec/specs/helpers/context_selector_spec.rb6
-rw-r--r--qa/spec/support/matchers/eventually_matcher.rb132
-rw-r--r--qa/tls_certificates/client/client.crt30
-rw-r--r--qa/tls_certificates/client/client.csr27
-rw-r--r--qa/tls_certificates/client/client.key51
-rw-r--r--qa/tls_certificates/client/client.pem113
-rw-r--r--qa/tls_certificates/client/client.pfxbin0 -> 7021 bytes
88 files changed, 1324 insertions, 461 deletions
diff --git a/qa/.gitignore b/qa/.gitignore
index 2095d5c722c..b54b8666e28 100644
--- a/qa/.gitignore
+++ b/qa/.gitignore
@@ -3,3 +3,4 @@ tmp/
.tool-versions
.ruby-gemset
urls.yml
+reports/
diff --git a/qa/Dockerfile b/qa/Dockerfile
index dda882dc5e6..81f207cbab9 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -38,6 +38,18 @@ RUN unzip chromedriver_linux64.zip -d /usr/local/bin
RUN rm -f chromedriver_linux64.zip
##
+# Install client certificate - Bug in Chrome Headless: https://gitlab.com/gitlab-org/gitlab/-/issues/331492
+#
+# RUN apt install -y libnss3-tools
+# RUN mkdir -p $HOME/.pki/nssdb
+# RUN certutil -N -d sql:$HOME/.pki/nssdb
+# COPY ./qa/tls_certificates/client/client.pfx /tmp/client.pfx
+# RUN pk12util -d sql:$HOME/.pki/nssdb -i /tmp/client.pfx -W ''
+# RUN mkdir -p /etc/opt/chrome/policies/managed
+# RUN echo '{ "AutoSelectCertificateForUrls": ["{\"pattern\":\"*\",\"filter\":{}}"] }' > /etc/opt/chrome/policies/managed/policy.json
+# RUN cat /etc/opt/chrome/policies/managed/policy.json
+
+##
# Install root certificate
#
RUN mkdir -p /usr/share/ca-certificates/gitlab
diff --git a/qa/Gemfile b/qa/Gemfile
index 8b3a9802000..0cb53ca99dc 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -3,7 +3,8 @@
source 'https://rubygems.org'
gem 'gitlab-qa'
-gem 'activesupport', '~> 6.0.3.3' # This should stay in sync with the root's Gemfile
+gem 'activesupport', '~> 6.1.3.2' # This should stay in sync with the root's Gemfile
+gem 'allure-rspec', '~> 2.14.1'
gem 'capybara', '~> 3.29.0'
gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 12.3.3'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 9bac86bad08..8b6c4ca0d3e 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -2,12 +2,12 @@ GEM
remote: https://rubygems.org/
specs:
abstract_type (0.0.7)
- activesupport (6.0.3.4)
+ activesupport (6.1.3.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- zeitwerk (~> 2.2, >= 2.2.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
adamantium (0.2.0)
ice_nine (~> 0.11.0)
memoizable (~> 0.4.0)
@@ -19,6 +19,14 @@ GEM
rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8)
+ allure-rspec (2.14.1)
+ allure-ruby-commons (= 2.14.1)
+ rspec-core (>= 3.8, < 4)
+ allure-ruby-commons (2.14.1)
+ mime-types (>= 3.3, < 4)
+ oj (>= 3.10, < 4)
+ require_all (>= 2, < 4)
+ uuid (>= 2.3, < 3)
ast (2.4.1)
binding_ninja (0.2.3)
byebug (9.1.0)
@@ -44,7 +52,7 @@ GEM
concord (0.1.5)
adamantium (~> 0.2.0)
equalizer (~> 0.0.9)
- concurrent-ruby (1.1.7)
+ concurrent-ruby (1.1.8)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.3)
@@ -66,7 +74,7 @@ GEM
http-accept (1.7.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
- i18n (1.8.5)
+ i18n (1.8.10)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
jwt (2.2.2)
@@ -74,6 +82,8 @@ GEM
rake
launchy (2.4.3)
addressable (~> 2.3)
+ macaddr (1.7.2)
+ systemu (~> 2.6.5)
memoizable (0.4.2)
thread_safe (~> 0.3, >= 0.3.1)
method_source (0.9.0)
@@ -82,7 +92,7 @@ GEM
mime-types-data (3.2020.0425)
mini_mime (1.0.2)
mini_portile2 (2.5.0)
- minitest (5.14.2)
+ minitest (5.14.4)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
@@ -96,6 +106,7 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
+ oj (3.11.5)
parallel (1.19.2)
parallel_tests (2.29.0)
parallel
@@ -119,6 +130,7 @@ GEM
rack (>= 1.0, < 3)
rake (12.3.3)
regexp_parser (1.6.0)
+ require_all (3.0.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
@@ -154,10 +166,11 @@ GEM
selenium-webdriver (3.142.6)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
+ systemu (2.6.5)
thread_safe (0.3.6)
timecop (0.9.1)
- tzinfo (1.2.9)
- thread_safe (~> 0.1)
+ tzinfo (2.0.4)
+ concurrent-ruby (~> 1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
@@ -169,6 +182,8 @@ GEM
equalizer (~> 0.0.9)
parser (>= 2.6.5)
procto (~> 0.0.2)
+ uuid (2.3.9)
+ macaddr (~> 1.0)
watir (6.18.0)
regexp_parser (>= 1.2, < 3)
selenium-webdriver (>= 3.8)
@@ -180,8 +195,9 @@ PLATFORMS
ruby
DEPENDENCIES
- activesupport (~> 6.0.3.3)
+ activesupport (~> 6.1.3.2)
airborne (~> 0.3.4)
+ allure-rspec (~> 2.14.1)
capybara (~> 3.29.0)
capybara-screenshot (~> 1.0.23)
chemlab (~> 0.5)
diff --git a/qa/qa.rb b/qa/qa.rb
index fafa428be41..aad40666065 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -45,6 +45,7 @@ module QA
autoload :IPAddress, 'qa/runtime/ip_address'
autoload :Search, 'qa/runtime/search'
autoload :ApplicationSettings, 'qa/runtime/application_settings'
+ autoload :AllureReport, 'qa/runtime/allure_report'
module API
autoload :Client, 'qa/runtime/api/client'
@@ -73,7 +74,9 @@ module QA
autoload :Issue, 'qa/resource/issue'
autoload :ProjectIssueNote, 'qa/resource/project_issue_note'
autoload :Project, 'qa/resource/project'
- autoload :Label, 'qa/resource/label'
+ autoload :LabelBase, 'qa/resource/label_base'
+ autoload :ProjectLabel, 'qa/resource/project_label'
+ autoload :GroupLabel, 'qa/resource/group_label'
autoload :MergeRequest, 'qa/resource/merge_request'
autoload :ProjectImportedFromGithub, 'qa/resource/project_imported_from_github'
autoload :MergeRequestFromFork, 'qa/resource/merge_request_from_fork'
@@ -335,8 +338,8 @@ module QA
autoload :Jenkins, 'qa/page/project/settings/services/jenkins'
autoload :Prometheus, 'qa/page/project/settings/services/prometheus'
end
- autoload :Operations, 'qa/page/project/settings/operations'
- autoload :Incidents, 'qa/page/project/settings/incidents'
+ autoload :Monitor, 'qa/page/project/settings/monitor'
+ autoload :Alerts, 'qa/page/project/settings/alerts'
autoload :Integrations, 'qa/page/project/settings/integrations'
end
@@ -344,7 +347,9 @@ module QA
autoload :CiCd, 'qa/page/project/sub_menus/ci_cd'
autoload :Common, 'qa/page/project/sub_menus/common'
autoload :Issues, 'qa/page/project/sub_menus/issues'
- autoload :Operations, 'qa/page/project/sub_menus/operations'
+ autoload :Monitor, 'qa/page/project/sub_menus/monitor'
+ autoload :Deployments, 'qa/page/project/sub_menus/deployments'
+ autoload :Infrastructure, 'qa/page/project/sub_menus/infrastructure'
autoload :Repository, 'qa/page/project/sub_menus/repository'
autoload :Settings, 'qa/page/project/sub_menus/settings'
autoload :Project, 'qa/page/project/sub_menus/project'
@@ -367,25 +372,29 @@ module QA
autoload :Index, 'qa/page/project/milestone/index'
end
- module Operations
+ module Deployments
module Environments
- autoload :Index, 'qa/page/project/operations/environments/index'
- autoload :Show, 'qa/page/project/operations/environments/show'
+ autoload :Index, 'qa/page/project/deployments/environments/index'
+ autoload :Show, 'qa/page/project/deployments/environments/show'
end
+ end
+ module Infrastructure
module Kubernetes
- autoload :Index, 'qa/page/project/operations/kubernetes/index'
- autoload :Add, 'qa/page/project/operations/kubernetes/add'
- autoload :AddExisting, 'qa/page/project/operations/kubernetes/add_existing'
- autoload :Show, 'qa/page/project/operations/kubernetes/show'
+ autoload :Index, 'qa/page/project/infrastructure/kubernetes/index'
+ autoload :Add, 'qa/page/project/infrastructure/kubernetes/add'
+ autoload :AddExisting, 'qa/page/project/infrastructure/kubernetes/add_existing'
+ autoload :Show, 'qa/page/project/infrastructure/kubernetes/show'
end
+ end
+ module Monitor
module Metrics
- autoload :Show, 'qa/page/project/operations/metrics/show'
+ autoload :Show, 'qa/page/project/monitor/metrics/show'
end
module Incidents
- autoload :Index, 'qa/page/project/operations/incidents/index'
+ autoload :Index, 'qa/page/project/monitor/incidents/index'
end
end
diff --git a/qa/qa/flow/user.rb b/qa/qa/flow/user.rb
index acc77cb9830..c0bd475adb7 100644
--- a/qa/qa/flow/user.rb
+++ b/qa/qa/flow/user.rb
@@ -9,13 +9,13 @@ module QA
Capybara.current_session
end
- def confirm_user(username)
+ def confirm_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(username)
- index.click_user(username)
+ index.search_user(user.email)
+ index.click_user(user.name)
end
Page::Admin::Overview::Users::Show.perform(&:confirm_user)
diff --git a/qa/qa/page/admin/overview/users/index.rb b/qa/qa/page/admin/overview/users/index.rb
index f8c79b4f72c..8a2c2303ff7 100644
--- a/qa/qa/page/admin/overview/users/index.rb
+++ b/qa/qa/page/admin/overview/users/index.rb
@@ -11,7 +11,7 @@ module QA
element :pending_approval_tab
end
- view 'app/views/admin/users/_user.html.haml' do
+ view 'app/assets/javascripts/admin/users/components/users_table.vue' do
element :user_row_content
end
diff --git a/qa/qa/page/component/issuable/sidebar.rb b/qa/qa/page/component/issuable/sidebar.rb
index 03c0811645f..3a9d316c321 100644
--- a/qa/qa/page/component/issuable/sidebar.rb
+++ b/qa/qa/page/component/issuable/sidebar.rb
@@ -30,7 +30,7 @@ module QA
element :labels_dropdown_content
end
- base.view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue' do
+ base.view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue' do
element :labels_edit_button
end
@@ -65,13 +65,13 @@ module QA
def has_assignee?(username)
within_element(:assignee_block) do
- has_text?(username, wait: 120)
+ has_text?(username, wait: 1)
end
end
def has_no_assignee?(username)
within_element(:assignee_block) do
- has_no_text?(username, wait: 120)
+ has_no_text?(username, wait: 1)
end
end
diff --git a/qa/qa/page/component/issue_board/show.rb b/qa/qa/page/component/issue_board/show.rb
index e0c8f73e1b0..1c1f7ab17f3 100644
--- a/qa/qa/page/component/issue_board/show.rb
+++ b/qa/qa/page/component/issue_board/show.rb
@@ -24,11 +24,11 @@ module QA
element :create_new_board_button
end
- view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue' do
+ view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue' do
element :labels_dropdown_content
end
- view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue' do
+ view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue' do
element :labels_edit_button
end
diff --git a/qa/qa/page/dashboard/snippet/index.rb b/qa/qa/page/dashboard/snippet/index.rb
index 63589c376f6..d8314509b1f 100644
--- a/qa/qa/page/dashboard/snippet/index.rb
+++ b/qa/qa/page/dashboard/snippet/index.rb
@@ -7,6 +7,9 @@ module QA
class Index < Page::Base
view 'app/views/layouts/header/_new_dropdown.html.haml' do
element :new_menu_toggle
+ end
+
+ view 'app/helpers/nav/new_dropdown_helper.rb' do
element :global_new_snippet_link
end
diff --git a/qa/qa/page/group/members.rb b/qa/qa/page/group/members.rb
index 68a169d5a7f..b526a4488b2 100644
--- a/qa/qa/page/group/members.rb
+++ b/qa/qa/page/group/members.rb
@@ -26,7 +26,7 @@ module QA
element :delete_member_button
end
- view 'app/views/groups/group_members/index.html.haml' do
+ view 'app/assets/javascripts/members/components/members_tabs.vue' do
element :groups_list_tab
end
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index 66e8b5d5863..9a3b129b6d2 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -12,6 +12,8 @@ module QA
element :group_members_item
element :group_milestones_link
element :group_settings
+ element :group_information_link
+ element :group_information_submenu
end
view 'app/views/groups/sidebar/_packages_settings.html.haml' do
@@ -24,8 +26,10 @@ module QA
end
def click_group_members_item
- within_sidebar do
- click_element(:group_members_item)
+ hover_element(:group_information_link) do
+ within_submenu(:group_information_submenu) do
+ click_element(:group_members_item)
+ end
end
end
diff --git a/qa/qa/page/group/new.rb b/qa/qa/page/group/new.rb
index 5a908266597..66afcf7547c 100644
--- a/qa/qa/page/group/new.rb
+++ b/qa/qa/page/group/new.rb
@@ -38,17 +38,32 @@ module QA
fill_element(:import_gitlab_token, token)
end
+ def click_import_group
+ click_on 'Import group'
+ end
+
+ def click_create_group
+ click_on 'Create group'
+ end
+
# Connect gitlab instance
#
# @param [String] gitlab_url
# @param [String] gitlab_token
# @return [void]
def connect_gitlab_instance(gitlab_url, gitlab_token)
+ # Wait until element is present and refresh if not in case feature flag did not kick in
+ wait_until(max_duration: 10) { has_element?(:import_gitlab_url, wait: 1) }
+
set_gitlab_url(gitlab_url)
set_gitlab_token(gitlab_token)
click_element(:connect_instance_button)
end
+
+ def switch_to_import_tab
+ click_element("import-group-pane_link")
+ end
end
end
end
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index f796f4c9475..760741a9630 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -19,25 +19,23 @@ module QA
element :todos_shortcut_button, required: true
end
- view 'app/views/layouts/nav/_dashboard.html.haml' do
- element :admin_area_link
- element :projects_dropdown, required: true
- element :groups_dropdown, required: true
- element :more_dropdown
- element :snippets_link
- element :groups_link
- element :activity_link
- element :milestones_link
+ view 'app/assets/javascripts/nav/components/top_nav_app.vue' do
+ element :navbar_dropdown
+ end
+
+ view 'app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue' do
+ element :menu_subview_container
end
- view 'app/views/layouts/nav/projects_dropdown/_show.html.haml' do
- element :projects_dropdown_sidebar
- element :your_projects_link
+ view 'lib/gitlab/nav/top_nav_menu_item.rb' do
+ element :menu_item_link
end
- view 'app/views/layouts/nav/groups_dropdown/_show.html.haml' do
- element :create_group_link
- element :import_group_link
+ view 'app/helpers/nav/top_nav_helper.rb' do
+ element :admin_area_link
+ element :projects_dropdown
+ element :groups_dropdown
+ element :snippets_link
end
view 'app/views/layouts/_search.html.haml' do
@@ -46,30 +44,32 @@ module QA
def go_to_groups
within_groups_menu do
- click_element :your_groups_link
+ click_element(:menu_item_link, title: 'Your groups')
end
end
- def go_to_import_group
+ def go_to_create_group
within_groups_menu do
- click_element :import_group_link
+ click_element(:menu_item_link, title: 'Create group')
end
end
def go_to_projects
- within_top_menu do
- click_element :projects_dropdown
+ within_projects_menu do
+ click_element(:menu_item_link, title: 'Your projects')
end
+ end
- page.within('.qa-projects-dropdown-sidebar') do
- click_element :your_projects_link
+ def go_to_create_project
+ within_projects_menu do
+ click_element(:menu_item_link, title: 'Create new project')
end
end
- def go_to_more_dropdown_option(option_name)
+ def go_to_menu_dropdown_option(option_name)
within_top_menu do
- click_element :more_dropdown
- click_element option_name
+ click_element(:navbar_dropdown, title: 'Menu')
+ click_element(option_name)
end
end
@@ -88,11 +88,11 @@ module QA
def go_to_admin_area
click_admin_area
- if has_text?('Enter Admin Mode', wait: 1.0)
- Admin::NewSession.perform do |new_session|
- new_session.set_password(Runtime::User.admin_password)
- new_session.click_enter_admin_mode
- end
+ return unless has_text?('Enter Admin Mode', wait: 1.0)
+
+ Admin::NewSession.perform do |new_session|
+ new_session.set_password(Runtime::User.admin_password)
+ new_session.click_enter_admin_mode
end
end
@@ -151,11 +151,17 @@ module QA
end
def has_admin_area_link?(wait: Capybara.default_max_wait_time)
- has_element?(:admin_area_link, wait: wait)
+ within_top_menu do
+ click_element(:navbar_dropdown, title: 'Menu')
+ has_element?(:admin_area_link, wait: wait)
+ end
end
def has_no_admin_area_link?(wait: Capybara.default_max_wait_time)
- has_no_element?(:admin_area_link, wait: wait)
+ within_top_menu do
+ click_element(:navbar_dropdown, title: 'Menu')
+ has_no_element?(:admin_area_link, wait: wait)
+ end
end
def click_stop_impersonation_link
@@ -164,32 +170,32 @@ module QA
private
- def within_top_menu
- within_element(:navbar) do
- yield
- end
+ def within_top_menu(&block)
+ within_element(:navbar, &block)
end
- def within_user_menu
+ def within_user_menu(&block)
within_top_menu do
click_element :user_avatar
- within_element(:user_menu) do
- yield
- end
+ within_element(:user_menu, &block)
end
end
def within_groups_menu(&block)
- within_top_menu do
- click_element :groups_dropdown
- end
+ go_to_menu_dropdown_option(:groups_dropdown)
+
+ within_element(:menu_subview_container, &block)
+ end
+
+ def within_projects_menu(&block)
+ go_to_menu_dropdown_option(:projects_dropdown)
- page.within('.qa-groups-dropdown-sidebar', &block)
+ within_element(:menu_subview_container, &block)
end
def click_admin_area
- within_top_menu { click_element :admin_area_link }
+ go_to_menu_dropdown_option(:admin_area_link)
end
end
end
diff --git a/qa/qa/page/project/branches/show.rb b/qa/qa/page/project/branches/show.rb
index 63021df30f6..afec0e27a0b 100644
--- a/qa/qa/page/project/branches/show.rb
+++ b/qa/qa/page/project/branches/show.rb
@@ -5,13 +5,23 @@ module QA
module Project
module Branches
class Show < Page::Base
+ view 'app/assets/javascripts/branches/components/delete_branch_button.vue' do
+ element :delete_branch_button
+ end
+
+ view 'app/assets/javascripts/branches/components/delete_branch_modal.vue' do
+ element :delete_branch_confirmation_button
+ end
+
view 'app/views/projects/branches/_branch.html.haml' do
element :remove_btn
element :branch_name
end
+
view 'app/views/projects/branches/_panel.html.haml' do
element :all_branches
end
+
view 'app/views/projects/branches/index.html.haml' do
element :delete_merged_branches
end
@@ -19,12 +29,12 @@ module QA
def delete_branch(branch_name)
within_element(:all_branches) do
within(".js-branch-#{branch_name}") do
- accept_alert do
- click_element(:remove_btn)
- end
+ click_element(:delete_branch_button)
end
end
+ click_element(:delete_branch_confirmation_button)
+
finished_loading?
end
diff --git a/qa/qa/page/project/operations/environments/index.rb b/qa/qa/page/project/deployments/environments/index.rb
index 6b46fa4985a..598e1f26815 100644
--- a/qa/qa/page/project/operations/environments/index.rb
+++ b/qa/qa/page/project/deployments/environments/index.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Deployments
module Environments
class Index < Page::Base
view 'app/assets/javascripts/environments/components/environment_item.vue' do
diff --git a/qa/qa/page/project/operations/environments/show.rb b/qa/qa/page/project/deployments/environments/show.rb
index aa88c218c89..48e4850d3be 100644
--- a/qa/qa/page/project/operations/environments/show.rb
+++ b/qa/qa/page/project/deployments/environments/show.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Deployments
module Environments
class Show < Page::Base
view 'app/views/projects/environments/_external_url.html.haml' do
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index 58c82fa14c1..dc683f7314b 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -32,24 +32,20 @@ module QA
end
def import!(full_path, name)
- unless already_imported(full_path)
- choose_test_namespace(full_path)
- set_path(full_path, name)
- import_project(full_path)
- wait_for_success
- end
+ return if already_imported(full_path)
- go_to_project(name)
+ choose_test_namespace(full_path)
+ set_path(full_path, name)
+ import_project(full_path)
+ wait_for_success
end
private
- def within_repo_path(full_path)
+ def within_repo_path(full_path, &block)
project_import_row = find_element(:project_import_row, text: full_path)
- within(project_import_row) do
- yield
- end
+ within(project_import_row, &block)
end
def choose_test_namespace(full_path)
@@ -75,8 +71,13 @@ module QA
def wait_for_success
# TODO: set reload:false and remove skip_finished_loading_check_on_refresh when
# https://gitlab.com/gitlab-org/gitlab/-/issues/292861 is fixed
- wait_until(max_duration: 60, sleep_interval: 5.0, reload: true, skip_finished_loading_check_on_refresh: true) do
- page.has_no_content?('Importing 1 repository', wait: 3.0)
+ wait_until(
+ max_duration: 90,
+ sleep_interval: 5.0,
+ reload: true,
+ skip_finished_loading_check_on_refresh: true
+ ) do
+ page.has_no_content?('Importing 1 repository')
end
end
diff --git a/qa/qa/page/project/operations/kubernetes/add.rb b/qa/qa/page/project/infrastructure/kubernetes/add.rb
index 9a6ea99ac18..e2d50c1bcf1 100644
--- a/qa/qa/page/project/operations/kubernetes/add.rb
+++ b/qa/qa/page/project/infrastructure/kubernetes/add.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Infrastructure
module Kubernetes
class Add < Page::Base
view 'app/views/clusters/clusters/new.html.haml' do
diff --git a/qa/qa/page/project/operations/kubernetes/add_existing.rb b/qa/qa/page/project/infrastructure/kubernetes/add_existing.rb
index 59f59ca9966..689c2a31c4f 100644
--- a/qa/qa/page/project/operations/kubernetes/add_existing.rb
+++ b/qa/qa/page/project/infrastructure/kubernetes/add_existing.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Infrastructure
module Kubernetes
class AddExisting < Page::Base
view 'app/views/clusters/clusters/user/_form.html.haml' do
@@ -32,7 +32,7 @@ module QA
end
def add_cluster!
- click_element :add_kubernetes_cluster_button, Page::Project::Operations::Kubernetes::Show
+ click_element :add_kubernetes_cluster_button, Page::Project::Infrastructure::Kubernetes::Show
end
def uncheck_rbac!
diff --git a/qa/qa/page/project/operations/kubernetes/index.rb b/qa/qa/page/project/infrastructure/kubernetes/index.rb
index ca41dddaca2..bdcaf7ffaff 100644
--- a/qa/qa/page/project/operations/kubernetes/index.rb
+++ b/qa/qa/page/project/infrastructure/kubernetes/index.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Infrastructure
module Kubernetes
class Index < Page::Base
view 'app/views/clusters/clusters/_empty_state.html.haml' do
diff --git a/qa/qa/page/project/operations/kubernetes/show.rb b/qa/qa/page/project/infrastructure/kubernetes/show.rb
index 3bb51d2d579..e3b4f8fe4d9 100644
--- a/qa/qa/page/project/operations/kubernetes/show.rb
+++ b/qa/qa/page/project/infrastructure/kubernetes/show.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Infrastructure
module Kubernetes
class Show < Page::Base
view 'app/assets/javascripts/clusters/components/applications.vue' do
@@ -77,7 +77,7 @@ module QA
end
def save_domain
- click_element :save_changes_button, Page::Project::Operations::Kubernetes::Show
+ click_element :save_changes_button, Page::Project::Infrastructure::Kubernetes::Show
end
def wait_for_cluster_health
diff --git a/qa/qa/page/project/members.rb b/qa/qa/page/project/members.rb
index 09264d95aed..eeb589d6ca8 100644
--- a/qa/qa/page/project/members.rb
+++ b/qa/qa/page/project/members.rb
@@ -6,7 +6,7 @@ module QA
class Members < Page::Base
include QA::Page::Component::InviteMembersModal
- view 'app/views/projects/project_members/index.html.haml' do
+ view 'app/assets/javascripts/members/components/members_tabs.vue' do
element :groups_list_tab
end
diff --git a/qa/qa/page/project/menu.rb b/qa/qa/page/project/menu.rb
index ffabaf30374..db70d3e1d02 100644
--- a/qa/qa/page/project/menu.rb
+++ b/qa/qa/page/project/menu.rb
@@ -8,7 +8,9 @@ module QA
include SubMenus::Project
include SubMenus::CiCd
include SubMenus::Issues
- include SubMenus::Operations
+ include SubMenus::Deployments
+ include SubMenus::Monitor
+ include SubMenus::Infrastructure
include SubMenus::Repository
include SubMenus::Settings
include SubMenus::Packages
@@ -26,8 +28,10 @@ module QA
end
def click_activity
- within_sidebar do
- click_element(:sidebar_menu_item_link, menu_item: 'Activity')
+ hover_project_information do
+ within_submenu do
+ click_element(:sidebar_menu_item_link, menu_item: 'Activity')
+ end
end
end
@@ -38,8 +42,21 @@ module QA
end
def click_members
+ hover_project_information do
+ within_submenu do
+ click_element(:sidebar_menu_item_link, menu_item: 'Members')
+ end
+ end
+ end
+
+ private
+
+ def hover_project_information
within_sidebar do
- click_element(:sidebar_menu_link, menu_item: 'Members')
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Project information')
+ find_element(:sidebar_menu_link, menu_item: 'Project information').hover
+
+ yield
end
end
end
diff --git a/qa/qa/page/project/operations/incidents/index.rb b/qa/qa/page/project/monitor/incidents/index.rb
index fd0c5253a7f..9317cb27562 100644
--- a/qa/qa/page/project/operations/incidents/index.rb
+++ b/qa/qa/page/project/monitor/incidents/index.rb
@@ -3,7 +3,7 @@
module QA
module Page
module Project
- module Operations
+ module Monitor
module Incidents
class Index < Page::Base
view 'app/assets/javascripts/incidents/components/incidents_list.vue' do
diff --git a/qa/qa/page/project/operations/metrics/show.rb b/qa/qa/page/project/monitor/metrics/show.rb
index 22a7f1eed8f..07ceb108fa3 100644
--- a/qa/qa/page/project/operations/metrics/show.rb
+++ b/qa/qa/page/project/monitor/metrics/show.rb
@@ -5,7 +5,7 @@ require 'securerandom'
module QA
module Page
module Project
- module Operations
+ module Monitor
module Metrics
class Show < Page::Base
EXPECTED_TITLE = 'Memory Usage (Total)'
@@ -134,4 +134,4 @@ module QA
end
end
-QA::Page::Project::Operations::Metrics::Show.prepend_mod_with('Page::Project::Operations::Metrics::Show', namespace: QA)
+QA::Page::Project::Monitor::Metrics::Show.prepend_mod_with('Page::Project::Monitor::Metrics::Show', namespace: QA)
diff --git a/qa/qa/page/project/settings/incidents.rb b/qa/qa/page/project/settings/alerts.rb
index 610129851d9..be9b61ded80 100644
--- a/qa/qa/page/project/settings/incidents.rb
+++ b/qa/qa/page/project/settings/alerts.rb
@@ -4,8 +4,8 @@ module QA
module Page
module Project
module Settings
- class Incidents < Page::Base
- view 'app/assets/javascripts/incidents_settings/components/alerts_form.vue' do
+ class Alerts < Page::Base
+ view 'app/assets/javascripts/alerts_settings/components/alerts_form.vue' do
element :create_issue_checkbox
element :incident_templates_dropdown
element :save_changes_button
diff --git a/qa/qa/page/project/settings/operations.rb b/qa/qa/page/project/settings/monitor.rb
index 12dcb064807..87fb0698897 100644
--- a/qa/qa/page/project/settings/operations.rb
+++ b/qa/qa/page/project/settings/monitor.rb
@@ -4,7 +4,7 @@ module QA
module Page
module Project
module Settings
- class Operations < Page::Base
+ class Monitor < Page::Base
include QA::Page::Settings::Common
view 'app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue' do
@@ -13,7 +13,7 @@ module QA
def expand_incidents(&block)
expand_content(:incidents_settings_content) do
- Settings::Incidents.perform(&block)
+ Settings::Alerts.perform(&block)
end
end
end
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index c174d4b0c3f..6e5097c3812 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -24,7 +24,10 @@ module QA
view 'app/views/layouts/header/_new_dropdown.html.haml' do
element :new_menu_toggle
- element :new_issue_link, "link_to _('New issue'), new_project_issue_path(@project)" # rubocop:disable QA/ElementWithPattern
+ end
+
+ view 'app/helpers/nav/new_dropdown_helper.rb' do
+ element :new_issue_link
end
view 'app/views/projects/_last_push.html.haml' do
@@ -115,7 +118,7 @@ module QA
def go_to_new_issue
click_element :new_menu_toggle
- click_link 'New issue'
+ click_element(:new_issue_link)
end
def has_file?(name)
diff --git a/qa/qa/page/project/sub_menus/deployments.rb b/qa/qa/page/project/sub_menus/deployments.rb
new file mode 100644
index 00000000000..24243cb2436
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/deployments.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module Deployments
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+ end
+ end
+
+ def go_to_deployments_environments
+ hover_deployments do
+ within_submenu do
+ click_element(:sidebar_menu_item_link, menu_item: 'Environments')
+ end
+ end
+ end
+
+ private
+
+ def hover_deployments
+ within_sidebar do
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Deployments')
+ find_element(:sidebar_menu_link, menu_item: 'Deployments').hover
+
+ yield
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/infrastructure.rb b/qa/qa/page/project/sub_menus/infrastructure.rb
new file mode 100644
index 00000000000..2c207022c8d
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/infrastructure.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module Infrastructure
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
+ include QA::Page::Project::SubMenus::Common
+ end
+ end
+
+ def go_to_infrastructure_kubernetes
+ hover_infrastructure do
+ within_submenu do
+ click_link('Kubernetes clusters')
+ end
+ end
+ end
+
+ private
+
+ def hover_infrastructure
+ within_sidebar do
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Infrastructure')
+ find_element(:sidebar_menu_link, menu_item: 'Infrastructure').hover
+
+ yield
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/operations.rb b/qa/qa/page/project/sub_menus/monitor.rb
index 077da697a63..e3593e0a257 100644
--- a/qa/qa/page/project/sub_menus/operations.rb
+++ b/qa/qa/page/project/sub_menus/monitor.rb
@@ -4,7 +4,7 @@ module QA
module Page
module Project
module SubMenus
- module Operations
+ module Monitor
extend QA::Page::PageConcern
def self.included(base)
@@ -15,32 +15,16 @@ module QA
end
end
- def go_to_operations_environments
- hover_operations do
- within_submenu do
- click_element(:sidebar_menu_item_link, menu_item: 'Environments')
- end
- end
- end
-
- def go_to_operations_metrics
- hover_operations do
+ def go_to_monitor_metrics
+ hover_monitor do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'Metrics')
end
end
end
- def go_to_operations_kubernetes
- hover_operations do
- within_submenu do
- click_link('Kubernetes')
- end
- end
- end
-
- def go_to_operations_incidents
- hover_operations do
+ def go_to_monitor_incidents
+ hover_monitor do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'Incidents')
end
@@ -49,10 +33,10 @@ module QA
private
- def hover_operations
+ def hover_monitor
within_sidebar do
- scroll_to_element(:sidebar_menu_link, menu_item: 'Operations')
- find_element(:sidebar_menu_link, menu_item: 'Operations').hover
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Monitor')
+ find_element(:sidebar_menu_link, menu_item: 'Monitor').hover
yield
end
diff --git a/qa/qa/page/project/sub_menus/project.rb b/qa/qa/page/project/sub_menus/project.rb
index 5499a0f71e3..cd08715bcd8 100644
--- a/qa/qa/page/project/sub_menus/project.rb
+++ b/qa/qa/page/project/sub_menus/project.rb
@@ -12,13 +12,17 @@ module QA
base.class_eval do
include QA::Page::Project::SubMenus::Common
+
+ view 'app/views/shared/nav/_scope_menu_body.html.haml' do
+ element :project_scope_link
+ end
end
end
def click_project
retry_on_exception do
within_sidebar do
- click_element(:sidebar_menu_link, menu_item: 'Project overview')
+ click_element(:project_scope_link)
end
end
end
diff --git a/qa/qa/page/project/sub_menus/settings.rb b/qa/qa/page/project/sub_menus/settings.rb
index 80f62c8efde..f35d27e658d 100644
--- a/qa/qa/page/project/sub_menus/settings.rb
+++ b/qa/qa/page/project/sub_menus/settings.rb
@@ -53,10 +53,10 @@ module QA
end
end
- def go_to_operations_settings
+ def go_to_monitor_settings
hover_settings do
within_submenu do
- click_element(:sidebar_menu_item_link, menu_item: 'Operations')
+ click_element(:sidebar_menu_item_link, menu_item: 'Monitor')
end
end
end
diff --git a/qa/qa/page/registration/sign_up.rb b/qa/qa/page/registration/sign_up.rb
index 0fb4b466e62..6d1b9cb3615 100644
--- a/qa/qa/page/registration/sign_up.rb
+++ b/qa/qa/page/registration/sign_up.rb
@@ -7,12 +7,15 @@ module QA
view 'app/views/devise/shared/_signup_box.html.haml' do
element :new_user_first_name_field
element :new_user_last_name_field
- element :new_user_username_field
element :new_user_email_field
element :new_user_password_field
element :new_user_register_button
end
+ view 'app/helpers/registrations_helper.rb' do
+ element :new_user_username_field
+ end
+
view 'app/views/registrations/welcome/show.html.haml' do
element :get_started_button
end
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index c7565871b0b..0f06113f85b 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -5,6 +5,10 @@ module QA
class Group < GroupBase
attr_accessor :description
+ attribute :full_path do
+ determine_full_path
+ end
+
attribute :sandbox do
Sandbox.fabricate_via_api! do |sandbox|
sandbox.api_client = api_client
@@ -29,6 +33,7 @@ module QA
group_show.go_to_new_subgroup
Page::Group::New.perform do |group_new|
+ group_new.click_create_group
group_new.set_path(path)
group_new.set_visibility('Public')
group_new.create
@@ -47,10 +52,16 @@ module QA
resource_web_url(api_get)
rescue ResourceNotFoundError
super
+
+ Support::Retrier.retry_on_exception(sleep_interval: 5) do
+ resource = resource_web_url(api_get)
+ populate(:runners_token)
+ resource
+ end
end
def api_get_path
- "/groups/#{CGI.escape("#{sandbox.path}/#{path}")}"
+ "/groups/#{CGI.escape(determine_full_path)}"
end
def api_post_body
@@ -93,6 +104,32 @@ module QA
'Timed out while waiting for the group repository storage move to finish'
)
end
+
+ private
+
+ # Determine the path up to the root group.
+ #
+ # This is equivalent to the full_path API attribute. We can't use the full_path attribute
+ # because it depends on the group being fabricated first, and we use this method to help
+ # _check_ if the group exists.
+ #
+ # @param [QA::Resource::GroupBase] sandbox the immediate parent group of this group
+ # @param [String] path the path name of this group (the leaf, not the full path)
+ # @return [String]
+ def determine_full_path
+ determine_parent_group_paths(sandbox, path)
+ end
+
+ # Recursively traverse the parents of this group up to the root group.
+ #
+ # @param [QA::Resource::GroupBase] parent the immediate parent group
+ # @param [String] path the path traversed so far
+ # @return [String]
+ def determine_parent_group_paths(parent, path)
+ return "#{parent.path}/#{path}" unless parent.respond_to?(:sandbox)
+
+ determine_parent_group_paths(parent.sandbox, "#{parent.path}/#{path}")
+ end
end
end
end
diff --git a/qa/qa/resource/group_base.rb b/qa/qa/resource/group_base.rb
index bdd442a1c8b..025d98f50e0 100644
--- a/qa/qa/resource/group_base.rb
+++ b/qa/qa/resource/group_base.rb
@@ -14,6 +14,29 @@ module QA
attribute :name
attribute :full_path
+ # Get group labels
+ #
+ # @return [Array<QA::Resource::GroupLabel>]
+ def labels
+ parse_body(api_get_from("#{api_get_path}/labels")).map do |label|
+ GroupLabel.new.tap do |resource|
+ resource.api_client = api_client
+ resource.group = self
+ resource.id = label[:id]
+ resource.title = label[:name]
+ resource.description = label[:description]
+ resource.color = label[:color]
+ end
+ end
+ end
+
+ # API get path
+ #
+ # @return [String]
+ def api_get_path
+ raise NotImplementedError
+ end
+
# API post path
#
# @return [String]
@@ -58,15 +81,21 @@ module QA
def comparable_group
reload! if api_response.nil?
- api_resource.except(
- :id,
- :web_url,
- :visibility,
- :full_name,
- :full_path,
- :created_at,
- :parent_id,
- :runners_token
+ api_resource.slice(
+ :name,
+ :path,
+ :description,
+ :emails_disabled,
+ :lfs_enabled,
+ :mentions_disabled,
+ :project_creation_level,
+ :request_access_enabled,
+ :require_two_factor_authentication,
+ :share_with_group_lock,
+ :subgroup_creation_level,
+ :two_factor_grace_perion
+ # TODO: Add back visibility comparison once https://gitlab.com/gitlab-org/gitlab/-/issues/331252 is fixed
+ # :visibility
)
end
end
diff --git a/qa/qa/resource/group_label.rb b/qa/qa/resource/group_label.rb
new file mode 100644
index 00000000000..d512dfc6a89
--- /dev/null
+++ b/qa/qa/resource/group_label.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class GroupLabel < LabelBase
+ attribute :group do
+ Group.fabricate! do |resource|
+ resource.name = 'group-with-label'
+ end
+ end
+
+ def fabricate!
+ raise NotImplementedError
+ end
+
+ def api_post_path
+ "/groups/#{CGI.escape(group.full_path)}/labels"
+ end
+
+ def api_get_path
+ "/groups/#{CGI.escape(group.full_path)}/labels/#{id}"
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/kubernetes_cluster/project_cluster.rb b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
index 78a24cdb677..b66a75d978b 100644
--- a/qa/qa/resource/kubernetes_cluster/project_cluster.rb
+++ b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
@@ -12,22 +12,22 @@ module QA
end
attribute :ingress_ip do
- Page::Project::Operations::Kubernetes::Show.perform(&:ingress_ip)
+ Page::Project::Infrastructure::Kubernetes::Show.perform(&:ingress_ip)
end
def fabricate!
project.visit!
Page::Project::Menu.perform(
- &:go_to_operations_kubernetes)
+ &:go_to_infrastructure_kubernetes)
- Page::Project::Operations::Kubernetes::Index.perform(
+ Page::Project::Infrastructure::Kubernetes::Index.perform(
&:add_kubernetes_cluster)
- Page::Project::Operations::Kubernetes::Add.perform(
+ Page::Project::Infrastructure::Kubernetes::Add.perform(
&:add_existing_cluster)
- Page::Project::Operations::Kubernetes::AddExisting.perform do |cluster_page|
+ Page::Project::Infrastructure::Kubernetes::AddExisting.perform do |cluster_page|
cluster_page.set_cluster_name(@cluster.cluster_name)
cluster_page.set_api_url(@cluster.api_url)
cluster_page.set_ca_certificate(@cluster.ca_certificate)
@@ -36,7 +36,7 @@ module QA
cluster_page.add_cluster!
end
- Page::Project::Operations::Kubernetes::Show.perform do |show|
+ Page::Project::Infrastructure::Kubernetes::Show.perform do |show|
# We must wait a few seconds for permissions to be set up correctly for new cluster
sleep 25
diff --git a/qa/qa/resource/label.rb b/qa/qa/resource/label.rb
deleted file mode 100644
index 6b0b0184130..00000000000
--- a/qa/qa/resource/label.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require 'securerandom'
-
-module QA
- module Resource
- class Label < Base
- attr_accessor :description, :color
-
- attribute :id
- attribute :title
-
- attribute :project do
- Project.fabricate! do |resource|
- resource.name = 'project-with-label'
- end
- end
-
- def initialize
- @title = "qa-test-#{SecureRandom.hex(8)}"
- @description = 'This is a test label'
- @color = '#0033CC'
- end
-
- def fabricate!
- project.visit!
-
- Page::Project::Menu.perform(&:go_to_labels)
- Page::Label::Index.perform(&:click_new_label_button)
-
- Page::Label::New.perform do |new_page|
- new_page.fill_title(@title)
- new_page.fill_description(@description)
- new_page.fill_color(@color)
- new_page.click_label_create_button
- end
- end
-
- def resource_web_url(resource)
- super
- rescue ResourceURLMissingError
- # this particular resource does not expose a web_url property
- end
-
- def api_get_path
- raise NotImplementedError, "The Labels API doesn't expose a single-resource endpoint so this method cannot be properly implemented."
- end
-
- def api_post_path
- "/projects/#{project.id}/labels"
- end
-
- def api_post_body
- {
- color: @color,
- name: @title
- }
- end
- end
- end
-end
diff --git a/qa/qa/resource/label_base.rb b/qa/qa/resource/label_base.rb
new file mode 100644
index 00000000000..14ddd0809ea
--- /dev/null
+++ b/qa/qa/resource/label_base.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'securerandom'
+
+module QA
+ module Resource
+ # Base label class for GroupLabel and ProjectLabel
+ #
+ class LabelBase < Base
+ attr_accessor :title, :description, :color
+
+ attribute :id
+ attribute :description_html
+ attribute :text_color
+ attribute :subscribed
+
+ def initialize
+ @title = "qa-test-#{SecureRandom.hex(8)}"
+ @description = 'This is a test label'
+ @color = '#0033CC'
+ end
+
+ def fabricate!
+ Page::Label::Index.perform(&:click_new_label_button)
+ Page::Label::New.perform do |new_page|
+ new_page.fill_title(title)
+ new_page.fill_description(description)
+ new_page.fill_color(color)
+ new_page.click_label_create_button
+ end
+ end
+
+ # Resource web url
+ #
+ # @param [Hash] resource
+ # @return [String]
+ def resource_web_url(resource)
+ super
+ rescue ResourceURLMissingError
+ # this particular resource does not expose a web_url property
+ end
+
+ # Params for label creation
+ #
+ # @return [Hash]
+ def api_post_body
+ {
+ name: title,
+ color: color,
+ description: description
+ }
+ end
+
+ # Object comparison
+ #
+ # @param [QA::Resource::GroupBase] other
+ # @return [Boolean]
+ def ==(other)
+ other.is_a?(LabelBase) && comparable_label == other.comparable_label
+ end
+
+ # Override inspect for a better rspec failure diff output
+ #
+ # @return [String]
+ def inspect
+ JSON.pretty_generate(comparable_label)
+ end
+
+ # protected
+
+ # Return subset of fields for comparing groups
+ #
+ # @return [Hash]
+ def comparable_label
+ reload! unless api_response
+
+ api_response.slice(
+ :name,
+ :description,
+ :description_html,
+ :color,
+ :text_color,
+ :subscribed
+ )
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index 96a60381146..f8cf816d6e4 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -10,10 +10,10 @@ module QA
include Visibility
attr_accessor :repository_storage # requires admin access
- attr_writer :initialize_with_readme
- attr_writer :auto_devops_enabled
- attr_writer :github_personal_access_token
- attr_writer :github_repository_path
+ attr_writer :initialize_with_readme,
+ :auto_devops_enabled,
+ :github_personal_access_token,
+ :github_repository_path
attribute :id
attribute :name
@@ -40,15 +40,11 @@ module QA
end
attribute :repository_ssh_location do
- Page::Project::Show.perform do |show|
- show.repository_clone_ssh_location
- end
+ Page::Project::Show.perform(&:repository_clone_ssh_location)
end
attribute :repository_http_location do
- Page::Project::Show.perform do |show|
- show.repository_clone_http_location
- end
+ Page::Project::Show.perform(&:repository_clone_http_location)
end
def initialize
@@ -104,7 +100,7 @@ module QA
def has_file?(file_path)
response = repository_tree
- raise ResourceNotFoundError, "#{response[:message]}" if response.is_a?(Hash) && response.has_key?(:message)
+ raise ResourceNotFoundError, (response[:message]).to_s if response.is_a?(Hash) && response.has_key?(:message)
response.any? { |file| file[:path] == file_path }
end
@@ -115,14 +111,14 @@ module QA
def has_branches?(branches)
branches.all? do |branch|
- response = get(Runtime::API::Request.new(api_client, "#{api_repository_branches_path}/#{branch}").url)
+ response = get(request_url("#{api_repository_branches_path}/#{branch}"))
response.code == HTTP_STATUS_OK
end
end
def has_tags?(tags)
tags.all? do |tag|
- response = get(Runtime::API::Request.new(api_client, "#{api_repository_tags_path}/#{tag}").url)
+ response = get(request_url("#{api_repository_tags_path}/#{tag}"))
response.code == HTTP_STATUS_OK
end
end
@@ -135,6 +131,18 @@ module QA
"/projects/#{id}"
end
+ def api_put_path
+ "/projects/#{id}"
+ end
+
+ def api_post_path
+ '/projects'
+ end
+
+ def api_delete_path
+ "/projects/#{id}"
+ end
+
def api_get_archive_path(type = 'tar.gz')
"#{api_get_path}/repository/archive.#{type}"
end
@@ -183,12 +191,20 @@ module QA
"#{api_get_path}/pipeline_schedules"
end
- def api_put_path
- "/projects/#{id}"
+ def api_issues_path
+ "#{api_get_path}/issues"
end
- def api_post_path
- '/projects'
+ def api_labels_path
+ "#{api_get_path}/labels"
+ end
+
+ def api_milestones_path
+ "#{api_get_path}/milestones"
+ end
+
+ def api_wikis_path
+ "#{api_get_path}/wikis"
end
def api_post_body
@@ -211,25 +227,25 @@ module QA
post_body
end
- def api_delete_path
- "/projects/#{id}"
- end
-
def change_repository_storage(new_storage)
put_body = { repository_storage: new_storage }
- response = put Runtime::API::Request.new(api_client, api_put_path).url, put_body
+ response = put(request_url(api_put_path), put_body)
unless response.code == HTTP_STATUS_OK
- raise ResourceUpdateFailedError, "Could not change repository storage to #{new_storage}. Request returned (#{response.code}): `#{response}`."
+ raise(
+ ResourceUpdateFailedError,
+ "Could not change repository storage to #{new_storage}. Request returned (#{response.code}): `#{response}`."
+ )
end
- wait_until(sleep_interval: 1) { Runtime::API::RepositoryStorageMoves.has_status?(self, 'finished', new_storage) }
+ wait_until(sleep_interval: 1) do
+ Runtime::API::RepositoryStorageMoves.has_status?(self, 'finished', new_storage)
+ end
rescue Support::Repeater::RepeaterConditionExceededError
- raise Runtime::API::RepositoryStorageMoves::RepositoryStorageMovesError, 'Timed out while waiting for the repository storage move to finish'
- end
-
- def commits
- parse_body(get(Runtime::API::Request.new(api_client, api_commits_path).url))
+ raise(
+ Runtime::API::RepositoryStorageMoves::RepositoryStorageMovesError,
+ 'Timed out while waiting for the repository storage move to finish'
+ )
end
def default_branch
@@ -237,7 +253,7 @@ module QA
end
def import_status
- response = get Runtime::API::Request.new(api_client, "/projects/#{id}/import").url
+ response = get(request_url("/projects/#{id}/import"))
unless response.code == HTTP_STATUS_OK
raise ResourceQueryError, "Could not get import status. Request returned (#{response.code}): `#{response}`."
@@ -250,8 +266,14 @@ module QA
result[:import_status]
end
+ def commits
+ response = get(request_url(api_commits_path))
+ parse_body(response)
+ end
+
def merge_requests
- parse_body(get(Runtime::API::Request.new(api_client, api_merge_requests_path).url))
+ response = get(request_url(api_merge_requests_path))
+ parse_body(response)
end
def merge_request_with_title(title)
@@ -259,43 +281,65 @@ module QA
end
def runners(tag_list: nil)
- response = if tag_list
- get Runtime::API::Request.new(api_client, "#{api_runners_path}?tag_list=#{tag_list.compact.join(',')}").url
- else
- get Runtime::API::Request.new(api_client, "#{api_runners_path}").url
- end
+ url = tag_list ? "#{api_runners_path}?tag_list=#{tag_list.compact.join(',')}" : api_runners_path
+ response = get(request_url(url, per_page: '100'))
parse_body(response)
end
def registry_repositories
- response = get Runtime::API::Request.new(api_client, "#{api_registry_repositories_path}").url
+ response = get(request_url(api_registry_repositories_path))
parse_body(response)
end
def packages
- response = get Runtime::API::Request.new(api_client, "#{api_packages_path}").url
+ response = get(request_url(api_packages_path))
parse_body(response)
end
def repository_branches
- parse_body(get(Runtime::API::Request.new(api_client, api_repository_branches_path).url))
+ response = get(request_url(api_repository_branches_path))
+ parse_body(response)
end
def repository_tags
- parse_body(get(Runtime::API::Request.new(api_client, api_repository_tags_path).url))
+ response = get(request_url(api_repository_tags_path))
+ parse_body(response)
end
def repository_tree
- parse_body(get(Runtime::API::Request.new(api_client, api_repository_tree_path).url))
+ response = get(request_url(api_repository_tree_path))
+ parse_body(response)
end
def pipelines
- parse_body(get(Runtime::API::Request.new(api_client, api_pipelines_path).url))
+ response = get(request_url(api_pipelines_path))
+ parse_body(response)
end
def pipeline_schedules
- parse_body(get(Runtime::API::Request.new(api_client, api_pipeline_schedules_path).url))
+ response = get(request_url(api_pipeline_schedules_path))
+ parse_body(response)
+ end
+
+ def issues
+ response = get(request_url(api_issues_path))
+ parse_body(response)
+ end
+
+ def labels
+ response = get(request_url(api_labels_path))
+ parse_body(response)
+ end
+
+ def milestones
+ response = get(request_url(api_milestones_path))
+ parse_body(response)
+ end
+
+ def wikis
+ response = get(request_url(api_wikis_path))
+ parse_body(response)
end
private
@@ -307,6 +351,14 @@ module QA
Git::Location.new(api_resource[:http_url_to_repo])
api_resource
end
+
+ # Get api request url
+ #
+ # @param [String] path
+ # @return [String]
+ def request_url(path, **opts)
+ Runtime::API::Request.new(api_client, path, **opts).url
+ end
end
end
end
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index b06a7fe4e3d..93cd166a191 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -7,23 +7,19 @@ module QA
class ProjectImportedFromGithub < Resource::Project
def fabricate!
self.import = true
- super
- group.visit!
+ Page::Main::Menu.perform(&:go_to_create_project)
- Page::Group::Show.perform(&:go_to_new_project)
- go_to_import_page
- Page::Project::New.perform(&:click_github_link)
+ Page::Project::New.perform do |project_page|
+ project_page.click_import_project
+ project_page.click_github_link
+ end
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(@github_personal_access_token)
import_page.import!(@github_repository_path, @name)
end
end
-
- def go_to_import_page
- Page::Project::New.perform(&:click_import_project)
- end
end
end
end
diff --git a/qa/qa/resource/project_label.rb b/qa/qa/resource/project_label.rb
new file mode 100644
index 00000000000..6b2943a801e
--- /dev/null
+++ b/qa/qa/resource/project_label.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class ProjectLabel < LabelBase
+ attribute :project do
+ Project.fabricate! do |resource|
+ resource.name = 'project-with-label'
+ end
+ end
+
+ def fabricate!
+ project.visit!
+ Page::Project::Menu.perform(&:go_to_labels)
+
+ super
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/labels"
+ end
+
+ def api_get_path
+ "/projects/#{project.id}/labels/#{id}"
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/sandbox.rb b/qa/qa/resource/sandbox.rb
index 913fd6ab9ec..b351d78a184 100644
--- a/qa/qa/resource/sandbox.rb
+++ b/qa/qa/resource/sandbox.rb
@@ -11,6 +11,8 @@ module QA
@path = Runtime::Namespace.sandbox_name
end
+ alias_method :full_path, :path
+
def fabricate!
Page::Main::Menu.perform(&:go_to_groups)
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
new file mode 100644
index 00000000000..5e9ae3e7bbe
--- /dev/null
+++ b/qa/qa/runtime/allure_report.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module QA
+ module Runtime
+ class AllureReport
+ class << self
+ # Configure allure reports
+ #
+ # @return [void]
+ def configure!
+ return unless Env.generate_allure_report?
+
+ require 'allure-rspec'
+
+ configure_allure
+ configure_attachments
+ configure_rspec
+ end
+
+ private
+
+ # Configure allure reporter
+ #
+ # @return [void]
+ def configure_allure
+ # Match job names like ee:relative, ce:update etc. and set as execution environment
+ env_matcher = /^(?<env>\w{2}:\S+)/
+
+ AllureRspec.configure do |config|
+ config.results_directory = 'tmp/allure-results'
+ config.clean_results_directory = true
+
+ # Set custom environment name to separate same specs executed on different environments
+ if Env.running_in_ci? && Env.ci_job_name.match?(env_matcher)
+ config.environment = Env.ci_job_name.match(env_matcher).named_captures['env']
+ end
+ end
+ end
+
+ # Set up failure screenshot attachments
+ #
+ # @return [void]
+ def configure_attachments
+ Capybara::Screenshot.after_save_screenshot do |path|
+ Allure.add_attachment(
+ name: 'screenshot',
+ source: File.open(path),
+ type: Allure::ContentType::PNG,
+ test_case: true
+ )
+ end
+ Capybara::Screenshot.after_save_html do |path|
+ Allure.add_attachment(
+ name: 'html',
+ source: File.open(path),
+ type: 'text/html',
+ test_case: true
+ )
+ end
+ end
+
+ # Configure rspec
+ #
+ # @return [void]
+ def configure_rspec
+ RSpec.configure do |config|
+ config.formatter = AllureRspecFormatter
+
+ config.before do |example|
+ next if example.attempts && example.attempts > 0
+
+ testcase = example.metadata[:testcase]
+ example.tms('Testcase', testcase) if testcase
+
+ issue = example.metadata.dig(:quarantine, :issue)
+ example.issue('Issue', issue) if issue
+
+ example.add_link(name: "Job(#{Env.ci_job_name})", url: Env.ci_job_url) if Env.running_in_ci?
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index e649084a394..ccb87147a6e 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -2,7 +2,6 @@
require 'gitlab/qa'
require 'uri'
-require 'active_support/core_ext/object/blank'
module QA
module Runtime
@@ -53,8 +52,12 @@ module QA
enabled?(ENV['QA_DEBUG'], default: false)
end
+ def generate_allure_report?
+ enabled?(ENV['QA_GENERATE_ALLURE_REPORT'], default: false)
+ end
+
def default_branch
- ENV['QA_DEFAULT_BRANCH'] || 'master'
+ ENV['QA_DEFAULT_BRANCH'] || 'main'
end
def log_destination
diff --git a/qa/qa/runtime/scenario.rb b/qa/qa/runtime/scenario.rb
index 3662ebe671b..d44cc846128 100644
--- a/qa/qa/runtime/scenario.rb
+++ b/qa/qa/runtime/scenario.rb
@@ -19,15 +19,15 @@ module QA
define_singleton_method(attribute) do
attributes[attribute.to_sym].tap do |value|
- if value.to_s.empty?
- raise ArgumentError, "Empty `#{attribute}` attribute!"
- end
+ raise ArgumentError, "Empty `#{attribute}` attribute!" if value.to_s.empty?
end
end
end
def from_env(var)
- JSON.parse(Runtime::Env.runtime_scenario_attributes).each { |k, v| define(k, v) }
+ return if var.blank?
+
+ JSON.parse(var).each { |k, v| define(k, v) }
end
def method_missing(name, *)
diff --git a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
index 9bf3474ba5a..08b71258cc6 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
@@ -6,7 +6,7 @@ module QA
RSpec.describe 'Create' do
context 'Gitaly' do
# Issue to track removal of feature flag: https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/602
- describe 'Distributed reads', :orchestrated, :gitaly_cluster, :skip_live_env, :requires_admin do
+ describe 'Distributed reads', :orchestrated, :gitaly_cluster, :skip_live_env, :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/322814', type: :investigating } do
let(:number_of_reads_per_loop) { 9 }
let(:praefect_manager) { Service::PraefectManager.new }
let(:project) do
diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
index 7e924475437..396d3f52798 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
@@ -4,7 +4,7 @@ require 'parallel'
module QA
RSpec.describe 'Create' do
- context 'Gitaly Cluster replication queue', :orchestrated, :gitaly_cluster, :skip_live_env do
+ context 'Gitaly Cluster replication queue', :orchestrated, :gitaly_cluster, :skip_live_env, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331989', type: :investigating } do
let(:praefect_manager) { Service::PraefectManager.new }
let(:project) do
Resource::Project.fabricate! do |project|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
index 055300122d4..d4c4ec5611a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb
@@ -2,20 +2,21 @@
module QA
RSpec.describe 'Manage', :requires_admin do
- describe 'Group bulk import' do
- let!(:api_client) { Runtime::API::Client.as_admin }
+ describe 'Bulk group import' do
+ let!(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user) do
Resource::User.fabricate_via_api! do |usr|
- usr.api_client = api_client
+ usr.api_client = admin_api_client
usr.hard_delete_on_api_removal = true
end
end
- let!(:personal_access_token) { Runtime::API::Client.new(user: user).personal_access_token }
+ let!(:api_client) { Runtime::API::Client.new(user: user) }
+ let!(:personal_access_token) { api_client.personal_access_token }
let!(:sandbox) do
Resource::Sandbox.fabricate_via_api! do |group|
- group.api_client = api_client
+ group.api_client = admin_api_client
end
end
@@ -37,6 +38,7 @@ module QA
let(:imported_group) do
Resource::Group.new.tap do |group|
group.api_client = api_client
+ group.sandbox = sandbox
group.path = source_group.path
end
end
@@ -54,42 +56,65 @@ module QA
end
before(:all) do
- Runtime::Feature.enable(:bulk_import)
+ Runtime::Feature.enable(:bulk_import) unless staging?
Runtime::Feature.enable(:top_level_group_creation_enabled) if staging?
end
before do
sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
- source_group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
Flow::Login.sign_in(as: user)
- Page::Main::Menu.new.go_to_import_group
- Page::Group::New.new.connect_gitlab_instance(Runtime::Scenario.gitlab_address, personal_access_token)
+ Page::Main::Menu.perform(&:go_to_create_group)
+ Page::Group::New.perform do |group|
+ group.switch_to_import_tab
+ group.connect_gitlab_instance(Runtime::Scenario.gitlab_address, personal_access_token)
+ end
end
+ # Non blocking issues:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/331252
it(
- 'performs bulk group import from another gitlab instance',
+ 'imports group with subgroups and labels',
testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1785',
- exclude: { job: ['ce:relative_url', 'ee:relative_url'] } # https://gitlab.com/gitlab-org/gitlab/-/issues/330344
+ quarantine: {
+ only: { job: 'relative_url' },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/330344',
+ type: :bug
+ }
) do
+ Resource::GroupLabel.fabricate_via_api! do |label|
+ label.api_client = api_client
+ label.group = source_group
+ label.title = "source-group-#{SecureRandom.hex(4)}"
+ end
+ Resource::GroupLabel.fabricate_via_api! do |label|
+ label.api_client = api_client
+ label.group = subgroup
+ label.title = "subgroup-#{SecureRandom.hex(4)}"
+ end
+
Page::Group::BulkImport.perform do |import_page|
import_page.import_group(source_group.path, sandbox.path)
aggregate_failures do
- expect(import_page).to have_imported_group(source_group.path, wait: 120)
- expect(imported_group).to eq(source_group)
- expect(imported_subgroup).to eq(subgroup)
+ expect(import_page).to have_imported_group(source_group.path, wait: 180)
+
+ expect { imported_group.reload! }.to eventually_eq(source_group).within(duration: 10)
+ expect { imported_group.labels }.to eventually_include(*source_group.labels).within(duration: 10)
+
+ # Do not validate subgroups until https://gitlab.com/gitlab-org/gitlab/-/issues/332818 is resolved
+ # expect { imported_subgroup.reload! }.to eventually_eq(subgroup).within(duration: 30)
+ # expect { imported_subgroup.labels }.to eventually_include(*subgroup.labels).within(duration: 30)
end
end
end
after do
user.remove_via_api!
- source_group.remove_via_api!
end
after(:all) do
- Runtime::Feature.disable(:bulk_import)
+ Runtime::Feature.disable(:bulk_import) unless staging?
Runtime::Feature.disable(:top_level_group_creation_enabled) if staging?
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb
index 7bcc1fa4e1c..192c1a3908b 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb
@@ -10,9 +10,13 @@ module QA
Page::Dashboard::Groups.perform do |groups|
groups.click_new_group
- expect(groups).to have_content(
- /Create a Mattermost team for this group/
- )
+ Page::Group::New.perform do |group_new|
+ group_new.click_create_group
+
+ expect(group_new).to have_content(
+ /Create a Mattermost team for this group/
+ )
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
index d6bcd134a03..84464f7174a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
@@ -28,14 +28,17 @@ module QA
end
it 'transfers a subgroup to another group',
- testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1724' do
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1724' do
Page::Group::Menu.perform(&:click_group_general_settings_item)
Page::Group::Settings::General.perform do |general|
general.transfer_group(target_group.path)
+
+ sub_group_for_transfer.sandbox = target_group
+ sub_group_for_transfer.reload!
end
expect(page).to have_text("Group '#{sub_group_for_transfer.path}' was successfully transferred.")
- expect(page.driver.current_url).to include("#{target_group.path}/#{sub_group_for_transfer.path}")
+ expect(page.driver.current_url).to include(sub_group_for_transfer.full_path)
end
after do
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 5072b6d48bf..55ad8baf872 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
@@ -3,25 +3,26 @@
module QA
RSpec.describe 'Manage', :github, :requires_admin do
describe 'Project import' 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 = Runtime::API::Client.as_admin
+ resource.api_client = api_client
+ resource.hard_delete_on_api_removal = true
end
end
- let(:group) { Resource::Group.fabricate_via_api! }
-
let(:imported_project) do
Resource::ProjectImportedFromGithub.fabricate_via_browser_ui! 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/test-project'
+ project.api_client = api_client
end
end
before do
- Runtime::Feature.enable(:invite_members_group_modal, group: group)
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
end
@@ -32,90 +33,90 @@ module QA
it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1762' do
Flow::Login.sign_in(as: user)
- imported_project # import the project
+ imported_project.reload! # import the project and reload all fields
- Page::Main::Menu.perform(&:go_to_projects)
- Page::Dashboard::Projects.perform do |dashboard|
- dashboard.go_to_project(imported_project.name)
+ aggregate_failures do
+ verify_repository_import
+ verify_commits_import
+ verify_labels_import
+ verify_issues_import
+ verify_milestones_import
+ verify_wikis_import
+ verify_merge_requests_import
end
-
- Page::Project::Show.perform(&:wait_for_import)
-
- verify_repository_import
- verify_issues_import
- verify_merge_requests_import
- verify_labels_import
- verify_milestones_import
- verify_wiki_import
end
def verify_repository_import
- Page::Project::Show.perform do |project|
- expect(project).to have_content('This test project is used for automated GitHub import by GitLab QA.')
- expect(project).to have_content(imported_project.name)
- end
+ expect(imported_project.api_response).to include(
+ description: 'A new repo for test',
+ import_status: 'finished',
+ import_error: nil
+ )
end
- def verify_issues_import
- QA::Support::Retrier.retry_on_exception do
- Page::Project::Menu.perform(&:click_issues)
-
- Page::Project::Issue::Show.perform do |issue_page|
- expect(issue_page).to have_content('This is a sample issue')
-
- click_link 'This is a sample issue'
-
- expect(issue_page).to have_content('This is a sample first comment')
-
- # Comments
- comment_text = 'This is a comment from @sliaquat'
-
- expect(issue_page).to have_comment(comment_text)
- expect(issue_page).to have_label('custom new label')
- expect(issue_page).to have_label('help wanted')
- expect(issue_page).to have_label('good first issue')
- end
- end
+ def verify_commits_import
+ expect(imported_project.commits.length).to eq(20)
end
- def verify_merge_requests_import
- Page::Project::Menu.perform(&:click_merge_requests)
-
- Page::MergeRequest::Show.perform do |merge_request|
- expect(merge_request).to have_content('Improve readme')
-
- click_link 'Improve readme'
-
- expect(merge_request).to have_content('This improves the README file a bit.')
-
- # Comments
- expect(merge_request).to have_content('[PR comment by @sliaquat] Nice work!')
-
- # Diff comments
- expect(merge_request).to have_content('[Single diff comment] Good riddance')
- expect(merge_request).to have_content('[Single diff comment] Nice addition')
-
- expect(merge_request).to have_label('bug')
- expect(merge_request).to have_label('documentation')
- end
+ def verify_labels_import
+ labels = imported_project.labels.map { |label| label.slice(:name, :color) }
+
+ expect(labels).to eq(
+ [
+ { name: 'bug', color: '#d73a4a' },
+ { name: 'custom new label', color: '#fc8f91' },
+ { 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
- # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/19228
- # to build upon it.
+ def verify_issues_import
+ issues = imported_project.issues
+
+ expect(issues.length).to eq(1)
+ expect(issues.first).to include(
+ title: 'This is a sample issue',
+ description: "*Created by: gitlab-qa-github*\n\nThis is a sample first comment",
+ labels: ['custom new label', 'good first issue', 'help wanted'],
+ user_notes_count: 1
+ )
end
def verify_milestones_import
- # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18727
- # to build upon it.
+ milestones = imported_project.milestones
+
+ expect(milestones.length).to eq(1)
+ expect(milestones.first).to include(title: 'v1.0', description: nil, state: 'active')
end
- def verify_wiki_import
- Page::Project::Menu.perform(&:click_wiki)
+ def verify_wikis_import
+ wikis = imported_project.wikis
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_content('Welcome to the test-project wiki!')
- end
+ expect(wikis.length).to eq(1)
+ expect(wikis.first).to include(title: 'Home', format: 'markdown')
+ end
+
+ def verify_merge_requests_import
+ merge_requests = imported_project.merge_requests
+
+ expect(merge_requests.length).to eq(1)
+ expect(merge_requests.first).to include(
+ title: 'Improve readme',
+ state: 'opened',
+ target_branch: 'main',
+ source_branch: 'improve-readme',
+ labels: %w[bug documentation],
+ description: <<~DSC.strip
+ *Created by: gitlab-qa-github*\n\nThis improves the README file a bit.\r\n\r\nTODO:\r\n\r\n \r\n\r\n- [ ] Do foo\r\n- [ ] Make bar\r\n - [ ] Think about baz
+ DSC
+ )
end
end
end
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 2654531bc2c..44a361df34d 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
@@ -25,6 +25,7 @@ module QA
after do
Runtime::Feature.disable('real_time_issue_sidebar', project: project)
Runtime::Feature.disable('broadcast_issue_updates', project: project)
+ Runtime::Feature.disable(:invite_members_group_modal, project: project)
end
it 'update without refresh', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1048' do
@@ -37,7 +38,9 @@ module QA
Page::Project::Issue::Show.perform do |show|
expect(show).to have_assignee(user1.name)
-
+ # We need to wait 1 second for the page to connect to the websocket to subscribe to updates
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/293699#note_583959786
+ sleep 1
issue.set_issue_assignees(assignee_ids: [user2.id])
expect(show).to have_assignee(user2.name)
diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb
index dfdc9b7c9b4..59d34612ca7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Create', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331978', type: :bug } do
context 'Design Management' do
let(:design) do
Resource::Design.fabricate! do |design|
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 81ad1896075..082d001b716 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
@@ -16,7 +16,11 @@ module QA
Flow::Login.sign_in
end
- it 'creates a basic merge request', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1276' do
+ it(
+ 'creates a basic merge request',
+ :smoke,
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1850'
+ ) do
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
merge_request.project = project
merge_request.title = merge_request_title
@@ -29,14 +33,17 @@ module QA
end
end
- it 'creates a merge request with a milestone and label', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/514' do
+ it(
+ 'creates a merge request with a milestone and label',
+ testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/514'
+ ) do
gitlab_account_username = "@#{Runtime::User.username}"
milestone = Resource::ProjectMilestone.fabricate_via_api! do |milestone|
milestone.project = project
end
- label = Resource::Label.fabricate_via_api! do |label|
+ label = Resource::ProjectLabel.fabricate_via_api! do |label|
label.project = project
label.title = 'label'
end
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 c2e148e19bd..dd4b3276687 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,8 @@
module QA
RSpec.describe 'Create' do
- describe 'Merge request creation from fork', :smoke do
+ describe 'Merge request creation from fork' do
+ # TODO: Please add this back to :smoke suite as soon as https://gitlab.com/gitlab-org/gitlab/-/issues/332588 is addressed
it 'can merge feature branch fork to mainline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1701' do
merge_request = 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/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
index d400876c838..639702f9148 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
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Create, list, and delete branches via web' do
+ describe 'Create, list, and delete branches via web', :requires_admin do
master_branch = nil
second_branch = 'second-branch'
third_branch = 'third-branch'
@@ -24,6 +24,8 @@ module QA
proj.initialize_with_readme = true
end
+ Runtime::Feature.enable(:delete_branch_confirmation_modals, project: project)
+
master_branch = project.default_branch
Git::Repository.perform do |repository|
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 2c0fb5ea290..67b48d254ac 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
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Git push over HTTP', :smoke do
- it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1278' do
+ it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1848' do
Flow::Login.sign_in
access_token = Resource::PersonalAccessToken.fabricate!.token
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 4f241325437..ae8f34f9845 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
@@ -7,7 +7,7 @@ module QA
Flow::Login.sign_in
Page::Main::Menu.perform do |menu|
- menu.go_to_more_dropdown_option(:snippets_link)
+ menu.go_to_menu_dropdown_option(:snippets_link)
end
Resource::Snippet.fabricate_via_browser_ui! do |snippet|
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 50f2f4789fa..8ff3222f065 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
@@ -7,7 +7,7 @@ module QA
Flow::Login.sign_in
Page::Main::Menu.perform do |menu|
- menu.go_to_more_dropdown_option(:snippets_link)
+ menu.go_to_menu_dropdown_option(:snippets_link)
end
Resource::Snippet.fabricate_via_browser_ui! do |snippet|
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 9c7dc868a2e..d922950335f 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
@@ -60,7 +60,7 @@ module QA
it "shows correct details of #{snippet_type} including file number" do
send(snippet_type)
Page::Main::Menu.perform do |menu|
- menu.go_to_more_dropdown_option(:snippets_link)
+ menu.go_to_menu_dropdown_option(:snippets_link)
end
Page::Dashboard::Snippet::Index.perform do |snippet|
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 8617e05f912..7a81318f158 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
@@ -24,7 +24,8 @@ module QA
runner.remove_via_api!
end
- it 'users creates a pipeline which gets processed', :smoke, testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1279' do
+ it 'users creates a pipeline which gets processed', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1849' do
+ # TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300909
Flow::Login.sign_in
Resource::Repository::Commit.fabricate_via_api! do |commit|
@@ -47,7 +48,7 @@ module QA
- echo 'FAILURE'
- exit 1
- test-tags:
+ test-tags-mismatch:
tags:
- invalid
script: echo 'NOOP'
@@ -70,7 +71,7 @@ module QA
{
'test-success': :passed,
'test-failure': :failed,
- 'test-tags': :pending,
+ 'test-tags-mismatch': :pending,
'test-artifacts': :passed
}.each do |job, status|
Page::Project::Pipeline::Show.perform do |pipeline|
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb
index 7a71d1cfbaf..9131cad7244 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry_spec.rb
@@ -30,6 +30,14 @@ module QA
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
+ before_script:
+ - |
+ echo "Waiting for docker to start..."
+ for i in $(seq 1 30)
+ do
+ docker info && break
+ sleep 1s
+ done
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
diff --git a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
index fb019290d4c..9c00f1f6d17 100644
--- a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
@@ -3,7 +3,7 @@
require 'securerandom'
module QA
- RSpec.describe 'Package', :orchestrated, :packages do
+ RSpec.describe 'Package', :orchestrated, :packages, :reliable do
describe 'Maven Repository' do
include Runtime::Fixtures
@@ -44,7 +44,7 @@ module QA
runner.name = "qa-runner-#{Time.now.to_i}"
runner.tags = ["runner-for-#{project.group.name}"]
runner.executor = :docker
- runner.token = project.group.sandbox.runners_token
+ runner.token = project.group.runners_token
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
index 4d714affd65..c4bfaacca11 100644
--- a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages do
+ RSpec.describe 'Package', :orchestrated, :packages, :reliable do
describe 'npm registry' do
include Runtime::Fixtures
@@ -37,7 +37,7 @@ module QA
runner.name = "qa-runner-#{Time.now.to_i}"
runner.tags = ["runner-for-#{project.group.name}"]
runner.executor = :docker
- runner.token = project.group.sandbox.runners_token
+ runner.token = project.group.runners_token
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
index 3db5b9671d9..daf41f1c6ab 100644
--- a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
@@ -31,9 +31,9 @@ module QA
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
- runner.tags = ["runner-for-#{project.group.sandbox.name}"]
+ runner.tags = ["runner-for-#{project.group.name}"]
runner.executor = :docker
- runner.token = project.group.sandbox.runners_token
+ runner.token = project.group.runners_token
end
end
@@ -69,7 +69,7 @@ module QA
only:
- "#{project.default_branch}"
tags:
- - "runner-for-#{project.group.sandbox.name}"
+ - "runner-for-#{project.group.name}"
YAML
}
]
@@ -128,7 +128,7 @@ module QA
only:
- "#{another_project.default_branch}"
tags:
- - "runner-for-#{project.group.sandbox.name}"
+ - "runner-for-#{project.group.name}"
YAML
}
]
@@ -145,7 +145,7 @@ module QA
expect(job).to be_successful(timeout: 800)
end
- project.group.sandbox.visit!
+ project.group.visit!
Page::Group::Menu.perform(&:go_to_group_packages)
diff --git a/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb
index 2cb2ea2d636..1502e1ab924 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pages/pages_pipeline_spec.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Release', :smoke, :runner do
+ RSpec.describe 'Release', :runner do
+ # TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300906
describe 'Pages' do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
index fe2d821576b..2538f249010 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
@@ -18,7 +18,7 @@ module QA
end
where(:template) do
- %w[rails spring express]
+ %w[express]
end
with_them do
@@ -45,7 +45,7 @@ module QA
Flow::Login.sign_in
end
- it 'works with Auto DevOps', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/240946', type: :flaky } do
+ it 'works with Auto DevOps' do
%w[build code_quality test].each do |job|
pipeline.visit!
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 e2cf5c5b195..1dcc02095f6 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
@@ -81,11 +81,11 @@ module QA
job.click_element(:pipeline_path)
end
- Page::Project::Menu.perform(&:go_to_operations_environments)
- Page::Project::Operations::Environments::Index.perform do |index|
+ Page::Project::Menu.perform(&:go_to_deployments_environments)
+ Page::Project::Deployments::Environments::Index.perform do |index|
index.click_environment_link('production')
end
- Page::Project::Operations::Environments::Show.perform do |show|
+ Page::Project::Deployments::Environments::Show.perform do |show|
show.view_deployment do
expect(page).to have_content('Hello World!')
expect(page).to have_content('you_can_see_this_variable')
@@ -115,7 +115,7 @@ module QA
end
end
- it 'runs an AutoDevOps pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1277' do
+ it 'runs an AutoDevOps pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1847' do
Flow::Pipeline.visit_latest_pipeline
Page::Project::Pipeline::Show.perform do |pipeline|
diff --git a/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb
index 09fbbf5adc5..1803b4b16de 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb
@@ -26,9 +26,9 @@ module QA
k8s_cluster.cluster = cluster
end.project.visit!
- Page::Project::Menu.perform(&:go_to_operations_kubernetes)
+ Page::Project::Menu.perform(&:go_to_infrastructure_kubernetes)
- Page::Project::Operations::Kubernetes::Index.perform do |index|
+ Page::Project::Infrastructure::Kubernetes::Index.perform do |index|
expect(index).to have_cluster(cluster)
end
end
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
index 94df408f9aa..1511f74c883 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
@@ -17,9 +17,9 @@ module QA
end
it 'duplicates to create dashboard to custom', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/871' do
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
on_dashboard.duplicate_dashboard
expect(on_dashboard).to have_metrics
@@ -28,9 +28,9 @@ module QA
end
it 'verifies data on filtered deployed environment', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/874' do
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
on_dashboard.filter_environment
expect(on_dashboard).to have_metrics
@@ -38,9 +38,9 @@ module QA
end
it 'filters using the quick range', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/873' do
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
on_dashboard.show_last('30 minutes')
expect(on_dashboard).to have_metrics
@@ -53,13 +53,13 @@ module QA
end
it 'observes cluster health graph', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/920' do
- Page::Project::Menu.perform(&:go_to_operations_kubernetes)
+ Page::Project::Menu.perform(&:go_to_infrastructure_kubernetes)
- Page::Project::Operations::Kubernetes::Index.perform do |cluster_list|
+ Page::Project::Infrastructure::Kubernetes::Index.perform do |cluster_list|
cluster_list.click_on_cluster(@cluster)
end
- Page::Project::Operations::Kubernetes::Show.perform do |cluster_panel|
+ Page::Project::Infrastructure::Kubernetes::Show.perform do |cluster_panel|
cluster_panel.open_health
cluster_panel.wait_for_cluster_health
end
@@ -78,9 +78,9 @@ module QA
push.new_branch = false
end
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |dashboard|
dashboard.select_dashboard('templating.yml')
expect(dashboard).to have_template_metric('CPU usage GitLab Runner')
@@ -101,9 +101,9 @@ module QA
metrics_panel.add_custom_metric
end
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
expect(on_dashboard).to have_custom_metric('HTTP Requests Total')
end
end
@@ -116,9 +116,9 @@ module QA
metrics_panel.edit_custom_metric
end
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
expect(on_dashboard).to have_custom_metric('Throughput')
end
end
@@ -132,9 +132,9 @@ module QA
metrics_panel.delete_custom_metric
end
- Page::Project::Menu.perform(&:go_to_operations_metrics)
+ Page::Project::Menu.perform(&:go_to_monitor_metrics)
- Page::Project::Operations::Metrics::Show.perform do |on_dashboard|
+ Page::Project::Monitor::Metrics::Show.perform do |on_dashboard|
expect(on_dashboard).not_to have_custom_metric('Throughput')
end
end
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb b/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb
index ed0064e8b6f..19e49400d5e 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb
@@ -17,7 +17,7 @@ module QA
%w[
CODE_QUALITY_DISABLED TEST_DISABLED LICENSE_MANAGEMENT_DISABLED
SAST_DISABLED DAST_DISABLED DEPENDENCY_SCANNING_DISABLED
- CONTAINER_SCANNING_DISABLED PERFORMANCE_DISABLED SECRET_DETECTION_DISABLED
+ CONTAINER_SCANNING_DISABLED BROWSER_PERFORMANCE_DISABLED SECRET_DETECTION_DISABLED
].each do |key|
Resource::CiVariable.fabricate_via_api! do |resource|
resource.project = @project
diff --git a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb b/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
index 302fec55c53..de425dde6c0 100644
--- a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
+++ b/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
@@ -20,7 +20,7 @@ module QA
end
end
- it 'shows results for the original request and AJAX requests', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/478', quarantine: { only: { pipeline: :master }, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/323051', type: :bug } do
+ it 'shows results for the original request and AJAX requests', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/478', quarantine: { only: { pipeline: :main }, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/323051', type: :bug } do
# Issue pages always make AJAX requests
Resource::Issue.fabricate_via_browser_ui! do |issue|
issue.title = 'Performance bar test'
diff --git a/qa/qa/tools/delete_projects.rb b/qa/qa/tools/delete_projects.rb
index bb73033e9d7..8a690373a37 100644
--- a/qa/qa/tools/delete_projects.rb
+++ b/qa/qa/tools/delete_projects.rb
@@ -20,7 +20,7 @@ module QA
end
def run
- STDOUT.puts 'Running...'
+ $stdout.puts 'Running...'
# Fetch group's id
group_id = fetch_group_id
@@ -30,16 +30,16 @@ module QA
# Do not delete projects that are less than 4 days old (for debugging purposes)
project_ids = fetch_project_ids(group_id, total_project_pages)
- STDOUT.puts "Number of projects to be deleted: #{project_ids.length}"
+ $stdout.puts "Number of projects to be deleted: #{project_ids.length}"
delete_projects(project_ids) unless project_ids.empty?
- STDOUT.puts "\nDone"
+ $stdout.puts "\nDone"
end
private
def delete_projects(project_ids)
- STDOUT.puts "Deleting #{project_ids.length} projects..."
+ $stdout.puts "Deleting #{project_ids.length} projects..."
project_ids.each do |project_id|
delete_response = delete Runtime::API::Request.new(@api_client, "/projects/#{project_id}").url
dot_or_f = delete_response.code.between?(200, 300) ? "\e[32m.\e[0m" : "\e[31mF\e[0m"
diff --git a/qa/qa/tools/delete_subgroups.rb b/qa/qa/tools/delete_subgroups.rb
index 903f730a030..b9e3ed66013 100644
--- a/qa/qa/tools/delete_subgroups.rb
+++ b/qa/qa/tools/delete_subgroups.rb
@@ -20,7 +20,7 @@ module QA
end
def run
- STDOUT.puts 'Running...'
+ $stdout.puts 'Running...'
# Fetch group's id
group_id = fetch_group_id
@@ -29,16 +29,16 @@ module QA
total_sub_group_pages = sub_groups_head_response.headers[:x_total_pages]
sub_group_ids = fetch_subgroup_ids(group_id, total_sub_group_pages)
- STDOUT.puts "Number of Sub Groups not already marked for deletion: #{sub_group_ids.length}"
+ $stdout.puts "Number of Sub Groups not already marked for deletion: #{sub_group_ids.length}"
delete_subgroups(sub_group_ids) unless sub_group_ids.empty?
- STDOUT.puts "\nDone"
+ $stdout.puts "\nDone"
end
private
def delete_subgroups(sub_group_ids)
- STDOUT.puts "Deleting #{sub_group_ids.length} subgroups..."
+ $stdout.puts "Deleting #{sub_group_ids.length} subgroups..."
sub_group_ids.each do |subgroup_id|
delete_response = delete Runtime::API::Request.new(@api_client, "/groups/#{subgroup_id}").url
dot_or_f = delete_response.code == 202 ? "\e[32m.\e[0m" : "\e[31mF\e[0m"
diff --git a/qa/qa/tools/delete_test_ssh_keys.rb b/qa/qa/tools/delete_test_ssh_keys.rb
index 953e9fc63d1..dea6930de1e 100644
--- a/qa/qa/tools/delete_test_ssh_keys.rb
+++ b/qa/qa/tools/delete_test_ssh_keys.rb
@@ -30,18 +30,18 @@ module QA
end
def run
- STDOUT.puts 'Running...'
+ $stdout.puts 'Running...'
keys_head_response = head Runtime::API::Request.new(@api_client, "/user/keys", per_page: ITEMS_PER_PAGE).url
total_pages = keys_head_response.headers[:x_total_pages]
test_ssh_key_ids = fetch_test_ssh_key_ids(total_pages)
- STDOUT.puts "Number of test ssh keys to be deleted: #{test_ssh_key_ids.length}"
+ $stdout.puts "Number of test ssh keys to be deleted: #{test_ssh_key_ids.length}"
return if dry_run?
delete_ssh_keys(test_ssh_key_ids) unless test_ssh_key_ids.empty?
- STDOUT.puts "\nDone"
+ $stdout.puts "\nDone"
end
private
@@ -50,7 +50,7 @@ module QA
alias_method :dry_run?, :dry_run
def delete_ssh_keys(ssh_key_ids)
- STDOUT.puts "Deleting #{ssh_key_ids.length} ssh keys..."
+ $stdout.puts "Deleting #{ssh_key_ids.length} ssh keys..."
ssh_key_ids.each do |key_id|
delete_response = delete Runtime::API::Request.new(@api_client, "/user/keys/#{key_id}").url
dot_or_f = delete_response.code == 204 ? "\e[32m.\e[0m" : "\e[31mF\e[0m"
diff --git a/qa/qa/tools/generate_perf_testdata.rb b/qa/qa/tools/generate_perf_testdata.rb
index 546f7e7cdca..ec1aa20c3b8 100644
--- a/qa/qa/tools/generate_perf_testdata.rb
+++ b/qa/qa/tools/generate_perf_testdata.rb
@@ -26,7 +26,7 @@ module QA
end
def all
- STDOUT.puts 'Running...'
+ $stdout.puts 'Running...'
group_id = create_group
create_project(group_id)
@@ -50,23 +50,23 @@ module QA
end
threads_arr.each(&:join)
- STDOUT.puts "\nURLs: #{@urls}"
+ $stdout.puts "\nURLs: #{@urls}"
File.open("urls.yml", "w") { |file| file.puts @urls.stringify_keys.to_yaml }
- STDOUT.puts "\nDone"
+ $stdout.puts "\nDone"
end
def create_group
group_search_response = create_a_group_api_req(@group_name, @visibility)
group = JSON.parse(group_search_response.body)
@urls[:group_page] = group["web_url"]
- STDOUT.puts "Created a group: #{@urls[:group_page]}"
+ $stdout.puts "Created a group: #{@urls[:group_page]}"
group["id"]
end
def create_project(group_id)
create_project_response = create_a_project_api_req(@project_name, group_id, @visibility)
@urls[:project_page] = JSON.parse(create_project_response.body)["web_url"]
- STDOUT.puts "Created a project: #{@urls[:project_page]}"
+ $stdout.puts "Created a project: #{@urls[:project_page]}"
end
def create_many_issues
@@ -74,7 +74,7 @@ module QA
create_an_issue_api_req("#{@group_name}%2F#{@project_name}", "issue#{i}", "desc#{i}")
end
@urls[:issues_list_page] = @urls[:project_page] + "/issues"
- STDOUT.puts "Created many issues: #{@urls[:issues_list_page]}"
+ $stdout.puts "Created many issues: #{@urls[:issues_list_page]}"
end
def create_many_todos
@@ -82,7 +82,7 @@ module QA
create_a_todo_api_req("#{@group_name}%2F#{@project_name}", "#{i + 1}")
end
@urls[:todos_page] = ENV['GITLAB_ADDRESS'] + "/dashboard/todos"
- STDOUT.puts "Created many todos: #{@urls[:todos_page]}"
+ $stdout.puts "Created many todos: #{@urls[:todos_page]}"
end
def create_many_labels
@@ -90,7 +90,7 @@ module QA
create_a_label_api_req("#{@group_name}%2F#{@project_name}", "label#{i}", "#{Faker::Color.hex_color}")
end
@urls[:labels_page] = @urls[:project_page] + "/labels"
- STDOUT.puts "Created many labels: #{@urls[:labels_page]}"
+ $stdout.puts "Created many labels: #{@urls[:labels_page]}"
end
def create_many_merge_requests
@@ -98,7 +98,7 @@ module QA
create_a_merge_request_api_req("#{@group_name}%2F#{@project_name}", "branch#{i}", Runtime::Env.default_branch, "MR#{i}")
end
@urls[:mr_list_page] = @urls[:project_page] + "/merge_requests"
- STDOUT.puts "Created many MRs: #{@urls[:mr_list_page]}"
+ $stdout.puts "Created many MRs: #{@urls[:mr_list_page]}"
end
def create_many_new_files
@@ -109,7 +109,7 @@ module QA
end
@urls[:files_page] = @urls[:project_page] + "/tree/#{Runtime::Env.default_branch}"
- STDOUT.puts "Added many new files: #{@urls[:files_page]}"
+ $stdout.puts "Added many new files: #{@urls[:files_page]}"
end
def create_many_branches
@@ -117,7 +117,7 @@ module QA
create_a_branch_api_req("branch#{i}", "#{@group_name}%2F#{@project_name}")
end
@urls[:branches_page] = @urls[:project_page] + "/-/branches"
- STDOUT.puts "Created many branches: #{@urls[:branches_page]}"
+ $stdout.puts "Created many branches: #{@urls[:branches_page]}"
end
def create_an_issue_with_many_discussions
@@ -130,7 +130,7 @@ module QA
# Add description and labels
update_an_issue_api_req("#{@group_name}%2F#{@project_name}", issue_id, "#{Faker::Lorem.sentences(500).join(" ")}", labels_list)
@urls[:large_issue] = @urls[:project_page] + "/issues/#{issue_id}"
- STDOUT.puts "Created an issue with many discussions: #{@urls[:large_issue]}"
+ $stdout.puts "Created an issue with many discussions: #{@urls[:large_issue]}"
end
def create_an_mr_with_large_files_and_many_mr_discussions
@@ -178,7 +178,7 @@ module QA
create_a_discussion_on_mr_api_req("#{@group_name}%2F#{@project_name}", iid, "Let us discuss")
end
@urls[:large_mr] = JSON.parse(create_mr_response.body)["web_url"]
- STDOUT.puts "Created an MR with many discussions and many very large Files: #{@urls[:large_mr]}"
+ $stdout.puts "Created an MR with many discussions and many very large Files: #{@urls[:large_mr]}"
end
def create_diff_note(iid, file_count, line_count, head_sha, start_sha, base_sha, line_type)
@@ -205,7 +205,7 @@ module QA
100.times do |i|
update_file_api_req(file_name, branch_name, project_path, Faker::Lorem.sentences(5).join(" "), Faker::Lorem.sentences(500).join("\n"))
end
- STDOUT.puts "Using branch: #{branch_name}, created an MR with many commits: #{@urls[:mr_with_many_commits]}"
+ $stdout.puts "Using branch: #{branch_name}, created an MR with many commits: #{@urls[:mr_with_many_commits]}"
end
private
diff --git a/qa/qa/tools/revoke_all_personal_access_tokens.rb b/qa/qa/tools/revoke_all_personal_access_tokens.rb
index 63a7b0d2d8e..c0a1697fa16 100644
--- a/qa/qa/tools/revoke_all_personal_access_tokens.rb
+++ b/qa/qa/tools/revoke_all_personal_access_tokens.rb
@@ -12,7 +12,7 @@ module QA
def run
do_run
rescue Net::ReadTimeout
- STDOUT.puts 'Net::ReadTimeout during run. Trying again'
+ $stdout.puts 'Net::ReadTimeout during run. Trying again'
run
end
@@ -23,7 +23,7 @@ module QA
raise ArgumentError, "Please provide GITLAB_PASSWORD" unless ENV['GITLAB_PASSWORD']
raise ArgumentError, "Please provide GITLAB_ADDRESS" unless ENV['GITLAB_ADDRESS']
- STDOUT.puts 'Running...'
+ $stdout.puts 'Running...'
Runtime::Browser.visit(ENV['GITLAB_ADDRESS'], Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb
index 0c9643c830b..f4bfd57504e 100644
--- a/qa/spec/spec_helper.rb
+++ b/qa/spec/spec_helper.rb
@@ -4,6 +4,7 @@ require_relative '../qa'
require 'rspec/retry'
require 'rspec-parameterized'
require 'active_support/core_ext/hash'
+require 'active_support/core_ext/object/blank'
if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK']
require 'knapsack'
@@ -11,8 +12,8 @@ if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK']
end
QA::Runtime::Browser.configure!
-
-QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes) if QA::Runtime::Env.runtime_scenario_attributes
+QA::Runtime::AllureReport.configure!
+QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
Dir[::File.join(__dir__, "support/helpers/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "support/matchers/*.rb")].sort.each { |f| require f }
diff --git a/qa/spec/specs/helpers/context_selector_spec.rb b/qa/spec/specs/helpers/context_selector_spec.rb
index 16b6c6601b1..7792d33dcf9 100644
--- a/qa/spec/specs/helpers/context_selector_spec.rb
+++ b/qa/spec/specs/helpers/context_selector_spec.rb
@@ -189,9 +189,9 @@ RSpec.describe QA::Specs::Helpers::ContextSelector do
it 'runs on default branch pipelines' do
group = describe_successfully do
- it('runs on master pipeline given a single pipeline', only: { pipeline: :master }) {}
- it('runs in master given an array of pipelines', only: { pipeline: [:canary, :master] }) {}
- it('does not run in non-default pipelines', only: { pipeline: [:nightly, :not_nightly, :not_master] }) {}
+ it('runs on main pipeline given a single pipeline', only: { pipeline: :main }) {}
+ it('runs in main given an array of pipelines', only: { pipeline: [:canary, :main] }) {}
+ it('does not run in non-default pipelines', only: { pipeline: [:nightly, :not_nightly, :not_main] }) {}
end
aggregate_failures do
diff --git a/qa/spec/support/matchers/eventually_matcher.rb b/qa/spec/support/matchers/eventually_matcher.rb
new file mode 100644
index 00000000000..3f0afd6fb54
--- /dev/null
+++ b/qa/spec/support/matchers/eventually_matcher.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+# Rspec matcher with build in retry logic
+#
+# USAGE:
+#
+# Basic
+# expect { Something.that.takes.time.to_appear }.to eventually_eq(expected_result)
+# expect { Something.that.takes.time.to_appear }.not_to eventually_eq(expected_result)
+#
+# With duration and attempts override
+# expect { Something.that.takes.time.to_appear }.to eventually_eq(expected_result).within(duration: 10, attempts: 5)
+
+module Matchers
+ %w[
+ eq
+ be
+ include
+ be_truthy
+ be_falsey
+ be_empty
+ ].each do |op|
+ RSpec::Matchers.define(:"eventually_#{op}") do |*expected|
+ chain(:within) do |options = {}|
+ @duration = options[:duration]
+ @attempts = options[:attempts]
+ end
+
+ def supports_block_expectations?
+ true
+ end
+
+ match { |actual| wait_and_check(actual, :default_expectation) }
+
+ match_when_negated { |actual| wait_and_check(actual, :when_negated_expectation) }
+
+ description do
+ "eventually #{operator_msg} #{expected.inspect}"
+ end
+
+ failure_message do
+ "#{e}:\nexpected to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
+ end
+
+ failure_message_when_negated do
+ "#{e}:\nexpected not to #{description}, last attempt was #{@result.nil? ? 'nil' : @result}"
+ end
+
+ # Execute rspec expectation within retrier
+ #
+ # @param [Proc] actual
+ # @param [Symbol] expectation_name
+ # @return [Boolean]
+ def wait_and_check(actual, expectation_name)
+ QA::Support::Retrier.retry_until(
+ max_attempts: @attempts,
+ max_duration: @duration,
+ sleep_interval: 0.5
+ ) do
+ public_send(expectation_name, actual)
+ rescue RSpec::Expectations::ExpectationNotMetError, QA::Resource::ApiFabricator::ResourceNotFoundError
+ false
+ end
+ rescue QA::Support::Repeater::RetriesExceededError, QA::Support::Repeater::WaitExceededError => e
+ @e = e
+ false
+ end
+
+ # Execute rspec expectation
+ #
+ # @param [Proc] actual
+ # @return [void]
+ def default_expectation(actual)
+ expect(result(&actual)).to public_send(*expectation_args)
+ end
+
+ # Execute negated rspec expectation
+ #
+ # @param [Proc] actual
+ # @return [void]
+ def when_negated_expectation(actual)
+ expect(result(&actual)).not_to public_send(*expectation_args)
+ end
+
+ # Result of actual block
+ #
+ # @return [Object]
+ def result
+ @result = yield
+ end
+
+ # Error message placeholder to indicate waiter did not fail properly
+ # This message should not appear under normal circumstances since it should
+ # always be assigned from repeater
+ #
+ # @return [String]
+ def e
+ @e ||= 'Waiter did not fail!'
+ end
+
+ # Operator message
+ #
+ # @return [String]
+ def operator_msg
+ case operator
+ when 'eq' then 'equal'
+ else operator
+ end
+ end
+
+ # Expect operator
+ #
+ # @return [String]
+ def operator
+ @operator ||= name.to_s.match(/eventually_(.+?)$/).to_a[1].to_s
+ end
+
+ # Expectation args
+ #
+ # @return [String, Array]
+ def expectation_args
+ if operator.include?('truthy') || operator.include?('falsey') || operator.include?('empty')
+ operator
+ elsif operator == "include" && expected.is_a?(Array)
+ [operator, *expected]
+ else
+ [operator, expected]
+ end
+ end
+ end
+ end
+end
diff --git a/qa/tls_certificates/client/client.crt b/qa/tls_certificates/client/client.crt
new file mode 100644
index 00000000000..1bbc49e77d5
--- /dev/null
+++ b/qa/tls_certificates/client/client.crt
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFLDCCAxQCAQEwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCVVMxEzARBgNV
+BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xGTAXBgNVBAoM
+EEdpdExhYiBBdXRob3JpdHkwHhcNMjEwMjEyMDc0NTM0WhcNMzEwMjEwMDc0NTM0
+WjBjMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
+U2FuIEZyYW5jaXNjbzEWMBQGA1UECgwNR2l0TGFiIENsaWVudDEPMA0GA1UEAwwG
+Q2xpZW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwZHPYiri29q+
+1qDh6ucjKztoZ9I0gqG4skuYs7jxj7jTOG/+rkYUVB+Eltq0m76rWEEA6OFW5Yze
+E+aZOYnLYi31BwhJZI2LHDWUsdDuX936FVr5B7l+nrvARVhhARbfhjFVAljcAmDy
+Q+cSgGxgM5de/KhJ0juU25lhe2rCViuJYUsCWny4pN91KhdLJCoPxQRxFDNKG/+k
+foacxKFwEtgz185xLgNZdydwhiY5yh4+P6rCMYqKAvnl2w6L/dPQmHasWbH4Gdvk
+TGCaxiJ7NBM4Lkv+uZmjHPnBmIdLnt+Yjb/lQmaSPA379yLA4L1n/JucmlUCMpVa
+KcJTPEUzUKM4u705XLqsRVH2YmcWAQH8XPw42Llw5T4fAooR+kyMN/zigPNdw7ZC
+r+2jW5rk95gb8iEbheVaSrGIAWPqcwrSTcna5Khbzy/najf2oAM87h95D2Fhg7eW
+LhoccImcuWEGFrmUGwPwS4Zxr2XeAFim8VVVMx9uGd+5u1AscfZFWKJP3j6FwpDH
+L4I7OXFh34INxluxKQ22+PEcIUkbqpGaLZ5U+ZTw8WOy77oflUkAEu1xoEBah+Nf
+5dr6b+n+8rSddCk3mDsgpDY5E3Uv8/FH2vxRmTpiq8ObdmMbNo9Qf+CpMNg4CG+v
+f96uqj69r3aqG3MEbRdy0UjgdaaeNx0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA
+OvEPqiQx5RuiqdVDzNAGGW6SzGoyehwVL0JkYvwHPZ8gOW4XBGl9Dtnkb3M7GeYq
+urZnoplk1uyMnNin2MVA0hRfCwCv7ix56Sh45odpN9scnXsr9I/e6ZfbQB7vFGnV
+NDESsOZKzkydameUBTu9yBk7mlV9jA7LpKipe67doptANURZjF8crmCeTvY3b1cF
+XbFe31FqvKdXeJgZU99kGUSncSS/1dWxbwyZZDBCqWfDlNh7Om+6RB1cMlQfal5z
+hqCYMGBB8YsMY1+l7l8eQDawrZNbs9yE4iqd6FXvss7o02cC1b7moZB+1JhOwwJ1
+wmgXuRiR5ynsb34LjFOicdm4YVmqiqXCW6Pr/DH/pkX8CI3Zu2hjatbgQrkGxXqT
+T1O/o48xwa8MBfviy7gkdCrapBkx0ojNLYNW6NTR3LNT4WYEQWOnqkm73Is9aVCy
+1doL6zG8chvCxLHXtpEMMPkOKpoWjokdCD4K5HAoIqmR904kOM5jCuETTWm0MD0e
+vKeWzck6YDt+zBhCD4k7yqF++d3ufcY2eCmVlwe0wH4srX/e4ni0tBKF25j3xLUA
+U+HI7Wa88zBAp3iN3CD/iWu8LBwTUlmRN8l7bi+O/AaKE08KvtzV5hhZ4c1UJa+N
+d4txM9tqkwMTFTFkRzduwuaIKB3Gaz1IWcOUJe5oO5M=
+-----END CERTIFICATE-----
diff --git a/qa/tls_certificates/client/client.csr b/qa/tls_certificates/client/client.csr
new file mode 100644
index 00000000000..42c868a381c
--- /dev/null
+++ b/qa/tls_certificates/client/client.csr
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIEqDCCApACAQAwYzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx
+FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xFjAUBgNVBAoMDUdpdExhYiBDbGllbnQx
+DzANBgNVBAMMBkNsaWVudDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AMGRz2Iq4tvavtag4ernIys7aGfSNIKhuLJLmLO48Y+40zhv/q5GFFQfhJbatJu+
+q1hBAOjhVuWM3hPmmTmJy2It9QcISWSNixw1lLHQ7l/d+hVa+Qe5fp67wEVYYQEW
+34YxVQJY3AJg8kPnEoBsYDOXXvyoSdI7lNuZYXtqwlYriWFLAlp8uKTfdSoXSyQq
+D8UEcRQzShv/pH6GnMShcBLYM9fOcS4DWXcncIYmOcoePj+qwjGKigL55dsOi/3T
+0Jh2rFmx+Bnb5ExgmsYiezQTOC5L/rmZoxz5wZiHS57fmI2/5UJmkjwN+/ciwOC9
+Z/ybnJpVAjKVWinCUzxFM1CjOLu9OVy6rEVR9mJnFgEB/Fz8ONi5cOU+HwKKEfpM
+jDf84oDzXcO2Qq/to1ua5PeYG/IhG4XlWkqxiAFj6nMK0k3J2uSoW88v52o39qAD
+PO4feQ9hYYO3li4aHHCJnLlhBha5lBsD8EuGca9l3gBYpvFVVTMfbhnfubtQLHH2
+RViiT94+hcKQxy+COzlxYd+CDcZbsSkNtvjxHCFJG6qRmi2eVPmU8PFjsu+6H5VJ
+ABLtcaBAWofjX+Xa+m/p/vK0nXQpN5g7IKQ2ORN1L/PxR9r8UZk6YqvDm3ZjGzaP
+UH/gqTDYOAhvr3/erqo+va92qhtzBG0XctFI4HWmnjcdAgMBAAGgADANBgkqhkiG
+9w0BAQsFAAOCAgEAAPvL+5aGluJVNDfTyQMLKFYl7qsF6cNqwzv+Zd9bB9Suznta
+c7pU2EdHO0qsqwpMvRHxdo/2R5gbnAtPLTgQA9I9aL+YjSLH7nZJPieHFt6ffSyz
+rGNwXUBgKwhAoTqQpXHLRSHKsPsK3cuz1Oy5dqg1KsfdMVdkUwlErQb0Igjz2xUV
+qJJ8Pil0Si4eiXvkWzbIWBcGKMiomTTOqAqr2dJ75siX5ZP6l24RqZItn7RQDuhr
+y0KnZgY2SeszQb6u0JETGbKjPmnAeukg35tYFin6Z5dHsO3E9EokOi07bCN5IIw4
+AUNYSKfBIY6HYTVvbm/GsfMSntxO6R0HI6dVQKJRiJ3hrgHduANOJQBHWM7bE24A
+v104OVkZ62rPZ/ypxb2Z+A0IP3ngAv6VY5oGHmOMDXtMQb+CBtmMgggyFT1DZ+Kt
+AA4H3i6LHqYskv21AdPW4f+br2b69a0Y9XcNrLBkiH2j9itk6Ihw6zZD5Jqj9tDv
+ZBMSIIVHlecQND2HFoCM9DCeFFaJlZVNGp9EnERyxIJezcKM0OZ7rFWv7ukbrCov
+CyrK4+JLaaOlrOEXTT2ob7StxdGXQps0rOP7A0cxf3mUqfX2F6VWKslpiAa9quuC
+5Auqh5vAdY4o0NObx50WRPoFSnOEpqa8yj3hAofl66mulB31VORgN6sH8l4=
+-----END CERTIFICATE REQUEST-----
diff --git a/qa/tls_certificates/client/client.key b/qa/tls_certificates/client/client.key
new file mode 100644
index 00000000000..49d7da54058
--- /dev/null
+++ b/qa/tls_certificates/client/client.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/qa/tls_certificates/client/client.pem b/qa/tls_certificates/client/client.pem
new file mode 100644
index 00000000000..ebca1a9920d
--- /dev/null
+++ b/qa/tls_certificates/client/client.pem
@@ -0,0 +1,113 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIFLDCCAxQCAQEwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCVVMxEzARBgNV
+BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xGTAXBgNVBAoM
+EEdpdExhYiBBdXRob3JpdHkwHhcNMjEwMjEyMDc0NTM0WhcNMzEwMjEwMDc0NTM0
+WjBjMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
+U2FuIEZyYW5jaXNjbzEWMBQGA1UECgwNR2l0TGFiIENsaWVudDEPMA0GA1UEAwwG
+Q2xpZW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwZHPYiri29q+
+1qDh6ucjKztoZ9I0gqG4skuYs7jxj7jTOG/+rkYUVB+Eltq0m76rWEEA6OFW5Yze
+E+aZOYnLYi31BwhJZI2LHDWUsdDuX936FVr5B7l+nrvARVhhARbfhjFVAljcAmDy
+Q+cSgGxgM5de/KhJ0juU25lhe2rCViuJYUsCWny4pN91KhdLJCoPxQRxFDNKG/+k
+foacxKFwEtgz185xLgNZdydwhiY5yh4+P6rCMYqKAvnl2w6L/dPQmHasWbH4Gdvk
+TGCaxiJ7NBM4Lkv+uZmjHPnBmIdLnt+Yjb/lQmaSPA379yLA4L1n/JucmlUCMpVa
+KcJTPEUzUKM4u705XLqsRVH2YmcWAQH8XPw42Llw5T4fAooR+kyMN/zigPNdw7ZC
+r+2jW5rk95gb8iEbheVaSrGIAWPqcwrSTcna5Khbzy/najf2oAM87h95D2Fhg7eW
+LhoccImcuWEGFrmUGwPwS4Zxr2XeAFim8VVVMx9uGd+5u1AscfZFWKJP3j6FwpDH
+L4I7OXFh34INxluxKQ22+PEcIUkbqpGaLZ5U+ZTw8WOy77oflUkAEu1xoEBah+Nf
+5dr6b+n+8rSddCk3mDsgpDY5E3Uv8/FH2vxRmTpiq8ObdmMbNo9Qf+CpMNg4CG+v
+f96uqj69r3aqG3MEbRdy0UjgdaaeNx0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA
+OvEPqiQx5RuiqdVDzNAGGW6SzGoyehwVL0JkYvwHPZ8gOW4XBGl9Dtnkb3M7GeYq
+urZnoplk1uyMnNin2MVA0hRfCwCv7ix56Sh45odpN9scnXsr9I/e6ZfbQB7vFGnV
+NDESsOZKzkydameUBTu9yBk7mlV9jA7LpKipe67doptANURZjF8crmCeTvY3b1cF
+XbFe31FqvKdXeJgZU99kGUSncSS/1dWxbwyZZDBCqWfDlNh7Om+6RB1cMlQfal5z
+hqCYMGBB8YsMY1+l7l8eQDawrZNbs9yE4iqd6FXvss7o02cC1b7moZB+1JhOwwJ1
+wmgXuRiR5ynsb34LjFOicdm4YVmqiqXCW6Pr/DH/pkX8CI3Zu2hjatbgQrkGxXqT
+T1O/o48xwa8MBfviy7gkdCrapBkx0ojNLYNW6NTR3LNT4WYEQWOnqkm73Is9aVCy
+1doL6zG8chvCxLHXtpEMMPkOKpoWjokdCD4K5HAoIqmR904kOM5jCuETTWm0MD0e
+vKeWzck6YDt+zBhCD4k7yqF++d3ufcY2eCmVlwe0wH4srX/e4ni0tBKF25j3xLUA
+U+HI7Wa88zBAp3iN3CD/iWu8LBwTUlmRN8l7bi+O/AaKE08KvtzV5hhZ4c1UJa+N
+d4txM9tqkwMTFTFkRzduwuaIKB3Gaz1IWcOUJe5oO5M=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFizCCA3OgAwIBAgIUJBX+SiNuqUYjf33EuMObynTcKx0wDQYJKoZIhvcNAQEL
+BQAwVTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
+DVNhbiBGcmFuY2lzY28xGTAXBgNVBAoMEEdpdExhYiBBdXRob3JpdHkwHhcNMjEw
+MjExMDYyMTUzWhcNMzEwMjA5MDYyMTUzWjBVMQswCQYDVQQGEwJVUzETMBEGA1UE
+CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQ
+R2l0TGFiIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ALxpL/dfJwhIWGYK93ovIVj+gqvJI58Sga7eWlp2LpuFQZETjJBA79R0gcwr42ph
+ch1BuxoxkYizM8sqIyFa5aW8SCWmO+IQzedKWZv+UWZg6pG+Fzyp6GO1wmXZdeXw
+xRiXp2qV+rqA8DaL2g1c2u6TB/mcfNTrfsSP3045yQW+4mdNx/g4wBf0dMpHe5DJ
+5jIvowa2O0kesq1UQ1eM9IMNSwW8fMQenV+F41LWE1NO726ksglih9TQjAIrlX6I
+XVmw0lgYegt2G+YQJ68nf2UmvK+C0KqzTZgqmzNMQnuSiJXMnlZvlgdLXTyTWCuq
+tyxp3+Z2Wshk/Cghic2MCm2XwWBIqYGu+20qoPM61c3Rk5++2VOcajD1yCYxVtM2
+akVP/e9arlCdi/CtJh3qvOlj9Uhs6a1UR/ZngpPLOa3r4JazZc04pK7q3ZynmoUL
+oDPF9AKOikvhYKxTYsgZ65VhI3myTBjQFk9qX++z2HF9UImGblqUtckn3eIoI8n2
+wd4pO/OFeFSXpR7jMywCwXTpC8yTTbuVzHEz8H83/qtsbjtw961g4kb8Vzh1zy73
+PFiJNI7hZlP1I5dqNTOAv+GnwiSnF28i7xbdkIfmjYqwcwGhAO7rjifq8ygBH3sF
+0I/6dnw4BvNlSgSJlJ1+2eH1uiaikpuOGtQAttz536dNAgMBAAGjUzBRMB0GA1Ud
+DgQWBBQSNZ46Xu4rfGVIPIQJpduWHJ+AQjAfBgNVHSMEGDAWgBQSNZ46Xu4rfGVI
+PIQJpduWHJ+AQjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQC1
+4REbDKF1tdYeCxpmQHXLHu7OkrgKIea6eKxf8mI+ZsJA4iNr3aiZYU5Wm+uAq3mK
+x6mrQRaqoo6JNbie5Tw8fU2c71EO4t3vwB7YOsBtcV0YrMtg316UE0lk+6kL0TRD
+tV7dAGCB3wXZVLPolC26/kecc258p6h4rCJ8Gi6FsIKGBisTFk3QOdLG3DQNulPF
+2bZaJjs/6HqLL+QMdChUfJP3i71LdNxzwXNPbjJ3fm5f9RNeOcWo6oI2fkQArl2i
+vcP/QtuqeOoJusbeL9zaF/EFlOggjkEtzFWCB05d6J7dMKYp5Lg4eMZQHPw6ycdk
+Ek/XTupvBk+8UiXeHLvX6II9zww9+gm3uycPiO/CSPNw4yQBPPGW+30WznbedsuY
+m79rxuq50KYvseJSPv7lw8v77ajQbRQzFi4frAFR+A1g8FArLxdpIptI9E+ekmaB
+UMhCmi17mEuBtj8Hc3VrokTFtAJV6YNIk1X+Q/zLh4TaR5mm6C/82j/ZvkSm5OX7
+TfaayRWDr7AfDKeG5Amt52BmYncsPUXnOofSz5UkqpeOWr0rKn+A7f2BeUP9R2nY
+6DncxYA+yOgU7RpnMBscsW6SkVIMJKFrfeZ1SbvZGRJd4L1PwfeaU+3yEG6oAfMa
+CFquw23nWhjvUlnCe9BaUiEtOJ2ruGjdu2sdvXPcnw==
+-----END CERTIFICATE-----
diff --git a/qa/tls_certificates/client/client.pfx b/qa/tls_certificates/client/client.pfx
new file mode 100644
index 00000000000..6931cfe659a
--- /dev/null
+++ b/qa/tls_certificates/client/client.pfx
Binary files differ