summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
Diffstat (limited to 'qa')
-rw-r--r--qa/Gemfile46
-rw-r--r--qa/Gemfile.lock250
-rw-r--r--qa/Rakefile4
-rw-r--r--qa/chemlab-library-gitlab.gemspec2
-rw-r--r--qa/lib/gitlab/page/admin/subscription.rb2
-rw-r--r--qa/lib/gitlab/page/group/settings/usage_quota.stub.rb404
-rw-r--r--qa/lib/gitlab/page/group/settings/usage_quotas.rb33
-rw-r--r--qa/qa.rb17
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb (renamed from qa/qa/fixtures/package_managers/maven/build_install.gradle.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb (renamed from qa/qa/fixtures/package_managers/maven/build_upload.gradle.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb (renamed from qa/qa/fixtures/package_managers/maven/gradle_install_package.yaml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb (renamed from qa/qa/fixtures/package_managers/maven/gradle_upload_package.yaml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/consumer/gitlab_ci.yaml.erb (renamed from qa/qa/fixtures/package_managers/maven/maven_install_package.yaml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/consumer/pom.xml.erb (renamed from qa/qa/fixtures/package_managers/maven/client_pom.xml.erb)4
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/consumer/settings.xml.erb16
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/producer/gitlab_ci.yaml.erb (renamed from qa/qa/fixtures/package_managers/maven/maven_upload_package.yaml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/producer/pom.xml.erb (renamed from qa/qa/fixtures/package_managers/maven/package_pom.xml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/producer/settings.xml.erb (renamed from qa/qa/fixtures/package_managers/maven/settings.xml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/settings_with_pat.xml.erb (renamed from qa/qa/fixtures/package_managers/maven/settings_with_pat.xml.erb)0
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/gitlab_ci.yaml.erb9
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/pom.xml.erb22
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb8
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb23
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/settings.xml.erb16
-rw-r--r--qa/qa/fixtures/software_licenses/other7
-rw-r--r--qa/qa/flow/purchase.rb7
-rw-r--r--qa/qa/mobile/page/main/menu.rb4
-rw-r--r--qa/qa/page/admin/menu.rb69
-rw-r--r--qa/qa/page/base.rb5
-rw-r--r--qa/qa/page/component/clone_panel.rb12
-rw-r--r--qa/qa/page/component/content_editor.rb6
-rw-r--r--qa/qa/page/component/groups_filter.rb2
-rw-r--r--qa/qa/page/component/invite_members_modal.rb10
-rw-r--r--qa/qa/page/component/issuable/sidebar.rb9
-rw-r--r--qa/qa/page/component/legacy_clone_panel.rb8
-rw-r--r--qa/qa/page/component/namespace_select.rb6
-rw-r--r--qa/qa/page/component/wiki_page_form.rb7
-rw-r--r--qa/qa/page/group/show.rb4
-rw-r--r--qa/qa/page/main/menu.rb8
-rw-r--r--qa/qa/page/main/terms.rb2
-rw-r--r--qa/qa/page/merge_request/new.rb1
-rw-r--r--qa/qa/page/merge_request/show.rb5
-rw-r--r--qa/qa/page/project/secure/configuration_form.rb26
-rw-r--r--qa/qa/page/project/settings/default_branch.rb14
-rw-r--r--qa/qa/page/project/settings/mirroring_repositories.rb2
-rw-r--r--qa/qa/page/project/settings/services/jira.rb14
-rw-r--r--qa/qa/page/project/tag/new.rb12
-rw-r--r--qa/qa/resource/issuable.rb79
-rw-r--r--qa/qa/resource/issue.rb27
-rw-r--r--qa/qa/resource/merge_request.rb26
-rw-r--r--qa/qa/resource/project.rb20
-rw-r--r--qa/qa/resource/project_imported_from_github.rb9
-rw-r--r--qa/qa/resource/protected_branch.rb4
-rw-r--r--qa/qa/resource/user.rb2
-rw-r--r--qa/qa/resource/wiki/group_page.rb1
-rw-r--r--qa/qa/runtime/env.rb9
-rw-r--r--qa/qa/scenario/test/instance.rb36
-rw-r--r--qa/qa/scenario/test/integration/github.rb20
-rw-r--r--qa/qa/specs/features/api/1_manage/group_access_token_spec.rb4
-rw-r--r--qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb (renamed from qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb)26
-rw-r--r--qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb (renamed from qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb)253
-rw-r--r--qa/qa/specs/features/api/1_manage/integrations/webhook_events_spec.rb (renamed from qa/qa/specs/features/api/3_create/integrations/webhook_events_spec.rb)7
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb6
-rw-r--r--qa/qa/specs/features/api/1_manage/project_access_token_spec.rb8
-rw-r--r--qa/qa/specs/features/api/1_manage/rate_limits_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb4
-rw-r--r--qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb10
-rw-r--r--qa/qa/specs/features/api/1_manage/users_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb16
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb)10
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb)15
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb (renamed from qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb)4
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb (renamed from qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_status_emails_spec.rb)2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb20
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb)19
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb95
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb51
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb)5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb)5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb)12
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb24
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb24
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb93
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb51
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb26
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb22
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb200
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb214
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb36
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb28
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb20
-rw-r--r--qa/qa/specs/features/sanity/framework_spec.rb2
-rw-r--r--qa/qa/specs/qa_deprecation_toolkit_env.rb30
-rw-r--r--qa/qa/specs/spec_helper.rb3
-rw-r--r--qa/qa/support/api.rb25
-rw-r--r--qa/qa/support/formatters/test_stats_formatter.rb1
-rw-r--r--qa/qa/support/repeater.rb3
-rw-r--r--qa/qa/tools/ci/non_empty_suites.rb81
-rw-r--r--qa/qa/tools/ci/qa_changes.rb51
-rw-r--r--qa/qa/tools/delete_test_ssh_keys.rb2
-rw-r--r--qa/qa/tools/initialize_gitlab_auth.rb2
-rw-r--r--qa/qa/tools/test_resources_handler.rb105
-rw-r--r--qa/qa/vendor/jira/jira_issue_page.rb47
-rw-r--r--qa/spec/resource/user_spec.rb4
-rw-r--r--qa/spec/runtime/env_spec.rb31
-rw-r--r--qa/spec/scenario/test/integration/github_spec.rb21
-rw-r--r--qa/spec/support/formatters/test_stats_formatter_spec.rb5
-rw-r--r--qa/spec/tools/ci/non_empty_suites_spec.rb4
-rw-r--r--qa/spec/tools/ci/qa_changes_spec.rb52
-rw-r--r--qa/spec/tools/reliable_report_spec.rb3
-rw-r--r--qa/tasks/ci.rake4
139 files changed, 1955 insertions, 1267 deletions
diff --git a/qa/Gemfile b/qa/Gemfile
index cf939f8e301..12e5d66fc6b 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,46 +2,48 @@
source 'https://rubygems.org'
-gem 'gitlab-qa', '~> 8', require: 'gitlab/qa'
+gem 'gitlab-qa', '~> 8', '>= 8.8.0', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
-gem 'allure-rspec', '~> 2.16.0'
-gem 'capybara', '~> 3.35.0'
-gem 'capybara-screenshot', '~> 1.0.23'
+gem 'allure-rspec', '~> 2.18.0'
+gem 'capybara', '~> 3.37.1'
+gem 'capybara-screenshot', '~> 1.0.26'
gem 'rake', '~> 13'
-gem 'rspec', '~> 3.10'
-gem 'selenium-webdriver', '~> 4.0'
-gem 'airborne', '~> 0.3.4', require: false # airborne is messing with rspec sandboxed mode so not requiring by default
+gem 'rspec', '~> 3.11'
+gem 'selenium-webdriver', '~> 4.5'
+gem 'airborne', '~> 0.3.7', require: false # airborne is messing with rspec sandboxed mode so not requiring by default
gem 'rest-client', '~> 2.1.0'
gem 'rspec-retry', '~> 0.6.1', require: 'rspec/retry'
-gem 'rspec_junit_formatter', '~> 0.4.1'
-gem 'faker', '~> 2.19', '>= 2.19.0'
+gem 'rspec_junit_formatter', '~> 0.6.0'
+gem 'faker', '~> 2.23'
gem 'knapsack', '~> 4.0'
-gem 'parallel_tests', '~> 2.29'
-gem 'rotp', '~> 3.1.0'
-gem 'timecop', '~> 0.9.1'
+gem 'parallel_tests', '~> 3.13'
+gem 'rotp', '~> 6.2.0'
+gem 'timecop', '~> 0.9.5'
gem 'parallel', '~> 1.19'
gem 'rainbow', '~> 3.0.0'
-gem 'rspec-parameterized', '~> 0.4.2'
-gem 'octokit', '~> 4.21'
-gem 'webdrivers', '~> 5.0'
+gem 'rspec-parameterized', '~> 0.5.2'
+gem 'octokit', '~> 5.6.1'
+gem "faraday-retry", "~> 2.0"
+gem 'webdrivers', '~> 5.2'
gem 'zeitwerk', '~> 2.4'
gem 'influxdb-client', '~> 1.17'
-gem 'terminal-table', '~> 3.0.0', require: false
+gem 'terminal-table', '~> 3.0.2', require: false
gem 'slack-notifier', '~> 2.4', require: false
-gem 'fog-google', '~> 1.17', require: false
+gem 'fog-google', '~> 1.19', require: false
+gem 'fog-core', '2.1.0', require: false # fog-google generates a ton of warnings with latest core
gem "warning", "~> 1.3"
gem 'confiner', '~> 0.3'
-gem 'chemlab', '~> 0.9'
+gem 'chemlab', '~> 0.10'
gem 'chemlab-library-www-gitlab-com', '~> 0.1'
# dependencies for jenkins client
-gem 'nokogiri', '~> 1.12'
+gem 'nokogiri', '~> 1.13', '>= 1.13.9'
-gem 'deprecation_toolkit', '~> 1.5.1', require: false
+gem 'deprecation_toolkit', '~> 2.0.0', require: false
group :development do
- gem 'pry-byebug', '~> 3.5.1', platform: :mri
- gem "ruby-debug-ide", "~> 0.7.0"
+ gem 'pry-byebug', '~> 3.10.1', platform: :mri
+ gem "ruby-debug-ide", "~> 0.7.3"
end
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index dd14b675769..23f82f553f1 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -1,28 +1,24 @@
GEM
remote: https://rubygems.org/
specs:
- abstract_type (0.0.7)
activesupport (6.1.4.7)
concurrent-ruby (~> 1.0, >= 1.0.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)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
- airborne (0.3.4)
+ airborne (0.3.7)
activesupport
rack
rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8)
- allure-rspec (2.16.1)
- allure-ruby-commons (= 2.16.1)
+ allure-rspec (2.18.0)
+ allure-ruby-commons (= 2.18.0)
rspec-core (>= 3.8, < 4)
- allure-ruby-commons (2.16.1)
+ allure-ruby-commons (2.18.0)
mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4)
require_all (>= 2, < 4)
@@ -30,19 +26,20 @@ GEM
ast (2.4.2)
binding_ninja (0.2.3)
builder (3.2.4)
- byebug (9.1.0)
- capybara (3.35.3)
+ byebug (11.1.3)
+ capybara (3.37.1)
addressable
+ matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
- capybara-screenshot (1.0.23)
+ capybara-screenshot (1.0.26)
capybara (>= 1.0, < 4)
launchy
- chemlab (0.9.2)
+ chemlab (0.10.0)
colorize (~> 0.8)
i18n (~> 1.8)
rake (>= 12, < 14)
@@ -53,40 +50,25 @@ GEM
childprocess (4.1.0)
coderay (1.1.2)
colorize (0.8.1)
- concord (0.1.5)
- adamantium (~> 0.2.0)
- equalizer (~> 0.0.9)
concurrent-ruby (1.1.10)
confiner (0.3.0)
gitlab (>= 4.17)
zeitwerk (~> 2.5.1)
declarative (0.0.20)
- deprecation_toolkit (1.5.1)
- activesupport (>= 4.2)
+ deprecation_toolkit (2.0.0)
+ activesupport (>= 5.2)
diff-lcs (1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
- equalizer (0.0.11)
- excon (0.88.0)
- faker (2.19.0)
- i18n (>= 1.6, < 2)
- faraday (1.5.1)
- faraday-em_http (~> 1.0)
- faraday-em_synchrony (~> 1.0)
- faraday-excon (~> 1.1)
- faraday-httpclient (~> 1.0.1)
- faraday-net_http (~> 1.0)
- faraday-net_http_persistent (~> 1.1)
- faraday-patron (~> 1.0)
- multipart-post (>= 1.2, < 3)
+ excon (0.92.4)
+ faker (2.23.0)
+ i18n (>= 1.8.11, < 2)
+ faraday (2.5.2)
+ faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
- faraday-em_http (1.0.0)
- faraday-em_synchrony (1.0.0)
- faraday-excon (1.1.0)
- faraday-httpclient (1.0.1)
- faraday-net_http (1.0.1)
- faraday-net_http_persistent (1.2.0)
- faraday-patron (1.0.0)
+ faraday-net_http (3.0.0)
+ faraday-retry (2.0.0)
+ faraday (~> 2.0)
ffi (1.15.5)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
@@ -96,8 +78,8 @@ GEM
excon (~> 0.58)
formatador (~> 0.2)
mime-types
- fog-google (1.17.0)
- fog-core (<= 2.1.0)
+ fog-google (1.19.0)
+ fog-core (< 2.3)
fog-json (~> 1.2)
fog-xml (~> 0.1.0)
google-apis-compute_v1 (~> 0.14)
@@ -118,17 +100,18 @@ GEM
gitlab (4.18.0)
httparty (~> 0.18)
terminal-table (>= 1.5.1)
- gitlab-qa (8.4.2)
+ gitlab-qa (8.8.0)
activesupport (~> 6.1)
gitlab (~> 4.18.0)
http (~> 5.0)
nokogiri (~> 1.10)
- rainbow (~> 3.0.0)
+ rainbow (>= 3, < 4)
table_print (= 1.5.7)
- zeitwerk (~> 2.4)
- google-apis-compute_v1 (0.21.0)
- google-apis-core (>= 0.4, < 2.a)
- google-apis-core (0.4.1)
+ toxiproxy (~> 2.0.2)
+ zeitwerk (>= 2, < 3)
+ google-apis-compute_v1 (0.51.0)
+ google-apis-core (>= 0.7.2, < 2.a)
+ google-apis-core (0.9.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -137,22 +120,22 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
- google-apis-dns_v1 (0.16.0)
- google-apis-core (>= 0.4, < 2.a)
- google-apis-iamcredentials_v1 (0.8.0)
- google-apis-core (>= 0.4, < 2.a)
- google-apis-monitoring_v3 (0.18.0)
- google-apis-core (>= 0.4, < 2.a)
- google-apis-pubsub_v1 (0.10.0)
- google-apis-core (>= 0.4, < 2.a)
- google-apis-sqladmin_v1beta4 (0.21.0)
- google-apis-core (>= 0.4, < 2.a)
- google-apis-storage_v1 (0.9.0)
- google-apis-core (>= 0.4, < 2.a)
+ google-apis-dns_v1 (0.27.0)
+ google-apis-core (>= 0.7.2, < 2.a)
+ google-apis-iamcredentials_v1 (0.14.0)
+ google-apis-core (>= 0.7.2, < 2.a)
+ google-apis-monitoring_v3 (0.33.0)
+ google-apis-core (>= 0.7, < 2.a)
+ google-apis-pubsub_v1 (0.28.0)
+ google-apis-core (>= 0.7.2, < 2.a)
+ google-apis-sqladmin_v1beta4 (0.36.0)
+ google-apis-core (>= 0.7.2, < 2.a)
+ google-apis-storage_v1 (0.18.0)
+ google-apis-core (>= 0.7, < 2.a)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
- googleauth (1.1.0)
- faraday (>= 0.17.3, < 2.0)
+ googleauth (1.2.0)
+ faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
@@ -173,22 +156,20 @@ GEM
httpclient (2.8.3)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
- ice_nine (0.11.2)
influxdb-client (1.17.0)
- jwt (2.3.0)
+ jwt (2.5.0)
knapsack (4.0.0)
rake
- launchy (2.4.3)
- addressable (~> 2.3)
+ launchy (2.5.0)
+ addressable (~> 2.7)
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
macaddr (1.7.2)
systemu (~> 2.6.5)
+ matrix (0.4.2)
memoist (0.16.2)
- memoizable (0.4.2)
- thread_safe (~> 0.3, >= 0.3.1)
- method_source (0.9.0)
+ method_source (1.0.0)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2022.0105)
@@ -197,18 +178,17 @@ GEM
minitest (5.16.3)
multi_json (1.15.0)
multi_xml (0.6.0)
- multipart-post (2.1.1)
netrc (0.11.0)
- nokogiri (1.13.8)
+ nokogiri (1.13.9)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
- octokit (4.25.1)
+ octokit (5.6.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
- oj (3.13.11)
+ oj (3.13.21)
os (1.1.4)
parallel (1.19.2)
- parallel_tests (2.29.0)
+ parallel_tests (3.13.0)
parallel
parser (3.1.2.1)
ast (~> 2.4.1)
@@ -216,13 +196,12 @@ GEM
coderay
parser
unparser
- procto (0.0.3)
- pry (0.11.3)
- coderay (~> 1.1.0)
- method_source (~> 0.9.0)
- pry-byebug (3.5.1)
- byebug (~> 9.1)
- pry (~> 0.10)
+ pry (0.14.1)
+ coderay (~> 1.1)
+ method_source (~> 1.0)
+ pry-byebug (3.10.1)
+ byebug (~> 11.0)
+ pry (>= 0.13, < 0.15)
public_suffix (5.0.0)
racc (1.6.0)
rack (2.2.3.1)
@@ -231,7 +210,7 @@ GEM
rainbow (3.0.0)
rake (13.0.6)
regexp_parser (2.1.1)
- representable (3.1.1)
+ representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
@@ -243,44 +222,45 @@ GEM
netrc (~> 0.8)
retriable (3.1.2)
rexml (3.2.5)
- rotp (3.1.0)
- rspec (3.10.0)
- rspec-core (~> 3.10.0)
- rspec-expectations (~> 3.10.0)
- rspec-mocks (~> 3.10.0)
- rspec-core (3.10.1)
- rspec-support (~> 3.10.0)
- rspec-expectations (3.10.1)
+ rotp (6.2.0)
+ rspec (3.11.0)
+ rspec-core (~> 3.11.0)
+ rspec-expectations (~> 3.11.0)
+ rspec-mocks (~> 3.11.0)
+ rspec-core (3.11.0)
+ rspec-support (~> 3.11.0)
+ rspec-expectations (3.11.1)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.10.0)
- rspec-mocks (3.10.2)
+ rspec-support (~> 3.11.0)
+ rspec-mocks (3.11.1)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.10.0)
- rspec-parameterized (0.4.2)
+ rspec-support (~> 3.11.0)
+ rspec-parameterized (0.5.2)
binding_ninja (>= 0.2.3)
parser
proc_to_ast
rspec (>= 2.13, < 4)
unparser
- rspec-retry (0.6.1)
+ rspec-retry (0.6.2)
rspec-core (> 3.3)
- rspec-support (3.10.2)
- rspec_junit_formatter (0.4.1)
+ rspec-support (3.11.1)
+ rspec_junit_formatter (0.6.0)
rspec-core (>= 2, < 4, != 2.12.0)
- ruby-debug-ide (0.7.2)
+ ruby-debug-ide (0.7.3)
rake (>= 0.8.1)
- ruby2_keywords (0.0.4)
+ ruby2_keywords (0.0.5)
rubyzip (2.3.2)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
- selenium-webdriver (4.0.3)
+ selenium-webdriver (4.5.0)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
- rubyzip (>= 1.2.2)
- signet (0.16.0)
+ rubyzip (>= 1.2.2, < 3.0)
+ websocket (~> 1.0)
+ signet (0.17.0)
addressable (~> 2.8)
- faraday (>= 0.17.3, < 2.0)
+ faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
slack-notifier (2.4.0)
@@ -288,8 +268,8 @@ GEM
table_print (1.5.7)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
- thread_safe (0.3.6)
- timecop (0.9.1)
+ timecop (0.9.5)
+ toxiproxy (2.0.2)
trailblazer-option (0.1.2)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
@@ -297,26 +277,22 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
- unicode-display_width (2.2.0)
- unparser (0.4.7)
- abstract_type (~> 0.0.7)
- adamantium (~> 0.2.0)
- concord (~> 0.1.5)
+ unicode-display_width (2.3.0)
+ unparser (0.6.5)
diff-lcs (~> 1.3)
- equalizer (~> 0.0.9)
- parser (>= 2.6.5)
- procto (~> 0.0.2)
+ parser (>= 3.1.0)
uuid (2.3.9)
macaddr (~> 1.0)
warning (1.3.0)
- watir (6.19.1)
+ watir (7.1.0)
regexp_parser (>= 1.2, < 3)
- selenium-webdriver (>= 3.142.7)
- webdrivers (5.0.0)
+ selenium-webdriver (~> 4.0)
+ webdrivers (5.2.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
webrick (1.7.0)
+ websocket (1.2.9)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.5.4)
@@ -326,40 +302,42 @@ PLATFORMS
DEPENDENCIES
activesupport (~> 6.1.4.7)
- airborne (~> 0.3.4)
- allure-rspec (~> 2.16.0)
- capybara (~> 3.35.0)
- capybara-screenshot (~> 1.0.23)
- chemlab (~> 0.9)
+ airborne (~> 0.3.7)
+ allure-rspec (~> 2.18.0)
+ capybara (~> 3.37.1)
+ capybara-screenshot (~> 1.0.26)
+ chemlab (~> 0.10)
chemlab-library-www-gitlab-com (~> 0.1)
confiner (~> 0.3)
- deprecation_toolkit (~> 1.5.1)
- faker (~> 2.19, >= 2.19.0)
- fog-google (~> 1.17)
- gitlab-qa (~> 8)
+ deprecation_toolkit (~> 2.0.0)
+ faker (~> 2.23)
+ faraday-retry (~> 2.0)
+ fog-core (= 2.1.0)
+ fog-google (~> 1.19)
+ gitlab-qa (~> 8, >= 8.8.0)
influxdb-client (~> 1.17)
knapsack (~> 4.0)
- nokogiri (~> 1.12)
- octokit (~> 4.21)
+ nokogiri (~> 1.13, >= 1.13.9)
+ octokit (~> 5.6.1)
parallel (~> 1.19)
- parallel_tests (~> 2.29)
- pry-byebug (~> 3.5.1)
+ parallel_tests (~> 3.13)
+ pry-byebug (~> 3.10.1)
rainbow (~> 3.0.0)
rake (~> 13)
rest-client (~> 2.1.0)
- rotp (~> 3.1.0)
- rspec (~> 3.10)
- rspec-parameterized (~> 0.4.2)
+ rotp (~> 6.2.0)
+ rspec (~> 3.11)
+ rspec-parameterized (~> 0.5.2)
rspec-retry (~> 0.6.1)
- rspec_junit_formatter (~> 0.4.1)
- ruby-debug-ide (~> 0.7.0)
- selenium-webdriver (~> 4.0)
+ rspec_junit_formatter (~> 0.6.0)
+ ruby-debug-ide (~> 0.7.3)
+ selenium-webdriver (~> 4.5)
slack-notifier (~> 2.4)
- terminal-table (~> 3.0.0)
- timecop (~> 0.9.1)
+ terminal-table (~> 3.0.2)
+ timecop (~> 0.9.5)
warning (~> 1.3)
- webdrivers (~> 5.0)
+ webdrivers (~> 5.2)
zeitwerk (~> 2.4)
BUNDLED WITH
- 2.3.15
+ 2.3.24
diff --git a/qa/Rakefile b/qa/Rakefile
index ada27596ae4..6f94c63b4de 100644
--- a/qa/Rakefile
+++ b/qa/Rakefile
@@ -11,7 +11,7 @@ end
desc "Initialize GitLab with an access token"
task :initialize_gitlab_auth, [:address] do |_, args|
- QA::Tools::InitializeGitLabAuth.new(args).run
+ QA::Tools::InitializeGitlabAuth.new(args).run
end
desc "Generate Performance Testdata"
@@ -46,7 +46,7 @@ task generate_data_and_run_load_test: [:generate_perf_testdata, :run_artillery_l
desc "Deletes test ssh keys a user"
task :delete_test_ssh_keys, [:title_portion, :delete_before, :dry_run] do |_, args|
- QA::Tools::DeleteTestSSHKeys.new(args).run
+ QA::Tools::DeleteTestSshKeys.new(args).run
end
desc "Deletes projects directly under the provided group"
diff --git a/qa/chemlab-library-gitlab.gemspec b/qa/chemlab-library-gitlab.gemspec
index 9af4a650d98..309de157757 100644
--- a/qa/chemlab-library-gitlab.gemspec
+++ b/qa/chemlab-library-gitlab.gemspec
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-$:.unshift(File.expand_path('lib', __dir__))
+$LOAD_PATH.unshift(File.expand_path('lib', __dir__))
Gem::Specification.new do |spec|
spec.name = 'chemlab-library-gitlab'
diff --git a/qa/lib/gitlab/page/admin/subscription.rb b/qa/lib/gitlab/page/admin/subscription.rb
index ef73bad2879..058cf8d281e 100644
--- a/qa/lib/gitlab/page/admin/subscription.rb
+++ b/qa/lib/gitlab/page/admin/subscription.rb
@@ -23,7 +23,7 @@ module Gitlab
h2 :users_over_subscription
table :subscription_history
- span :no_valid_license_alert, text: /no longer has a valid license/
+ div :no_valid_license_alert, text: /no longer has a valid license/
h3 :no_active_subscription_title, text: /do not have an active subscription/
def accept_terms
diff --git a/qa/lib/gitlab/page/group/settings/usage_quota.stub.rb b/qa/lib/gitlab/page/group/settings/usage_quota.stub.rb
index 192e71e6c90..2a5d9a6bb5e 100644
--- a/qa/lib/gitlab/page/group/settings/usage_quota.stub.rb
+++ b/qa/lib/gitlab/page/group/settings/usage_quota.stub.rb
@@ -5,51 +5,51 @@ module Gitlab
module Group
module Settings
module UsageQuota
- # @note Defined as +link :pipeline_tab+
- # Clicks +pipeline_tab+
- def pipeline_tab
+ # @note Defined as +link :seats_tab+
+ # Clicks +seats_tab+
+ def seats_tab
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.pipeline_tab_element).to exist
+ # expect(usage_quota.seats_tab_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
- def pipeline_tab_element
+ def seats_tab_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_pipeline_tab
+ # expect(usage_quota).to be_seats_tab
# end
- # @return [Boolean] true if the +pipeline_tab+ element is present on the page
- def pipeline_tab?
+ # @return [Boolean] true if the +seats_tab+ element is present on the page
+ def seats_tab?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +link :storage_tab+
- # Clicks +storage_tab+
- def storage_tab
+ # @note Defined as +link :pipelines_tab+
+ # Clicks +pipelines_tab+
+ def pipelines_tab
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.storage_tab_element).to exist
+ # expect(usage_quota.pipelines_tab_element).to exist
# end
# @return [Watir::Link] The raw +Link+ element
- def storage_tab_element
+ def pipelines_tab_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_storage_tab
+ # expect(usage_quota).to be_pipelines_tab
# end
- # @return [Boolean] true if the +storage_tab+ element is present on the page
- def storage_tab?
+ # @return [Boolean] true if the +pipelines_tab+ element is present on the page
+ def pipelines_tab?
# This is a stub, used for indexing. The method is dynamically generated.
end
@@ -77,6 +77,102 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
+ # @note Defined as +div :plan_ci_minutes+
+ # @return [String] The text content or value of +plan_ci_minutes+
+ def plan_ci_minutes
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.plan_ci_minutes_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def plan_ci_minutes_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_plan_ci_minutes
+ # end
+ # @return [Boolean] true if the +plan_ci_minutes+ element is present on the page
+ def plan_ci_minutes?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :additional_ci_minutes+
+ # @return [String] The text content or value of +additional_ci_minutes+
+ def additional_ci_minutes
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.additional_ci_minutes_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def additional_ci_minutes_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_additional_ci_minutes
+ # end
+ # @return [Boolean] true if the +additional_ci_minutes+ element is present on the page
+ def additional_ci_minutes?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :ci_purchase_successful_alert+
+ # @return [String] The text content or value of +ci_purchase_successful_alert+
+ def ci_purchase_successful_alert
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.ci_purchase_successful_alert_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def ci_purchase_successful_alert_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_ci_purchase_successful_alert
+ # end
+ # @return [Boolean] true if the +ci_purchase_successful_alert+ element is present on the page
+ def ci_purchase_successful_alert?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +link :storage_tab+
+ # Clicks +storage_tab+
+ def storage_tab
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.storage_tab_element).to exist
+ # end
+ # @return [Watir::Link] The raw +Link+ element
+ def storage_tab_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_storage_tab
+ # end
+ # @return [Boolean] true if the +storage_tab+ element is present on the page
+ def storage_tab?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
# @note Defined as +link :buy_storage+
# Clicks +buy_storage+
def buy_storage
@@ -101,123 +197,315 @@ module Gitlab
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +strong :additional_minutes+
- # @return [String] The text content or value of +additional_minutes+
- def additional_minutes
+ # @note Defined as +div :used_storage_message+
+ # @return [String] The text content or value of +used_storage_message+
+ def used_storage_message
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.used_storage_message_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def used_storage_message_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_used_storage_message
+ # end
+ # @return [Boolean] true if the +used_storage_message+ element is present on the page
+ def used_storage_message?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :group_usage_message+
+ # @return [String] The text content or value of +group_usage_message+
+ def group_usage_message
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.group_usage_message_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def group_usage_message_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_group_usage_message
+ # end
+ # @return [Boolean] true if the +group_usage_message+ element is present on the page
+ def group_usage_message?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :dependency_proxy_usage+
+ # @return [String] The text content or value of +dependency_proxy_usage+
+ def dependency_proxy_usage
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.dependency_proxy_usage_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def dependency_proxy_usage_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_dependency_proxy_usage
+ # end
+ # @return [Boolean] true if the +dependency_proxy_usage+ element is present on the page
+ def dependency_proxy_usage?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +span :dependency_proxy_size+
+ # @return [String] The text content or value of +dependency_proxy_size+
+ def dependency_proxy_size
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.additional_minutes_element).to exist
+ # expect(usage_quota.dependency_proxy_size_element).to exist
# end
- # @return [Watir::Strong] The raw +Strong+ element
- def additional_minutes_element
+ # @return [Watir::Span] The raw +Span+ element
+ def dependency_proxy_size_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_additional_minutes
+ # expect(usage_quota).to be_dependency_proxy_size
# end
- # @return [Boolean] true if the +additional_minutes+ element is present on the page
- def additional_minutes?
+ # @return [Boolean] true if the +dependency_proxy_size+ element is present on the page
+ def dependency_proxy_size?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +div :additional_minutes_usage+
- # @return [String] The text content or value of +additional_minutes_usage+
- def additional_minutes_usage
+ # @note Defined as +div :container_registry_usage+
+ # @return [String] The text content or value of +container_registry_usage+
+ def container_registry_usage
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.additional_minutes_usage_element).to exist
+ # expect(usage_quota.container_registry_usage_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
- def additional_minutes_usage_element
+ def container_registry_usage_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_additional_minutes_usage
+ # expect(usage_quota).to be_container_registry_usage
# end
- # @return [Boolean] true if the +additional_minutes_usage+ element is present on the page
- def additional_minutes_usage?
+ # @return [Boolean] true if the +container_registry_usage+ element is present on the page
+ def container_registry_usage?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +strong :plan_minutes+
- # @return [String] The text content or value of +plan_minutes+
- def plan_minutes
+ # @note Defined as +div :project_storage_used+
+ # @return [String] The text content or value of +project_storage_used+
+ def project_storage_used
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.plan_minutes_element).to exist
+ # expect(usage_quota.project_storage_used_element).to exist
# end
- # @return [Watir::Strong] The raw +Strong+ element
- def plan_minutes_element
+ # @return [Watir::Div] The raw +Div+ element
+ def project_storage_used_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_plan_minutes
+ # expect(usage_quota).to be_project_storage_used
# end
- # @return [Boolean] true if the +plan_minutes+ element is present on the page
- def plan_minutes?
+ # @return [Boolean] true if the +project_storage_used+ element is present on the page
+ def project_storage_used?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +div :plan_minutes_usage+
- # @return [String] The text content or value of +plan_minutes_usage+
- def plan_minutes_usage
+ # @note Defined as +div :project+
+ # @return [String] The text content or value of +project+
+ def project
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.plan_minutes_usage_element).to exist
+ # expect(usage_quota.project_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
- def plan_minutes_usage_element
+ def project_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_plan_minutes_usage
+ # expect(usage_quota).to be_project
# end
- # @return [Boolean] true if the +plan_minutes_usage+ element is present on the page
- def plan_minutes_usage?
+ # @return [Boolean] true if the +project+ element is present on the page
+ def project?
# This is a stub, used for indexing. The method is dynamically generated.
end
- # @note Defined as +div :purchase_successful_alert+
- # @return [String] The text content or value of +purchase_successful_alert+
- def purchase_successful_alert
+ # @note Defined as +div :storage_type_legend+
+ # @return [String] The text content or value of +storage_type_legend+
+ def storage_type_legend
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota.purchase_successful_alert_element).to exist
+ # expect(usage_quota.storage_type_legend_element).to exist
# end
# @return [Watir::Div] The raw +Div+ element
- def purchase_successful_alert_element
+ def storage_type_legend_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_storage_type_legend
+ # end
+ # @return [Boolean] true if the +storage_type_legend+ element is present on the page
+ def storage_type_legend?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +span :container_registry_size+
+ # @return [String] The text content or value of +container_registry_size+
+ def container_registry_size
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.container_registry_size_element).to exist
+ # end
+ # @return [Watir::Span] The raw +Span+ element
+ def container_registry_size_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_container_registry_size
+ # end
+ # @return [Boolean] true if the +container_registry_size+ element is present on the page
+ def container_registry_size?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :purchased_usage_total_free+
+ # @return [String] The text content or value of +purchased_usage_total_free+
+ def purchased_usage_total_free
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.purchased_usage_total_free_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def purchased_usage_total_free_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_purchased_usage_total_free
+ # end
+ # @return [Boolean] true if the +purchased_usage_total_free+ element is present on the page
+ def purchased_usage_total_free?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +span :purchased_usage_total+
+ # @return [String] The text content or value of +purchased_usage_total+
+ def purchased_usage_total
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.purchased_usage_total_element).to exist
+ # end
+ # @return [Watir::Span] The raw +Span+ element
+ def purchased_usage_total_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_purchased_usage_total
+ # end
+ # @return [Boolean] true if the +purchased_usage_total+ element is present on the page
+ def purchased_usage_total?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +div :storage_purchase_successful_alert+
+ # @return [String] The text content or value of +storage_purchase_successful_alert+
+ def storage_purchase_successful_alert
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.storage_purchase_successful_alert_element).to exist
+ # end
+ # @return [Watir::Div] The raw +Div+ element
+ def storage_purchase_successful_alert_element
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota).to be_storage_purchase_successful_alert
+ # end
+ # @return [Boolean] true if the +storage_purchase_successful_alert+ element is present on the page
+ def storage_purchase_successful_alert?
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @note Defined as +h2 :storage_available_alert+
+ # @return [String] The text content or value of +storage_available_alert+
+ def storage_available_alert
+ # This is a stub, used for indexing. The method is dynamically generated.
+ end
+
+ # @example
+ # Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
+ # expect(usage_quota.storage_available_alert_element).to exist
+ # end
+ # @return [Watir::H2] The raw +H2+ element
+ def storage_available_alert_element
# This is a stub, used for indexing. The method is dynamically generated.
end
# @example
# Gitlab::Page::Group::Settings::UsageQuota.perform do |usage_quota|
- # expect(usage_quota).to be_purchase_successful_alert
+ # expect(usage_quota).to be_storage_available_alert
# end
- # @return [Boolean] true if the +purchase_successful_alert+ element is present on the page
- def purchase_successful_alert?
+ # @return [Boolean] true if the +storage_available_alert+ element is present on the page
+ def storage_available_alert?
# This is a stub, used for indexing. The method is dynamically generated.
end
end
diff --git a/qa/lib/gitlab/page/group/settings/usage_quotas.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.rb
index 2b491188595..a1ab345bf1e 100644
--- a/qa/lib/gitlab/page/group/settings/usage_quotas.rb
+++ b/qa/lib/gitlab/page/group/settings/usage_quotas.rb
@@ -5,16 +5,30 @@ module Gitlab
module Group
module Settings
class UsageQuotas < Chemlab::Page
- # TODO: Supplant with data-qa-selectors
+ # Seats section
+ link :seats_tab
+
+ # Pipelines section
link :pipelines_tab
- link :storage_tab
link :buy_ci_minutes
- link :buy_storage
div :plan_ci_minutes
div :additional_ci_minutes
- span :purchased_usage_total
- div :purchased_usage_total_free, 'data-testid': 'purchased-usage-card' # Different UI for free namespace
div :ci_purchase_successful_alert, text: /You have successfully purchased CI minutes/
+
+ # Storage section
+ link :storage_tab
+ link :purchase_more_storage
+ div :used_storage_message
+ div :group_usage_message
+ div :dependency_proxy_usage
+ span :dependency_proxy_size
+ div :container_registry_usage
+ div :project_storage_used
+ div :project
+ div :storage_type_legend
+ span :container_registry_size
+ div :purchased_usage_total_free # Different UI for free namespace
+ span :purchased_usage_total
div :storage_purchase_successful_alert, text: /You have successfully purchased a storage/
h2 :storage_available_alert, text: /purchased storage is available/
@@ -35,6 +49,15 @@ module Gitlab
false
end
+ # Waits and Checks if storage project data loaded
+ #
+ # @return [Boolean] True if the alert presents, false if not after 5 second wait
+ def project_storage_data_available?
+ storage_type_legend_element.wait_until(timeout: 3, &:present?)
+ rescue Watir::Wait::TimeoutError
+ false
+ end
+
# Returns total purchased storage value once it's ready on page
#
# @return [Float] Total purchased storage value in GiB
diff --git a/qa/qa.rb b/qa/qa.rb
index 99a8a34d6d8..bf6b75a1278 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -30,6 +30,22 @@ module QA
loader.ignore("#{root}/specs/features")
loader.ignore("#{root}/specs/spec_helper.rb")
+ # we need to eager load scenario classes
+ # zeitwerk does not have option to configure what to eager load, so all exceptions have to be defined
+ loader.do_not_eager_load("#{root}/ce")
+ loader.do_not_eager_load("#{root}/ee")
+ loader.do_not_eager_load("#{root}/flow")
+ loader.do_not_eager_load("#{root}/git")
+ loader.do_not_eager_load("#{root}/mobile")
+ loader.do_not_eager_load("#{root}/page")
+ loader.do_not_eager_load("#{root}/resource")
+ loader.do_not_eager_load("#{root}/runtime")
+ loader.do_not_eager_load("#{root}/service")
+ loader.do_not_eager_load("#{root}/specs")
+ loader.do_not_eager_load("#{root}/support")
+ loader.do_not_eager_load("#{root}/tools")
+ loader.do_not_eager_load("#{root}/vendor")
+
loader.inflector.inflect(
"ce" => "CE",
"ee" => "EE",
@@ -74,6 +90,7 @@ module QA
end
loader.setup
+ loader.eager_load
end
# Custom warning processing
diff --git a/qa/qa/fixtures/package_managers/maven/build_install.gradle.erb b/qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb
index 31543d30e88..31543d30e88 100644
--- a/qa/qa/fixtures/package_managers/maven/build_install.gradle.erb
+++ b/qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb
diff --git a/qa/qa/fixtures/package_managers/maven/build_upload.gradle.erb b/qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb
index c14e63e11df..c14e63e11df 100644
--- a/qa/qa/fixtures/package_managers/maven/build_upload.gradle.erb
+++ b/qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb
diff --git a/qa/qa/fixtures/package_managers/maven/gradle_install_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb
index 49873f124cc..49873f124cc 100644
--- a/qa/qa/fixtures/package_managers/maven/gradle_install_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/gradle_upload_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb
index 3f3c7dce03c..3f3c7dce03c 100644
--- a/qa/qa/fixtures/package_managers/maven/gradle_upload_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/maven_install_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/group/consumer/gitlab_ci.yaml.erb
index 78d6255e9a9..78d6255e9a9 100644
--- a/qa/qa/fixtures/package_managers/maven/maven_install_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/maven/group/consumer/gitlab_ci.yaml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/client_pom.xml.erb b/qa/qa/fixtures/package_managers/maven/group/consumer/pom.xml.erb
index 20bb5f3964e..adc8b0294b3 100644
--- a/qa/qa/fixtures/package_managers/maven/client_pom.xml.erb
+++ b/qa/qa/fixtures/package_managers/maven/group/consumer/pom.xml.erb
@@ -5,8 +5,8 @@
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
- <id><%= package_project.name %></id>
- <url><%= gitlab_address_with_port %>/api/v4/groups/<%= package_project.group.id %>/-/packages/maven</url>
+ <id><%= client_project.name %></id>
+ <url><%= gitlab_address_with_port %>/api/v4/groups/<%= client_project.group.id %>/-/packages/maven</url>
</repository>
</repositories>
<dependencies>
diff --git a/qa/qa/fixtures/package_managers/maven/group/consumer/settings.xml.erb b/qa/qa/fixtures/package_managers/maven/group/consumer/settings.xml.erb
new file mode 100644
index 00000000000..fb7e2a4af88
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/group/consumer/settings.xml.erb
@@ -0,0 +1,16 @@
+<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
+<servers>
+ <server>
+ <id><%= client_project.name %></id>
+ <configuration>
+ <httpHeaders>
+ <property>
+ <name><%= maven_header_name %></name>
+ <value><%= token %></value>
+ </property>
+ </httpHeaders>
+ </configuration>
+ </server>
+</servers>
+</settings> \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/maven_upload_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/group/producer/gitlab_ci.yaml.erb
index 64a63bf0bd8..64a63bf0bd8 100644
--- a/qa/qa/fixtures/package_managers/maven/maven_upload_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/maven/group/producer/gitlab_ci.yaml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/package_pom.xml.erb b/qa/qa/fixtures/package_managers/maven/group/producer/pom.xml.erb
index 5159172a170..5159172a170 100644
--- a/qa/qa/fixtures/package_managers/maven/package_pom.xml.erb
+++ b/qa/qa/fixtures/package_managers/maven/group/producer/pom.xml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/settings.xml.erb b/qa/qa/fixtures/package_managers/maven/group/producer/settings.xml.erb
index b670b83cf85..b670b83cf85 100644
--- a/qa/qa/fixtures/package_managers/maven/settings.xml.erb
+++ b/qa/qa/fixtures/package_managers/maven/group/producer/settings.xml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/settings_with_pat.xml.erb b/qa/qa/fixtures/package_managers/maven/group/settings_with_pat.xml.erb
index 611c232819f..611c232819f 100644
--- a/qa/qa/fixtures/package_managers/maven/settings_with_pat.xml.erb
+++ b/qa/qa/fixtures/package_managers/maven/group/settings_with_pat.xml.erb
diff --git a/qa/qa/fixtures/package_managers/maven/project/gitlab_ci.yaml.erb b/qa/qa/fixtures/package_managers/maven/project/gitlab_ci.yaml.erb
new file mode 100644
index 00000000000..44186e92ba7
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/project/gitlab_ci.yaml.erb
@@ -0,0 +1,9 @@
+deploy-and-install:
+ image: maven:3.6-jdk-11
+ script:
+ - 'mvn deploy -s settings.xml'
+ - 'mvn install -s settings.xml'
+ only:
+ - "<%= package_project.default_branch %>"
+ tags:
+ - "runner-for-<%= package_project.name %>" \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/project/pom.xml.erb b/qa/qa/fixtures/package_managers/maven/project/pom.xml.erb
new file mode 100644
index 00000000000..5159172a170
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/project/pom.xml.erb
@@ -0,0 +1,22 @@
+ <project>
+ <groupId><%= group_id %></groupId>
+ <artifactId><%= artifact_id %></artifactId>
+ <version><%= package_version %></version>
+ <modelVersion>4.0.0</modelVersion>
+ <repositories>
+ <repository>
+ <id><%= package_project.name %></id>
+ <url><%= gitlab_address_with_port %>/api/v4/groups/<%= package_project.group.id %>/-/packages/maven</url>
+ </repository>
+ </repositories>
+ <distributionManagement>
+ <repository>
+ <id><%= package_project.name %></id>
+ <url><%= gitlab_address_with_port %>/api/v4/projects/<%= package_project.id %>/packages/maven</url>
+ </repository>
+ <snapshotRepository>
+ <id><%= package_project.name %></id>
+ <url><%= gitlab_address_with_port %>/api/v4/projects/<%= package_project.id %>/packages/maven</url>
+ </snapshotRepository>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb b/qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb
new file mode 100644
index 00000000000..a41bdc4d650
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb
@@ -0,0 +1,8 @@
+install:
+ image: maven:3.6-jdk-11
+ script:
+ - 'mvn install -U -s settings.xml'
+ only:
+ - "<%= imported_project.default_branch %>"
+ tags:
+ - "runner-for-<%= imported_project.name %>" \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb b/qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb
new file mode 100644
index 00000000000..caf1fc9b761
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb
@@ -0,0 +1,23 @@
+<settings>
+ <servers>
+ <server>
+ <id>central-proxy</id>
+ <configuration>
+ <httpHeaders>
+ <property>
+ <name>Private-Token</name>
+ <value><%= personal_access_token %></value>
+ </property>
+ </httpHeaders>
+ </configuration>
+ </server>
+ </servers>
+ <mirrors>
+ <mirror>
+ <id>central-proxy</id>
+ <name>GitLab proxy of central repo</name>
+ <url><%= gitlab_address_with_port %>/api/v4/projects/<%= imported_project.id %>/packages/maven</url>
+ <mirrorOf>central</mirrorOf>
+ </mirror>
+ </mirrors>
+</settings>
diff --git a/qa/qa/fixtures/package_managers/maven/project/settings.xml.erb b/qa/qa/fixtures/package_managers/maven/project/settings.xml.erb
new file mode 100644
index 00000000000..b670b83cf85
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/project/settings.xml.erb
@@ -0,0 +1,16 @@
+<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
+<servers>
+ <server>
+ <id><%= package_project.name %></id>
+ <configuration>
+ <httpHeaders>
+ <property>
+ <name><%= maven_header_name %></name>
+ <value><%= token %></value>
+ </property>
+ </httpHeaders>
+ </configuration>
+ </server>
+</servers>
+</settings> \ No newline at end of file
diff --git a/qa/qa/fixtures/software_licenses/other b/qa/qa/fixtures/software_licenses/other
new file mode 100644
index 00000000000..b6652f05dab
--- /dev/null
+++ b/qa/qa/fixtures/software_licenses/other
@@ -0,0 +1,7 @@
+This software is licensed under the Other license
+=======
+
+This Other license isn't a real license and won't be used by any real project.
+This license does not come with any guarantees. The author cannot be hold liable
+in any way, and users are permitted to do anything they want with the provided
+code. \ No newline at end of file
diff --git a/qa/qa/flow/purchase.rb b/qa/qa/flow/purchase.rb
index c07e03c104d..32c4f469207 100644
--- a/qa/qa/flow/purchase.rb
+++ b/qa/qa/flow/purchase.rb
@@ -45,11 +45,12 @@ module QA
Page::Group::Menu.perform(&:go_to_usage_quotas)
Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quota|
usage_quota.storage_tab
- usage_quota.buy_storage
+ usage_quota.purchase_more_storage
end
- # Purchase checkout opens a new tab
- Chemlab.configuration.browser.session.engine.switch_window
+ # Purchase checkout opens a new tab but buying additional storage does not
+ session = Chemlab.configuration.browser.session.engine
+ session.switch_window if session.windows.size == 2
Gitlab::Page::Subscriptions::New.perform do |storage|
storage.quantity = quantity
diff --git a/qa/qa/mobile/page/main/menu.rb b/qa/qa/mobile/page/main/menu.rb
index 40bb421b383..73d3b9f7982 100644
--- a/qa/qa/mobile/page/main/menu.rb
+++ b/qa/qa/mobile/page/main/menu.rb
@@ -22,10 +22,10 @@ module QA
end
def open_mobile_menu
- if has_no_element?(:user_avatar)
+ if has_no_element?(:user_avatar_content)
Support::Retrier.retry_until do
click_element(:mobile_navbar_button)
- has_element?(:user_avatar)
+ has_element?(:user_avatar_content)
end
end
end
diff --git a/qa/qa/page/admin/menu.rb b/qa/qa/page/admin/menu.rb
index e55e156fb8a..3164676f8e4 100644
--- a/qa/qa/page/admin/menu.rb
+++ b/qa/qa/page/admin/menu.rb
@@ -5,78 +5,79 @@ module QA
module Admin
class Menu < Page::Base
view 'app/views/layouts/nav/sidebar/_admin.html.haml' do
- element :admin_sidebar
- element :admin_sidebar_settings_submenu_content
- element :admin_settings_item
- element :admin_settings_repository_item
- element :admin_settings_general_item
- element :admin_settings_metrics_and_profiling_item
+ element :admin_sidebar_content
+ element :admin_monitoring_menu_link
+ element :admin_monitoring_submenu_content
+ element :admin_overview_submenu_content
+ element :admin_overview_users_link
+ element :admin_overview_groups_link
+ element :admin_settings_menu_link
+ element :admin_settings_submenu_content
+ element :admin_settings_general_link
+ element :admin_settings_integrations_link
+ element :admin_settings_metrics_and_profiling_link
+ element :admin_settings_network_link
element :admin_settings_preferences_link
- element :admin_monitoring_link
- element :admin_sidebar_monitoring_submenu_content
- element :admin_sidebar_overview_submenu_content
- element :users_overview_link
- element :groups_overview_link
- element :integration_settings_link
+ element :admin_settings_repository_link
end
def go_to_preferences_settings
- hover_element(:admin_settings_item) do
- within_submenu(:admin_sidebar_settings_submenu_content) do
+ hover_element(:admin_settings_menu_link) do
+ within_submenu(:admin_settings_submenu_content) do
click_element :admin_settings_preferences_link
end
end
end
def go_to_repository_settings
- hover_element(:admin_settings_item) do
- within_submenu(:admin_sidebar_settings_submenu_content) do
- click_element :admin_settings_repository_item
+ hover_element(:admin_settings_menu_link) do
+ within_submenu(:admin_settings_submenu_content) do
+ click_element :admin_settings_repository_link
end
end
end
def go_to_integration_settings
- hover_element(:admin_settings_item) do
- within_submenu(:admin_sidebar_settings_submenu_content) do
- click_element :integration_settings_link
+ hover_element(:admin_settings_menu_link) do
+ within_submenu(:admin_settings_submenu_content) do
+ click_element :admin_settings_integrations_link
end
end
end
def go_to_general_settings
- hover_element(:admin_settings_item) do
- within_submenu(:admin_sidebar_settings_submenu_content) do
- click_element :admin_settings_general_item
+ hover_element(:admin_settings_menu_link) do
+ within_submenu(:admin_settings_submenu_content) do
+ click_element :admin_settings_general_link
end
end
end
def go_to_metrics_and_profiling_settings
- hover_element(:admin_settings_item) do
- within_submenu(:admin_sidebar_settings_submenu_content) do
- click_element :admin_settings_metrics_and_profiling_item
+ hover_element(:admin_settings_menu_link) do
+ within_submenu(:admin_settings_submenu_content) do
+ click_element :admin_settings_metrics_and_profiling_link
end
end
end
def go_to_network_settings
- hover_element(:admin_settings_item) do
- within_submenu(:admin_sidebar_settings_submenu_content) do
- click_element :admin_settings_network_item
+ hover_element(:admin_settings_menu_link) do
+ within_submenu(:admin_settings_submenu_content) do
+ click_element :admin_settings_network_link
end
end
end
def go_to_users_overview
- within_submenu(:admin_sidebar_overview_submenu_content) do
- click_element :users_overview_link
+ within_submenu(:admin_overview_submenu_content) do
+ click_element :admin_overview_users_link
end
end
def go_to_groups_overview
- within_submenu(:admin_sidebar_overview_submenu_content) do
- click_element :groups_overview_link
+ within_submenu(:admin_overview_submenu_content) do
+ click_element :admin_overview_groups_link
end
end
@@ -92,7 +93,7 @@ module QA
end
def within_sidebar
- within_element(:admin_sidebar) do
+ within_element(:admin_sidebar_content) do
yield
end
end
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 03f753b1d61..81c518bb4c6 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -242,6 +242,11 @@ module QA
end
def fill_element(name, content)
+ # `click_element_coordinates` is used to ensure the element is focused.
+ # Without it, flakiness can occur on pages with GitLab keyboard shortcuts enabled,
+ # where certain keys trigger actions when typed elsewhere on the page.
+ click_element_coordinates(name)
+
find_element(name).set(content)
end
diff --git a/qa/qa/page/component/clone_panel.rb b/qa/qa/page/component/clone_panel.rb
index a0aea6fe44d..3ea29ff63da 100644
--- a/qa/qa/page/component/clone_panel.rb
+++ b/qa/qa/page/component/clone_panel.rb
@@ -11,18 +11,18 @@ module QA
base.view 'app/views/projects/buttons/_clone.html.haml' do
element :clone_dropdown
- element :clone_options
- element :ssh_clone_url
- element :http_clone_url
+ element :clone_dropdown_content
+ element :ssh_clone_url_content
+ element :http_clone_url_content
end
end
def repository_clone_http_location
- repository_clone_location(:http_clone_url)
+ repository_clone_location(:http_clone_url_content)
end
def repository_clone_ssh_location
- repository_clone_location(:ssh_clone_url)
+ repository_clone_location(:ssh_clone_url_content)
end
private
@@ -31,7 +31,7 @@ module QA
wait_until(reload: false) do
click_element :clone_dropdown
- within_element :clone_options do
+ within_element :clone_dropdown_content do
Git::Location.new(find_element(kind).value)
end
end
diff --git a/qa/qa/page/component/content_editor.rb b/qa/qa/page/component/content_editor.rb
index f7b055b6052..e9fc575ae39 100644
--- a/qa/qa/page/component/content_editor.rb
+++ b/qa/qa/page/component/content_editor.rb
@@ -22,8 +22,8 @@ module QA
element :file_upload_field
end
- base.view 'app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue' do
- element :wiki_hidden_content
+ base.view 'app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue' do
+ element :markdown_editor_form_field
end
end
@@ -47,7 +47,7 @@ module QA
end
QA::Support::Retrier.retry_on_exception do
- source = find_element(:wiki_hidden_content, visible: false)
+ source = find_element(:markdown_editor_form_field, visible: false)
source.value =~ %r{uploads/.*#{::File.basename(image_path)}}
end
end
diff --git a/qa/qa/page/component/groups_filter.rb b/qa/qa/page/component/groups_filter.rb
index ff61c91f0f6..28b8ece918d 100644
--- a/qa/qa/page/component/groups_filter.rb
+++ b/qa/qa/page/component/groups_filter.rb
@@ -9,7 +9,7 @@ module QA
def self.included(base)
super
- base.view 'app/views/shared/groups/_search_form.html.haml' do
+ base.view 'app/assets/javascripts/groups/components/overview_tabs.vue' do
element :groups_filter_field
end
diff --git a/qa/qa/page/component/invite_members_modal.rb b/qa/qa/page/component/invite_members_modal.rb
index 5c39cfd3695..27dce152367 100644
--- a/qa/qa/page/component/invite_members_modal.rb
+++ b/qa/qa/page/component/invite_members_modal.rb
@@ -62,13 +62,9 @@ module QA
Support::Waiter.wait_until { has_element?(:group_select_dropdown_item) }
- # Workaround for race condition with concurrent group API calls while searching
- # Remove Retrier after https://gitlab.com/gitlab-org/gitlab/-/issues/349379 is resolved
- Support::Retrier.retry_on_exception do
- fill_element :group_select_dropdown_search_field, group_name
- Support::WaitForRequests.wait_for_requests
- click_button group_name
- end
+ fill_element :group_select_dropdown_search_field, group_name
+ Support::WaitForRequests.wait_for_requests
+ click_button group_name
set_access_level(access_level)
end
diff --git a/qa/qa/page/component/issuable/sidebar.rb b/qa/qa/page/component/issuable/sidebar.rb
index 68da89dc81d..71a69576c06 100644
--- a/qa/qa/page/component/issuable/sidebar.rb
+++ b/qa/qa/page/component/issuable/sidebar.rb
@@ -18,6 +18,10 @@ module QA
element :more_assignees_link
end
+ base.view 'app/assets/javascripts/sidebar/components/reviewers/reviewer_title.vue' do
+ element :reviewers_edit_button
+ end
+
base.view 'app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue' do
element :labels_block
end
@@ -37,6 +41,7 @@ module QA
base.view 'app/views/shared/issuable/_sidebar.html.haml' do
element :assignee_block_container
element :milestone_block
+ element :reviewers_block_container
end
base.view 'app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue' do
@@ -46,6 +51,10 @@ module QA
base.view 'app/assets/javascripts/sidebar/components/sidebar_editable_item.vue' do
element :edit_link
end
+
+ base.view 'app/helpers/dropdowns_helper.rb' do
+ element :dropdown_list_content
+ end
end
def assign_milestone(milestone)
diff --git a/qa/qa/page/component/legacy_clone_panel.rb b/qa/qa/page/component/legacy_clone_panel.rb
index f15d159a712..ee372a3f9aa 100644
--- a/qa/qa/page/component/legacy_clone_panel.rb
+++ b/qa/qa/page/component/legacy_clone_panel.rb
@@ -11,8 +11,8 @@ module QA
base.view 'app/views/shared/_clone_panel.html.haml' do
element :clone_dropdown
- element :clone_options_dropdown, '.clone-options-dropdown' # rubocop:disable QA/ElementWithPattern
- element :clone_url, 'text_field_tag :clone_url' # rubocop:disable QA/ElementWithPattern
+ element :clone_dropdown_content
+ element :clone_url_content
end
end
@@ -28,7 +28,7 @@ module QA
end
def repository_location
- Git::Location.new(find('#clone_url').value)
+ Git::Location.new(find_element(:clone_url_content).text)
end
private
@@ -37,7 +37,7 @@ module QA
wait_until(reload: false) do
click_element :clone_dropdown
- page.within('.clone-options-dropdown') do
+ within_element(:clone_dropdown_content) do
click_link(kind)
end
diff --git a/qa/qa/page/component/namespace_select.rb b/qa/qa/page/component/namespace_select.rb
index 4dbcb39ced6..9b483162f1b 100644
--- a/qa/qa/page/component/namespace_select.rb
+++ b/qa/qa/page/component/namespace_select.rb
@@ -9,7 +9,7 @@ module QA
def self.included(base)
super
- base.view "app/assets/javascripts/vue_shared/components/namespace_select/namespace_select.vue" do
+ base.view "app/assets/javascripts/vue_shared/components/namespace_select/namespace_select_deprecated.vue" do
element :namespaces_list
element :namespaces_list_groups
element :namespaces_list_item
@@ -20,8 +20,10 @@ module QA
def select_namespace(item)
click_element :namespaces_list
+ wait_for_requests
+
within_element(:namespaces_list) do
- find_element(:namespaces_list_search).fill_in(with: item)
+ fill_element(:namespaces_list_search, item)
wait_for_requests
diff --git a/qa/qa/page/component/wiki_page_form.rb b/qa/qa/page/component/wiki_page_form.rb
index 9e558844469..7a7329e6110 100644
--- a/qa/qa/page/component/wiki_page_form.rb
+++ b/qa/qa/page/component/wiki_page_form.rb
@@ -11,9 +11,12 @@ module QA
base.view 'app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue' do
element :wiki_title_textbox
- element :wiki_content_textarea
element :wiki_message_textbox
element :wiki_submit_button
+ end
+
+ base.view 'app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue' do
+ element :markdown_editor_form_field
element :editing_mode_button
end
@@ -27,7 +30,7 @@ module QA
end
def set_content(content)
- fill_element(:wiki_content_textarea, content)
+ fill_element(:markdown_editor_form_field, content)
end
def set_message(message)
diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb
index b057a27fa3e..a30d489e6ff 100644
--- a/qa/qa/page/group/show.rb
+++ b/qa/qa/page/group/show.rb
@@ -13,10 +13,6 @@ module QA
element :group_id_content
end
- view 'app/assets/javascripts/groups/constants.js' do
- element :no_result_text, 'No groups or projects matched your search' # rubocop:disable QA/ElementWithPattern
- end
-
view 'app/views/shared/members/_access_request_links.html.haml' do
element :leave_group_link
end
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index aaf10e12e82..2f618224a73 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -14,7 +14,7 @@ module QA
view 'app/views/layouts/header/_default.html.haml' do
element :navbar, required: true
element :canary_badge_link
- element :user_avatar, required: !QA::Runtime::Env.mobile_layout?
+ element :user_avatar_content, required: !QA::Runtime::Env.mobile_layout?
element :user_menu, required: !QA::Runtime::Env.mobile_layout?
element :stop_impersonation_link
element :issues_shortcut_button, required: !QA::Runtime::Env.mobile_layout?
@@ -184,11 +184,11 @@ module QA
end
def has_personal_area?(wait: Capybara.default_max_wait_time)
- has_element?(:user_avatar, wait: wait)
+ has_element?(:user_avatar_content, wait: wait)
end
def has_no_personal_area?(wait: Capybara.default_max_wait_time)
- has_no_element?(:user_avatar, wait: wait)
+ has_no_element?(:user_avatar_content, wait: wait)
end
def has_admin_area_link?(wait: Capybara.default_max_wait_time)
@@ -227,7 +227,7 @@ module QA
def within_user_menu(&block)
within_top_menu do
- click_element :user_avatar unless has_element?(:user_profile_link, wait: 1)
+ click_element :user_avatar_content unless has_element?(:user_profile_link, wait: 1)
within_element(:user_menu, &block)
end
diff --git a/qa/qa/page/main/terms.rb b/qa/qa/page/main/terms.rb
index 024510c33cf..24f6b03549b 100644
--- a/qa/qa/page/main/terms.rb
+++ b/qa/qa/page/main/terms.rb
@@ -5,7 +5,7 @@ module QA
module Main
class Terms < Page::Base
view 'app/views/layouts/terms.html.haml' do
- element :user_avatar, required: true
+ element :user_avatar_content, required: true
end
view 'app/assets/javascripts/terms/components/app.vue' do
diff --git a/qa/qa/page/merge_request/new.rb b/qa/qa/page/merge_request/new.rb
index 79eb4f2d51b..909b37943ff 100644
--- a/qa/qa/page/merge_request/new.rb
+++ b/qa/qa/page/merge_request/new.rb
@@ -38,7 +38,6 @@ module QA
def click_diffs_tab
click_element(:diffs_tab)
- click_element(:dismiss_popover_button) if has_element?(:dismiss_popover_button, wait: 1)
end
def has_file?(file_name)
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 2587241ed18..e1add9ad434 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -108,6 +108,7 @@ module QA
view 'app/assets/javascripts/vue_shared/components/markdown/header.vue' do
element :suggestion_button
+ element :dismiss_suggestion_popover_button
end
view 'app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue' do
@@ -191,8 +192,11 @@ module QA
wait_until(sleep_interval: 5) do
has_css?('a[data-linenumber="1"]')
end
+
all_elements(:new_diff_line_link, minimum: 1).first.hover
click_element(:diff_comment_button)
+ click_element(:dismiss_suggestion_popover_button) if has_element?(:dismiss_suggestion_popover_button, wait: 1)
+
fill_element(:reply_field, text)
end
@@ -208,7 +212,6 @@ module QA
def click_diffs_tab
click_element(:diffs_tab)
- click_element(:dismiss_popover_button) if has_element?(:dismiss_popover_button, wait: 1)
end
def click_pipeline_link
diff --git a/qa/qa/page/project/secure/configuration_form.rb b/qa/qa/page/project/secure/configuration_form.rb
index fa1fad44273..20999f7c92a 100644
--- a/qa/qa/page/project/secure/configuration_form.rb
+++ b/qa/qa/page/project/secure/configuration_form.rb
@@ -9,6 +9,7 @@ module QA
include QA::Page::Settings::Common
view 'app/assets/javascripts/security_configuration/components/app.vue' do
+ element :security_configuration_container
element :security_configuration_history_link
end
@@ -17,6 +18,7 @@ module QA
element :sast_status, "`${feature.type}_status`" # rubocop:disable QA/ElementWithPattern
element :sast_enable_button, "`${feature.type}_enable_button`" # rubocop:disable QA/ElementWithPattern
element :dependency_scanning_mr_button, "`${feature.type}_mr_button`" # rubocop:disable QA/ElementWithPattern
+ element :license_scanning_status, "`${feature.type}_status`" # rubocop:disable QA/ElementWithPattern
end
view 'app/assets/javascripts/security_configuration/components/auto_dev_ops_alert.vue' do
@@ -67,6 +69,18 @@ module QA
end
end
+ def has_license_compliance_status?(status_text)
+ within_element(:license_scanning_status) do
+ has_text?(status_text)
+ end
+ end
+
+ def has_no_license_compliance_status?(status_text)
+ within_element(:license_scanning_status) do
+ has_no_text?(status_text)
+ end
+ end
+
def has_auto_devops_container?
has_element?(:autodevops_container)
end
@@ -80,6 +94,18 @@ module QA
has_text?('Quickly enable all continuous testing and compliance tools by enabling Auto DevOps')
end
end
+
+ def go_to_compliance_tab
+ go_to_tab('Compliance')
+ end
+
+ private
+
+ def go_to_tab(name)
+ within_element(:security_configuration_container) do
+ find('.nav-item', text: name).click
+ end
+ end
end
end
end
diff --git a/qa/qa/page/project/settings/default_branch.rb b/qa/qa/page/project/settings/default_branch.rb
index cc28b37b88f..575f9006c84 100644
--- a/qa/qa/page/project/settings/default_branch.rb
+++ b/qa/qa/page/project/settings/default_branch.rb
@@ -5,16 +5,22 @@ module QA
module Project
module Settings
class DefaultBranch < Page::Base
- include Page::Component::Select2
-
view 'app/views/projects/default_branch/_show.html.haml' do
element :save_changes_button
+ end
+
+ view 'app/assets/javascripts/projects/settings/components/default_branch_selector.vue' do
element :default_branch_dropdown
end
+ view 'app/assets/javascripts/ref/components/ref_selector.vue' do
+ element :ref_selector_searchbox
+ end
+
def set_default_branch(branch)
- find('.select2-chosen').click
- search_and_select(branch)
+ click_button :default_branch_dropdown
+ fill_in :ref_selector_searchbox, with: branch
+ click_button branch
end
def click_save_changes_button
diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb
index 7eeeeefdae6..f55faff19e7 100644
--- a/qa/qa/page/project/settings/mirroring_repositories.rb
+++ b/qa/qa/page/project/settings/mirroring_repositories.rb
@@ -62,7 +62,7 @@ module QA
end
def authentication_method=(value)
- unless %w[Password None SSH\ public\ key].include?(value)
+ unless ['Password', 'None', 'SSH public key'].include?(value)
raise ArgumentError, "Authentication method must be 'SSH public key', 'Password', or 'None'"
end
diff --git a/qa/qa/page/project/settings/services/jira.rb b/qa/qa/page/project/settings/services/jira.rb
index 827508e488c..41034bbd897 100644
--- a/qa/qa/page/project/settings/services/jira.rb
+++ b/qa/qa/page/project/settings/services/jira.rb
@@ -41,10 +41,7 @@ module QA
yield self if block_given?
- click_save_changes_button
- wait_until(reload: false) do
- has_element?(:save_changes_button, wait: 1) ? !find_element(:save_changes_button).disabled? : true
- end
+ click_save_changes_and_wait
end
def enable_jira_issues
@@ -55,6 +52,13 @@ module QA
fill_element(:service_jira_project_key_field, key)
end
+ def click_save_changes_and_wait
+ click_save_changes_button
+ wait_until(reload: false) do
+ has_element?(:save_changes_button, wait: 1) ? !find_element(:save_changes_button).disabled? : true
+ end
+ end
+
private
def set_jira_server_url(url)
@@ -94,3 +98,5 @@ module QA
end
end
end
+
+QA::Page::Project::Settings::Services::Jira.prepend_mod_with('Page::Project::Settings::Services::Jira', namespace: QA)
diff --git a/qa/qa/page/project/tag/new.rb b/qa/qa/page/project/tag/new.rb
index dc59c07ec98..50e11acd94a 100644
--- a/qa/qa/page/project/tag/new.rb
+++ b/qa/qa/page/project/tag/new.rb
@@ -8,17 +8,9 @@ module QA
view 'app/views/projects/tags/new.html.haml' do
element :tag_name_field
element :tag_message_field
- element :release_notes_field
element :create_tag_button
end
- view 'app/views/shared/_zen.html.haml' do
- # This partial adds the `release_notes_field` selector passed from 'app/views/projects/tags/new.html.haml'
- # The checks below ensure that required lines are not removed without updating this page object
- element :_, "qa_selector = local_assigns.fetch(:qa_selector, '')" # rubocop:disable QA/ElementWithPattern
- element :_, "text_area_tag attr, current_text, data: { qa_selector: qa_selector }" # rubocop:disable QA/ElementWithPattern
- end
-
def fill_tag_name(text)
fill_element(:tag_name_field, text)
end
@@ -27,10 +19,6 @@ module QA
fill_element(:tag_message_field, text)
end
- def fill_release_notes(text)
- fill_element(:release_notes_field, text)
- end
-
def click_create_tag_button
click_element :create_tag_button
end
diff --git a/qa/qa/resource/issuable.rb b/qa/qa/resource/issuable.rb
new file mode 100644
index 00000000000..6ebdaac8298
--- /dev/null
+++ b/qa/qa/resource/issuable.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class Issuable < Base
+ # Commentes (notes) path
+ #
+ # @return [String]
+ def api_comments_path
+ "#{api_get_path}/notes"
+ end
+
+ # Get issue comments
+ #
+ # @return [Array]
+ def comments(auto_paginate: false, attempts: 0)
+ return parse_body(api_get_from(api_comments_path)) unless auto_paginate
+
+ auto_paginated_response(
+ Runtime::API::Request.new(api_client, api_comments_path, per_page: '100').url,
+ attempts: attempts
+ )
+ end
+
+ # Create a new comment
+ #
+ # @param [String] body
+ # @param [Boolean] confidential
+ # @return [Hash]
+ def add_comment(body:, confidential: false)
+ api_post_to(api_comments_path, body: body, confidential: confidential)
+ end
+
+ # Issue label events
+ #
+ # @param [Boolean] auto_paginate
+ # @param [Integer] attempts
+ # @return [Array<Hash>]
+ def label_events(auto_paginate: false, attempts: 0)
+ events("label", auto_paginate: auto_paginate, attempts: attempts)
+ end
+
+ # Issue state events
+ #
+ # @param [Boolean] auto_paginate
+ # @param [Integer] attempts
+ # @return [Array<Hash>]
+ def state_events(auto_paginate: false, attempts: 0)
+ events("state", auto_paginate: auto_paginate, attempts: attempts)
+ end
+
+ # Issue milestone events
+ #
+ # @param [Boolean] auto_paginate
+ # @param [Integer] attempts
+ # @return [Array<Hash>]
+ def milestone_events(auto_paginate: false, attempts: 0)
+ events("milestone", auto_paginate: auto_paginate, attempts: attempts)
+ end
+
+ private
+
+ # Issue events
+ #
+ # @param [String] name event name
+ # @param [Boolean] auto_paginate
+ # @param [Integer] attempts
+ # @return [Array<Hash>]
+ def events(name, auto_paginate:, attempts:)
+ return parse_body(api_get_from("#{api_get_path}/resource_#{name}_events")) unless auto_paginate
+
+ auto_paginated_response(
+ Runtime::API::Request.new(api_client, "#{api_get_path}/resource_#{name}_events", per_page: '100').url,
+ attempts: attempts
+ )
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index 1e38de97c1e..2e18e1d0323 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -2,7 +2,7 @@
module QA
module Resource
- class Issue < Base
+ class Issue < Issuable
attr_writer :milestone, :template, :weight
attribute :project do
@@ -53,10 +53,6 @@ module QA
"/projects/#{project.id}/issues/#{iid}"
end
- def api_comments_path
- "#{api_get_path}/notes"
- end
-
def api_post_body
{
assignee_ids: assignee_ids,
@@ -83,27 +79,6 @@ module QA
QA::Runtime::Logger.debug("Successfully updated issue assignees to #{assignee_ids}")
end
- # Get issue comments
- #
- # @return [Array]
- def comments(auto_paginate: false, attempts: 0)
- return parse_body(api_get_from(api_comments_path)) unless auto_paginate
-
- auto_paginated_response(
- Runtime::API::Request.new(api_client, api_comments_path, per_page: '100').url,
- attempts: attempts
- )
- end
-
- # Create a new comment
- #
- # @param [String] body
- # @param [Boolean] confidential
- # @return [Hash]
- def add_comment(body:, confidential: false)
- api_post_to(api_comments_path, body: body, confidential: confidential)
- end
-
protected
# Return subset of fields for comparing issues
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index 0a92553690f..5d6dc12ac9c 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -2,7 +2,7 @@
module QA
module Resource
- class MergeRequest < Base
+ class MergeRequest < Issuable
attr_accessor :approval_rules,
:source_branch,
:target_new_branch,
@@ -130,10 +130,6 @@ module QA
}
end
- def api_comments_path
- "#{api_get_path}/notes"
- end
-
def merge_via_api!
Support::Waiter.wait_until(sleep_interval: 1) do
QA::Runtime::Logger.debug("Waiting until merge request with id '#{iid}' can be merged")
@@ -166,26 +162,6 @@ module QA
current_url
end
- # Get MR comments
- #
- # @return [Array]
- def comments(auto_paginate: false, attempts: 0)
- return parse_body(api_get_from(api_comments_path)) unless auto_paginate
-
- auto_paginated_response(
- Runtime::API::Request.new(api_client, api_comments_path, per_page: '100').url,
- attempts: attempts
- )
- end
-
- # Add mr comment
- #
- # @param [String] body
- # @return [Hash]
- def add_comment(body)
- api_post_to(api_comments_path, body: body)
- end
-
# Return subset of fields for comparing merge requests
#
# @return [Hash]
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index 13c6f285259..e5df95f1fa5 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -226,7 +226,11 @@ module QA
end
def api_housekeeping_path
- "/projects/#{id}/housekeeping"
+ "#{api_get_path}/housekeeping"
+ end
+
+ def api_protected_branches_path
+ "#{api_get_path}/protected_branches"
end
def api_post_body
@@ -324,8 +328,11 @@ module QA
result = parse_body(response)
if result[:import_status] == "failed"
- Runtime::Logger.error("Import failed: #{result[:import_error]}")
- Runtime::Logger.error("Failed relations: #{result[:failed_relations]}")
+ Runtime::Logger.error(<<~ERR)
+ Import of project '#{full_path}' failed!
+ error: '#{result[:import_error]}'
+ failed relations: '#{result[:failed_relations]}'
+ ERR
end
result
@@ -420,7 +427,7 @@ module QA
end
def wikis
- response = get(request_url(api_wikis_path))
+ response = api_get_from(api_wikis_path)
parse_body(response)
end
@@ -437,6 +444,11 @@ module QA
api_post_to(api_releases_path, tag_name: tag, ref: ref, **params)
end
+ def protected_branches
+ response = api_get_from(api_protected_branches_path)
+ parse_body(response)
+ end
+
# Uses the API to wait until a pull mirroring update is successful (pull mirroring is treated as an import)
def wait_for_pull_mirroring
mirror_succeeded = Support::Retrier.retry_until(
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index b9dbd2a6131..9ba9723f0cc 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -3,6 +3,8 @@
module QA
module Resource
class ProjectImportedFromGithub < Resource::Project
+ attr_accessor :issue_events_import, :full_notes_import, :attachments_import
+
attribute :github_repo_id do
github_client.repository(github_repository_path).id
end
@@ -51,7 +53,12 @@ module QA
new_name: name,
target_namespace: @personal_namespace || group.full_path,
personal_access_token: github_personal_access_token,
- ci_cd_only: false
+ ci_cd_only: false,
+ optional_stages: {
+ single_endpoint_issue_events_import: issue_events_import,
+ single_endpoint_notes_import: full_notes_import,
+ attachments_import: attachments_import
+ }
}
end
diff --git a/qa/qa/resource/protected_branch.rb b/qa/qa/resource/protected_branch.rb
index 55ad6edb3c1..7b6a3d296c4 100644
--- a/qa/qa/resource/protected_branch.rb
+++ b/qa/qa/resource/protected_branch.rb
@@ -22,9 +22,7 @@ module QA
commit.branch = branch_name
commit.start_branch = project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: "new_file-#{SecureRandom.hex(8)}.md", content: 'new file' }
- ])
+ commit.add_files([{ file_path: "new_file-#{SecureRandom.hex(8)}.md", content: 'new file' }])
end
end
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index a974446b3cb..71a5e1c8930 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -44,7 +44,7 @@ module QA
alias_method :ldap_username, :username
def password
- @password ||= SecureRandom.hex(8)
+ @password ||= "Pa$$w0rd"
end
alias_method :ldap_password, :password
diff --git a/qa/qa/resource/wiki/group_page.rb b/qa/qa/resource/wiki/group_page.rb
index 1e40426a389..69ad83ea10a 100644
--- a/qa/qa/resource/wiki/group_page.rb
+++ b/qa/qa/resource/wiki/group_page.rb
@@ -23,6 +23,7 @@ module QA
end
def initialize
+ # Note: A Group Wiki Home page requires title = 'Home', otherwise when going /-/wikis, Rails will render a new page creation form.
@title = 'Home'
@content = 'This wiki page is created via API'
end
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index b1a912ac43e..782ba1cf2fa 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -29,6 +29,15 @@ module QA
@gitlab_url ||= ENV["QA_GITLAB_URL"] || "http://127.0.0.1:3000" # default to GDK
end
+ # Retrieves the value of the gitlab_canary cookie if set or returns an empty hash.
+ #
+ # @return [Hash]
+ def canary_cookie
+ canary = ENV['QA_COOKIES']&.scan(/gitlab_canary=(true|false)/)&.dig(0, 0)
+
+ canary ? { gitlab_canary: canary } : {}
+ end
+
def additional_repository_storage
ENV['QA_ADDITIONAL_REPOSITORY_STORAGE']
end
diff --git a/qa/qa/scenario/test/instance.rb b/qa/qa/scenario/test/instance.rb
deleted file mode 100644
index b4098619e4e..00000000000
--- a/qa/qa/scenario/test/instance.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Scenario
- module Test
- # This class exists for back-compatibility so that gitlab-qa can continue
- # to call Test::Instance instead of Test::Instance::All until at least
- # the current latest GitLab version has the Test::Instance::All class.
- # As of Aug, 22nd 2018. Only GitLab >= 11.3 has this class.
- module Instance
- include Bootable
-
- def self.perform(*args)
- self.tap do |scenario|
- yield scenario if block_given?
- break scenario.do_perform(*args)
- end
- end
-
- def self.do_perform(address, *rspec_options)
- Runtime::Scenario.define(:gitlab_address, address)
-
- ##
- # Perform before hooks, which are different for CE and EE
- #
- Runtime::Release.perform_before_hooks
-
- Specs::Runner.perform do |specs|
- specs.tty = true
- specs.options = rspec_options if rspec_options.any?
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/scenario/test/integration/github.rb b/qa/qa/scenario/test/integration/github.rb
deleted file mode 100644
index 857a1f00bd5..00000000000
--- a/qa/qa/scenario/test/integration/github.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Scenario
- module Test
- module Integration
- class Github < Test::Instance::All
- tags :github
-
- def perform(address, *rspec_options)
- # This test suite requires a GitHub personal access token
- Runtime::Env.require_github_access_token!
-
- super
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb b/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb
index 7d3916641aa..bf95a215c8e 100644
--- a/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/group_access_token_spec.rb
@@ -40,9 +40,7 @@ module QA
commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }
- ])
+ commit.add_files([{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }])
end
end.not_to raise_error
end
diff --git a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
index df34bf32421..c3e41e9298b 100644
--- a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
@@ -3,7 +3,7 @@
module QA
# Spec uses real github.com, which means outage of github.com can actually block deployment
# Keep spec in reliable bucket but don't run in blocking pipelines
- RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin do
+ RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do
describe 'Project import', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353583' do
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
@@ -20,7 +20,9 @@ module QA
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = 'gitlab-qa-github/import-test'
- project.api_client = api_client
+ project.api_client = Runtime::API::Client.new(user: user)
+ project.issue_events_import = true
+ project.full_notes_import = true
end
end
@@ -41,6 +43,7 @@ module QA
aggregate_failures do
verify_status_data
verify_repository_import
+ verify_protected_branches_import
verify_commits_import
verify_labels_import
verify_issues_import
@@ -53,7 +56,7 @@ module QA
def verify_status_data
stats = imported_project.project_import_status.dig(:stats, :imported)
expect(stats).to include(
- # issue: 2,
+ issue: 1,
label: 9,
milestone: 1,
note: 3,
@@ -69,6 +72,21 @@ module QA
expect(imported_project.api_response[:import_error]).to be_nil
end
+ def verify_protected_branches_import
+ branches = imported_project.protected_branches.map do |branch|
+ branch.slice(:name, :allow_force_push, :code_owner_approval_required)
+ end
+ expect(branches.first).to include(
+ {
+ name: 'main'
+ # TODO: Add validation once https://gitlab.com/groups/gitlab-org/-/epics/8585 is closed
+ # At the moment both options are always set to false regardless of state in github
+ # allow_force_push: true,
+ # code_owner_approval_required: true
+ }
+ )
+ end
+
def verify_commits_import
expect(imported_project.commits.length).to eq(2)
end
@@ -122,7 +140,7 @@ module QA
mr.iid = merge_requests.first[:iid]
mr.api_client = api_client
end.reload!
- mr_comments = merge_request.comments.map { |comment| comment[:body] } # rubocop:disable Rails/Pluck
+ mr_comments = merge_request.comments.map { |comment| comment[:body] }
expect(merge_requests.length).to eq(1)
expect(merge_request.api_resource).to include(
diff --git a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb
index e6b60a5b090..5acf15dd2b4 100644
--- a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb
@@ -1,21 +1,82 @@
# frozen_string_literal: true
+require "etc"
+
# Lifesize project import test executed from https://gitlab.com/gitlab-org/manage/import/import-metrics
# rubocop:disable Rails/Pluck
module QA
RSpec.describe 'Manage', :github, requires_admin: 'creates users', only: { job: 'large-github-import' } do
- describe 'Project import' do
+ describe 'Project import', product_group: :import do # rubocop:disable RSpec/MultipleMemoizedHelpers
+ let(:github_repo) { ENV['QA_LARGE_IMPORT_REPO'] || 'rspec/rspec-core' }
+ let(:import_max_duration) { ENV['QA_LARGE_IMPORT_DURATION']&.to_i || 7200 }
let(:logger) { Runtime::Logger.logger }
let(:differ) { RSpec::Support::Differ.new(color: true) }
- let(:gitlab_address) { QA::Runtime::Scenario.gitlab_address }
+ let(:gitlab_address) { QA::Runtime::Scenario.gitlab_address.chomp("/") }
let(:dummy_url) { "https://example.com" }
+ let(:api_request_params) { { auto_paginate: true, attempts: 2 } }
let(:created_by_pattern) { /\*Created by: \S+\*\n\n/ }
let(:suggestion_pattern) { /suggestion:-\d+\+\d+/ }
let(:gh_link_pattern) { %r{https://github.com/#{github_repo}/(issues|pull)} }
let(:gl_link_pattern) { %r{#{gitlab_address}/#{imported_project.path_with_namespace}/-/(issues|merge_requests)} }
- let(:event_pattern) { %r{(un)?assigned( to)? @\S+|mentioned in (issue|merge request) [!#]\d+|changed title from \*\*.*\*\* to \*\*.*\*\*} } # rubocop:disable Layout/LineLength
+ # rubocop:disable Lint/MixedRegexpCaptureTypes
+ let(:event_pattern) do
+ Regexp.union(
+ [
+ /(?<event>(un)?assigned)( to)? @\S+/,
+ /(?<event>mentioned) in (issue|merge request) [!#]\d+/,
+ /(?<event>changed title) from \*\*.*\*\* to \*\*.*\*\*/,
+ /(?<event>requested review) from @\w+/,
+ /\*(?<event>Merged) by:/,
+ /\*\*(Review):\*\*/
+ ]
+ )
+ end
+ # rubocop:enable Lint/MixedRegexpCaptureTypes
+
+ # mapping from gitlab to github names
+ let(:event_mapping) do
+ {
+ "label_add" => "labeled",
+ "label_remove" => "unlabeled",
+ "milestone_add" => "milestoned",
+ "milestone_remove" => "demilestoned",
+ "assigned" => "assigned",
+ "unassigned" => "unassigned",
+ "changed title" => "renamed",
+ "requested review" => "review_requested",
+ "Merged" => "merged"
+ }
+ end
+
+ # github events that are not migrated or are not correctly mapable in gitlab
+ let(:unsupported_events) do
+ [
+ "head_ref_deleted",
+ "head_ref_force_pushed",
+ "head_ref_restored",
+ "base_ref_force_pushed",
+ "base_ref_changed",
+ "review_request_removed",
+ "review_dismissed",
+ "auto_squash_enabled",
+ "auto_merge_disabled",
+ "comment_deleted",
+ "convert_to_draft",
+ "ready_for_review",
+ "subscribed",
+ "unsubscribed",
+ "transferred",
+ "locked",
+ "unlocked",
+ # mentions are supported but they can be reported differently on gitlab's side
+ # for example mention of issue creation in pr will be reported in the issue on gitlab side
+ # or referenced in github will still create a 'mentioned in' comment in gitlab
+ "referenced",
+ "mentioned"
+ ]
+ end
let(:api_client) { Runtime::API::Client.as_admin }
@@ -25,79 +86,105 @@ module QA
end
end
- let(:github_repo) { ENV['QA_LARGE_IMPORT_REPO'] || 'rspec/rspec-core' }
- let(:import_max_duration) { ENV['QA_LARGE_IMPORT_DURATION'] ? ENV['QA_LARGE_IMPORT_DURATION'].to_i : 7200 }
let(:github_client) do
Octokit::Client.new(
access_token: ENV['QA_LARGE_IMPORT_GH_TOKEN'] || Runtime::Env.github_access_token,
- auto_paginate: true
+ auto_paginate: true,
+ middleware: Faraday::RackBuilder.new do |builder|
+ builder.use(Faraday::Retry::Middleware, exceptions: [Octokit::InternalServerError, Octokit::ServerError])
+ end
)
end
let(:gh_repo) { github_client.repository(github_repo) }
let(:gh_branches) do
- logger.debug("= Fetching branches =")
+ logger.info("= Fetching branches =")
github_client.branches(github_repo).map(&:name)
end
let(:gh_commits) do
- logger.debug("= Fetching commits =")
+ logger.info("= Fetching commits =")
github_client.commits(github_repo).map(&:sha)
end
let(:gh_labels) do
- logger.debug("= Fetching labels =")
+ logger.info("= Fetching labels =")
github_client.labels(github_repo).map { |label| { name: label.name, color: "##{label.color}" } }
end
let(:gh_milestones) do
- logger.debug("= Fetching milestones =")
+ logger.info("= Fetching milestones =")
github_client
.list_milestones(github_repo, state: 'all')
.map { |ms| { title: ms.title, description: ms.description } }
end
- let(:gh_all_issues) do
- logger.debug("= Fetching issues and prs =")
- github_client.list_issues(github_repo, state: 'all')
- end
-
let(:gh_prs) do
gh_all_issues.select(&:pull_request).each_with_object({}) do |pr, hash|
- hash[pr.number] = {
+ id = pr.number
+ hash[id] = {
url: pr.html_url,
title: pr.title,
body: pr.body || '',
- comments: [*gh_pr_comments[pr.html_url], *gh_issue_comments[pr.html_url]].compact
+ comments: [*gh_pr_comments[id], *gh_issue_comments[id]].compact,
+ events: gh_pr_events[id].reject { |event| unsupported_events.include?(event) }
}
end
end
let(:gh_issues) do
gh_all_issues.reject(&:pull_request).each_with_object({}) do |issue, hash|
- hash[issue.number] = {
+ id = issue.number
+ hash[id] = {
url: issue.html_url,
title: issue.title,
body: issue.body || '',
- comments: gh_issue_comments[issue.html_url]
+ comments: gh_issue_comments[id],
+ events: gh_issue_events[id].reject { |event| unsupported_events.include?(event) }
}
end
end
+ let(:gh_all_issues) do
+ logger.info("= Fetching issues and prs =")
+ github_client.list_issues(github_repo, state: 'all')
+ end
+
+ let(:gh_all_events) do
+ logger.info("- Fetching issue and pr events -")
+ github_client.repository_issue_events(github_repo).map do |event|
+ { name: event[:event], **(event[:issue] || {}) } # some events don't have issue object at all
+ end
+ end
+
+ let(:gh_issue_events) do
+ gh_all_events.each_with_object(Hash.new { |h, k| h[k] = [] }) do |event, hash|
+ next if event[:pull_request] || !event[:number]
+
+ hash[event[:number]] << event[:name]
+ end
+ end
+
+ let(:gh_pr_events) do
+ gh_all_events.each_with_object(Hash.new { |h, k| h[k] = [] }) do |event, hash|
+ next unless event[:pull_request]
+
+ hash[event[:number]] << event[:name]
+ end
+ end
+
let(:gh_issue_comments) do
- logger.debug("= Fetching issue comments =")
+ logger.info("- Fetching issue comments -")
github_client.issues_comments(github_repo).each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, hash|
- # use base html url as key
- hash[c.html_url.gsub(/\#\S+/, "")] << c.body&.gsub(gh_link_pattern, dummy_url)
+ hash[id_from_url(c.html_url)] << c.body&.gsub(gh_link_pattern, dummy_url)
end
end
let(:gh_pr_comments) do
- logger.debug("= Fetching pr comments =")
+ logger.info("- Fetching pr comments -")
github_client.pull_requests_comments(github_repo).each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, hash|
- # use base html url as key
- hash[c.html_url.gsub(/\#\S+/, "")] << c.body
+ hash[id_from_url(c.html_url)] << c.body
# some suggestions can contain extra whitespaces which gitlab will remove
&.gsub(/suggestion\s+\r/, "suggestion\r")
&.gsub(gh_link_pattern, dummy_url)
@@ -111,11 +198,12 @@ module QA
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = github_repo
project.personal_namespace = user.username
- project.api_client = api_client
+ project.api_client = Runtime::API::Client.new(user: user)
+ project.issue_events_import = true
+ project.full_notes_import = true
end
end
- # rubocop:disable RSpec/InstanceVariable
after do |example|
next unless defined?(@import_time)
@@ -138,8 +226,10 @@ module QA
milestones: gh_milestones.length,
mrs: gh_prs.length,
mr_comments: gh_prs.sum { |_k, v| v[:comments].length },
+ mr_events: gh_prs.sum { |_k, v| v[:events].length },
issues: gh_issues.length,
- issue_comments: gh_issues.sum { |_k, v| v[:comments].length }
+ issue_comments: gh_issues.sum { |_k, v| v[:comments].length },
+ issue_events: gh_issues.sum { |_k, v| v[:events].length }
}
},
target: {
@@ -153,8 +243,10 @@ module QA
milestones: gl_milestones.length,
mrs: mrs.length,
mr_comments: mrs.sum { |_k, v| v[:comments].length },
+ mr_events: mrs.sum { |_k, v| v[:events].length },
issues: gl_issues.length,
- issue_comments: gl_issues.sum { |_k, v| v[:comments].length }
+ issue_comments: gl_issues.sum { |_k, v| v[:comments].length },
+ issue_events: gl_issues.sum { |_k, v| v[:events].length }
}
},
not_imported: {
@@ -164,7 +256,6 @@ module QA
}
)
end
- # rubocop:enable RSpec/InstanceVariable
it(
'imports large Github repo via api',
@@ -172,8 +263,9 @@ module QA
) do
start = Time.now
- # import the project and log gitlab path
- logger.info("== Importing project '#{github_repo}' in to '#{imported_project.reload!.full_path}' ==")
+ # trigger import and log project paths
+ logger.info("== Triggering import of project '#{github_repo}' in to '#{imported_project.reload!.full_path}' ==")
+
# fetch all objects right after import has started
fetch_github_objects
@@ -182,7 +274,7 @@ module QA
@stats = status.dig(:stats, :imported)
# fail fast if import explicitly failed
- raise "Import of '#{imported_project.name}' failed!" if status[:import_status] == 'failed'
+ raise "Import of '#{imported_project.full_path}' failed!" if status[:import_status] == 'failed'
status[:import_status]
end
@@ -276,25 +368,26 @@ module QA
count_msg = "Expected to contain same amount of #{type}s. Gitlab: #{expected.length}, Github: #{actual.length}"
expect(expected.length).to eq(actual.length), count_msg
- missing_comments = verify_comments(type, actual, expected)
+ missing_objects = (actual.keys - expected.keys).map { |it| actual[it].slice(:title, :url) }
+ missing_content = verify_comments_and_events(type, actual, expected)
{
- "#{type}s": (actual.keys - expected.keys).map { |it| actual[it].slice(:title, :url) },
- "#{type}_comments": missing_comments
- }
+ "#{type}s": missing_objects.empty? ? nil : missing_objects,
+ "#{type}_content": missing_content.empty? ? nil : missing_content
+ }.compact
end
- # Verify imported comments
+ # Verify imported comments and events
#
# @param [String] type verification object, 'mrs' or 'issues'
# @param [Hash] actual
# @param [Hash] expected
# @return [Hash]
- def verify_comments(type, actual, expected)
- actual.each_with_object([]) do |(key, actual_item), missing_comments|
+ def verify_comments_and_events(type, actual, expected)
+ actual.each_with_object([]) do |(key, actual_item), missing_content|
expected_item = expected[key]
title = actual_item[:title]
- msg = "expected #{type} with title '#{title}' to have"
+ msg = "expected #{type} with iid '#{key}' to have"
# Print title in the error message to see which object is missing
#
@@ -320,17 +413,27 @@ module QA
expect(expected_comments.length).to eq(actual_comments.length), comment_count_msg
expect(expected_comments).to match_array(actual_comments)
- # Save missing comments
+ expected_events = expected_item[:events]
+ actual_events = actual_item[:events]
+ event_count_msg = <<~MSG
+ #{msg} same amount of events. Gitlab: #{expected_events.length}, Github: #{actual_events.length}
+ MSG
+ expect(expected_events.length).to eq(actual_events.length), event_count_msg
+ expect(expected_events).to match_array(actual_events)
+
+ # Save missing comments and events
#
comment_diff = actual_comments - expected_comments
- next if comment_diff.empty?
+ event_diff = actual_events - expected_events
+ next if comment_diff.empty? && event_diff.empty?
- missing_comments << {
+ missing_content << {
title: title,
github_url: actual_item[:url],
gitlab_url: expected_item[:url],
- missing_comments: comment_diff
- }
+ missing_comments: comment_diff.empty? ? nil : comment_diff,
+ missing_events: event_diff.empty? ? nil : event_diff
+ }.compact
end
end
@@ -380,26 +483,27 @@ module QA
def mrs
@mrs ||= begin
logger.debug("= Fetching merge requests =")
- imported_mrs = imported_project.merge_requests(auto_paginate: true, attempts: 2)
+ imported_mrs = imported_project.merge_requests(**api_request_params)
logger.debug("= Fetching merge request comments =")
- Parallel.map(imported_mrs, in_threads: 4) do |mr|
+ Parallel.map(imported_mrs, in_threads: Etc.nprocessors) do |mr|
resource = Resource::MergeRequest.init do |resource|
resource.project = imported_project
resource.iid = mr[:iid]
resource.api_client = api_client
end
- logger.debug("Fetching comments for mr '#{mr[:title]}'")
- comments = resource
- .comments(auto_paginate: true, attempts: 2)
- .reject { |c| c[:system] || c[:body].match?(/^(\*\*Review:\*\*)|(\*Merged by:).*/) }
+ logger.debug("Fetching events and comments for mr '!#{mr[:iid]}'")
+ comments = resource.comments(**api_request_params)
+ label_events = resource.label_events(**api_request_params)
+ state_events = resource.state_events(**api_request_params)
+ milestone_events = resource.milestone_events(**api_request_params)
[mr[:iid], {
url: mr[:web_url],
title: mr[:title],
body: sanitize_description(mr[:description]) || '',
- events: events(comments),
+ events: events(comments, label_events, state_events, milestone_events),
comments: non_event_comments(comments)
}]
end.to_h
@@ -412,48 +516,59 @@ module QA
def gl_issues
@gl_issues ||= begin
logger.debug("= Fetching issues =")
- imported_issues = imported_project.issues(auto_paginate: true, attempts: 2)
+ imported_issues = imported_project.issues(**api_request_params)
logger.debug("= Fetching issue comments =")
- Parallel.map(imported_issues, in_threads: 4) do |issue|
+ Parallel.map(imported_issues, in_threads: Etc.nprocessors) do |issue|
resource = Resource::Issue.init do |issue_resource|
issue_resource.project = imported_project
issue_resource.iid = issue[:iid]
issue_resource.api_client = api_client
end
- logger.debug("Fetching comments for issue '#{issue[:title]}'")
- comments = resource.comments(auto_paginate: true, attempts: 2)
+ logger.debug("Fetching events and comments for issue '!#{issue[:iid]}'")
+ comments = resource.comments(**api_request_params)
+ label_events = resource.label_events(**api_request_params)
+ state_events = resource.state_events(**api_request_params)
+ milestone_events = resource.milestone_events(**api_request_params)
[issue[:iid], {
url: issue[:web_url],
title: issue[:title],
body: sanitize_description(issue[:description]) || '',
- events: events(comments),
+ events: events(comments, label_events, state_events, milestone_events),
comments: non_event_comments(comments)
}]
end.to_h
end
end
- # Fetch comments without events
+ # Filter out event comments
#
# @param [Array] comments
# @return [Array]
def non_event_comments(comments)
comments
- .reject { |c| c[:body].match?(event_pattern) }
+ .reject { |c| c[:system] || c[:body].match?(event_pattern) }
.map { |c| sanitize_comment(c[:body]) }
end
# Events
#
# @param [Array] comments
+ # @param [Array] label_events
+ # @param [Array] state_events
+ # @param [Array] milestone_events
# @return [Array]
- def events(comments)
- comments
- .select { |c| c[:body].match?(event_pattern) }
- .map { |c| c[:body] }
+ def events(comments, label_events, state_events, milestone_events)
+ mapped_label_events = label_events.map { |event| event_mapping["label_#{event[:action]}"] }
+ mapped_milestone_events = milestone_events.map { |event| event_mapping["milestone_#{event[:action]}"] }
+ mapped_state_event = state_events.map { |event| event[:state] }
+ mapped_comment_events = comments.map do |c|
+ event_mapping[c[:body].match(event_pattern)&.named_captures&.fetch("event", nil)]
+ end
+
+ [*mapped_label_events, *mapped_milestone_events, *mapped_state_event, *mapped_comment_events].compact
end
# Normalize comments and make them directly comparable
@@ -489,6 +604,16 @@ module QA
def save_json(name, json)
File.open("tmp/#{name}.json", "w") { |file| file.write(JSON.pretty_generate(json)) }
end
+
+ # Extract id number from web url of issue or pull request
+ #
+ # Some endpoints don't return object id as separate parameter so web url can be used as a workaround
+ #
+ # @param [String] url
+ # @return [Integer]
+ def id_from_url(url)
+ url.match(%r{(?<type>issues|pull)/(?<id>\d+)})&.named_captures&.fetch("id", nil).to_i
+ end
end
end
end
diff --git a/qa/qa/specs/features/api/3_create/integrations/webhook_events_spec.rb b/qa/qa/specs/features/api/1_manage/integrations/webhook_events_spec.rb
index aae0329003b..a2d66ffe8d3 100644
--- a/qa/qa/specs/features/api/3_create/integrations/webhook_events_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/integrations/webhook_events_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
- describe 'WebHooks integration', :requires_admin, :integrations, :orchestrated do
+ RSpec.describe 'Manage' do
+ describe 'WebHooks integration', :requires_admin, :integrations, :orchestrated, product_group: :integrations do
before(:context) do
toggle_local_requests(true)
end
@@ -70,7 +70,8 @@ module QA
end
end
- it 'sends an issues and note event', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349723' do
+ it 'sends an issues and note event',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349723' do
setup_webhook(issues: true, note: true) do |webhook, smocker|
issue = Resource::Issue.fabricate_via_api! do |issue_init|
issue_init.project = webhook.project
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
index f721b3326a0..e17e12cdaf3 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :reliable, :requires_admin do
+ RSpec.describe 'Manage', :reliable, :requires_admin, product_group: :import do
describe 'Gitlab migration' do
let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } }
let(:admin_api_client) { Runtime::API::Client.as_admin }
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
index 74a00e1c74c..c1f11b15068 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb
@@ -4,7 +4,7 @@ require_relative 'gitlab_project_migration_common'
module QA
RSpec.describe 'Manage' do
- describe 'Gitlab migration' do
+ describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
let!(:source_issue) do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
index 83cc44f9958..5689fa169ce 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
@@ -5,7 +5,7 @@
# rubocop:disable Rails/Pluck, Layout/LineLength, RSpec/MultipleMemoizedHelpers
module QA
RSpec.describe "Manage", requires_admin: 'creates users', only: { job: 'large-gitlab-import' } do
- describe "Gitlab migration" do
+ describe "Gitlab migration", product_group: :import do
let(:logger) { Runtime::Logger.logger }
let(:differ) { RSpec::Support::Differ.new(color: true) }
let(:gitlab_group) { ENV['QA_LARGE_IMPORT_GROUP'] || 'gitlab-migration' }
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
index 704325d9235..aa4d3becbe7 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
@@ -4,7 +4,7 @@ require_relative 'gitlab_project_migration_common'
module QA
RSpec.describe 'Manage' do
- describe 'Gitlab migration' do
+ describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
let(:member) do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
index d656ea4dea5..92cba005832 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
@@ -4,7 +4,7 @@ require_relative 'gitlab_project_migration_common'
module QA
RSpec.describe 'Manage' do
- describe 'Gitlab migration' do
+ describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
context 'with merge request' do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
index 484c32956e3..3db4ff4351e 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
@@ -4,7 +4,7 @@ require_relative 'gitlab_project_migration_common'
module QA
RSpec.describe 'Manage' do
- describe 'Gitlab migration' do
+ describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
context 'with ci pipeline' do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
index 421dbe56a99..3e0df3d1e13 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb
@@ -4,7 +4,7 @@ require_relative 'gitlab_project_migration_common'
module QA
RSpec.describe 'Manage' do
- describe 'Gitlab migration' do
+ describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
context 'with uninitialized project' do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
index 6910b6a7fa2..91dcfe6a1a3 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
@@ -4,7 +4,7 @@ require_relative 'gitlab_project_migration_common'
module QA
RSpec.describe 'Manage' do
- describe 'Gitlab migration' do
+ describe 'Gitlab migration', product_group: :import do
include_context 'with gitlab project migration'
context 'with release' do
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
index 3581ad3d207..9c80c088917 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
@@ -1,9 +1,11 @@
# frozen_string_literal: true
module QA
- # Disable on live envs until bulk_import_projects toggle is on by default
- # Otherwise tests running in parallel can disable feature in the middle of other test
RSpec.shared_context 'with gitlab project migration', requires_admin: 'creates a user via API',
+ quarantine: {
+ type: :flaky,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/364839'
+ },
feature_flag: {
name: 'bulk_import_projects',
scope: :global
diff --git a/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb b/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
index 539da92f471..c4be90d3759 100644
--- a/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
@@ -33,9 +33,7 @@ module QA
commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = @project_access_token.project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }
- ])
+ commit.add_files([{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }])
end
end.not_to raise_error
end
@@ -67,9 +65,7 @@ module QA
commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = @different_project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }
- ])
+ commit.add_files([{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }])
end
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError, /403 Forbidden - You are not allowed to push into this branch/)
end
diff --git a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
index 874626e01f1..24088057abc 100644
--- a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage', :requires_admin, :skip_live_env, except: { job: 'review-qa-*' } do
- describe 'rate limits', :reliable do
+ describe 'rate limits', :reliable, product_group: :integrations do
let(:rate_limited_user) { Resource::User.fabricate_via_api! }
let(:api_client) { Runtime::API::Client.new(:gitlab, user: rate_limited_user) }
let!(:request) { Runtime::API::Request.new(api_client, '/users') }
diff --git a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
index e518bbfc6f7..28c20344b29 100644
--- a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
@@ -69,9 +69,7 @@ module QA
commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = @project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: 'test.txt', content: 'new file' }
- ])
+ commit.add_files([{ file_path: 'test.txt', content: 'new file' }])
end
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError, /403 Forbidden - You are not allowed to push into this branch/)
end
diff --git a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb b/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb
index 9f0e2664213..16d4fd35b69 100644
--- a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin do
+ describe 'User', :requires_admin, product_group: :workspace do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:sub_group) do
@@ -85,9 +85,7 @@ module QA
commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = sub_group_project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: 'test.txt', content: 'new file' }
- ])
+ commit.add_files([{ file_path: 'test.txt', content: 'new file' }])
end
end.not_to raise_error
end
@@ -167,9 +165,7 @@ module QA
commit.branch = "new_branch_#{SecureRandom.hex(8)}"
commit.start_branch = parent_group_project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: 'test.txt', content: 'new file' }
- ])
+ commit.add_files([{ file_path: 'test.txt', content: 'new file' }])
end
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError,
/403 Forbidden - You are not allowed to push into this branch/)
diff --git a/qa/qa/specs/features/api/1_manage/users_spec.rb b/qa/qa/specs/features/api/1_manage/users_spec.rb
index 531419e8d0f..ff036c18671 100644
--- a/qa/qa/specs/features/api/1_manage/users_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/users_spec.rb
@@ -4,7 +4,7 @@ require 'airborne'
module QA
RSpec.describe 'Manage' do
- describe 'Users API', :reliable do
+ describe 'Users API', :reliable, product_group: :workspace do
let(:api_client) { Runtime::API::Client.new(:gitlab) }
let(:request) { Runtime::API::Request.new(api_client, '/users') }
diff --git a/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb b/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb
index 9d47872a774..4ee436a597a 100644
--- a/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb
@@ -16,18 +16,18 @@ module QA
commit.project = project
commit.update_files(
[
- {
- file_path: '.gitlab-ci.yml',
- content: 'script'
- }
+ {
+ file_path: '.gitlab-ci.yml',
+ content: 'script'
+ }
]
)
commit.add_files(
[
- {
- file_path: 'foo',
- content: 'bar'
- }
+ {
+ file_path: 'foo',
+ content: 'bar'
+ }
]
)
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb
index a1b9e232e3d..c690202f091 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- describe 'Manage', :requires_admin, :reliable do
+ describe 'Manage', :requires_admin, :reliable, product_group: :import do
describe 'Gitlab migration' do
let!(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user) do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
index 2c331584cf7..d684eabe644 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project transfer between groups', :reliable do
+ describe 'Project transfer between groups', :reliable, product_group: :workspace do
let(:source_group) do
Resource::Group.fabricate_via_api! do |group|
group.path = "source-group-#{SecureRandom.hex(8)}"
@@ -27,9 +27,7 @@ module QA
before do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
- commit.add_files([
- { file_path: 'README.md', content: readme_content }
- ])
+ commit.add_files([{ file_path: 'README.md', content: readme_content }])
end
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb
index 4bfd253c992..b8d00c2faee 100644
--- a/qa/qa/specs/features/browser_ui/3_create/jenkins/jenkins_build_status_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jenkins/jenkins_build_status_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :requires_admin, :skip_live_env, except: { job: 'review-qa-*' } do
- describe 'Jenkins integration' do
+ RSpec.describe 'Manage', :requires_admin, :skip_live_env, except: { job: 'review-qa-*' } do
+ describe 'Jenkins integration', product_group: :integrations do
let(:jenkins_server) { Service::DockerRun::Jenkins.new }
let(:jenkins_client) do
@@ -48,7 +48,8 @@ module QA
toggle_local_requests(false)
end
- it 'integrates and displays build status for MR pipeline in GitLab', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347788' do
+ it 'integrates and displays build status for MR pipeline in GitLab',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347788' do
setup_project_integration
jenkins_integration = project.find_integration('jenkins')
@@ -133,7 +134,8 @@ module QA
def patch_host_name(host_name, container_name)
return host_name unless host_name.include?('localhost')
- ip_address = `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' #{container_name}`.strip
+ ip_address = `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' #{container_name}`
+ .strip
host_name.gsub('localhost', ip_address)
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb
index 088556a3981..5a4031b4305 100644
--- a/qa/qa/specs/features/browser_ui/3_create/jira/jira_basic_integration_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_basic_integration_spec.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create' do
+ RSpec.describe 'Manage' do
include Support::API
- describe 'Jira integration', :jira, :orchestrated, :requires_admin do
+ describe 'Jira integration', :jira, :orchestrated, :requires_admin, product_group: :integrations do
let(:jira_project_key) { 'JITP' }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -15,7 +15,8 @@ module QA
before do
page.visit Vendor::Jira::JiraAPI.perform(&:base_url)
- QA::Support::Retrier.retry_until(sleep_interval: 3, reload_page: page, max_attempts: 20, raise_on_failure: true) do
+ QA::Support::Retrier
+ .retry_until(sleep_interval: 3, reload_page: page, max_attempts: 20, raise_on_failure: true) do
page.has_text? 'Welcome to Jira'
end
@@ -33,10 +34,11 @@ module QA
jira.setup_service_with(url: Vendor::Jira::JiraAPI.perform(&:base_url))
end
- expect(page).not_to have_text("Requests to the local network are not allowed")
+ expect(page).not_to have_text("Requests to the local network are not allowed") # rubocop:disable RSpec/ExpectInHook
end
- it 'closes an issue via pushing a commit', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347794' do
+ it 'closes an issue via pushing a commit',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347794' do
issue_key = Vendor::Jira::JiraAPI.perform do |jira_api|
jira_api.create_issue(jira_project_key)
end
@@ -46,7 +48,8 @@ module QA
expect_issue_done(issue_key)
end
- it 'closes an issue via a merge request', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347795' do
+ it 'closes an issue via a merge request',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347795' do
issue_key = Vendor::Jira::JiraAPI.perform do |jira_api|
jira_api.create_issue(jira_project_key)
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
index d8435407296..7e46276be92 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/jira_issue_import_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable do
- describe 'Jira issue import', :jira, :orchestrated, :requires_admin do
+ RSpec.describe 'Manage', :reliable do
+ describe 'Jira issue import', :jira, :orchestrated, :requires_admin, product_group: :integrations do
let(:jira_project_key) { "JITD" }
let(:jira_issue_title) { "[#{jira_project_key}-1] Jira to GitLab Test Issue" }
let(:jira_issue_description) { "This issue is for testing importing Jira issues to GitLab." }
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_status_emails_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb
index f4794b3a904..4495d83f336 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_status_emails_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/pipeline_status_emails_spec.rb
@@ -24,7 +24,7 @@ module QA
end
end
- RSpec.describe 'Verify', :orchestrated, :runner, :requires_admin, :smtp do
+ RSpec.describe 'Manage', :orchestrated, :runner, :requires_admin, :smtp, product_group: :integrations do
describe 'Pipeline status emails' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:emails) { %w[foo@bar.com baz@buzz.com] }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
index ad90df4b90d..56883917153 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
@@ -3,8 +3,12 @@
module QA
RSpec.describe 'Manage', :requires_admin, :skip_live_env do
describe '2FA' do
+ let(:admin_api_client) { Runtime::API::Client.as_admin }
+ let(:owner_api_client) { Runtime::API::Client.new(:gitlab, user: owner_user) }
+
let!(:owner_user) do
Resource::User.fabricate_via_api! do |usr|
+ usr.username = "owner_user_#{SecureRandom.hex(4)}"
usr.api_client = admin_api_client
end
end
@@ -26,6 +30,7 @@ module QA
let(:developer_user) do
Resource::User.fabricate_via_api! do |resource|
+ resource.username = "developer_user_#{SecureRandom.hex(4)}"
resource.api_client = admin_api_client
end
end
@@ -38,8 +43,7 @@ module QA
it(
'allows enforcing 2FA via UI and logging in with 2FA',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931',
- quarantine: { type: :flaky, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/369516' }
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931'
) do
enforce_two_factor_authentication_on_group(group)
@@ -70,14 +74,6 @@ module QA
developer_user.remove_via_api!
end
- def admin_api_client
- @admin_api_client ||= Runtime::API::Client.as_admin
- end
-
- def owner_api_client
- @owner_api_client ||= Runtime::API::Client.new(:gitlab, user: owner_user)
- end
-
# We are intentionally using the UI to enforce 2FA to exercise the flow with UI.
# Any future tests should use the API for this purpose.
def enforce_two_factor_authentication_on_group(group)
@@ -87,7 +83,9 @@ module QA
Page::Group::Menu.perform(&:click_group_general_settings_item)
Page::Group::Settings::General.perform(&:set_require_2fa_enabled)
- expect(page).to have_text(two_fa_expected_text)
+ QA::Support::Retrier.retry_on_exception(reload_page: page) do
+ expect(page).to have_text(two_fa_expected_text)
+ end
Page::Profile::TwoFactorAuth.perform(&:click_configure_it_later_button)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
index 90fbff3261e..3f461e9247f 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :reliable do
+ RSpec.describe 'Manage', :reliable, product_group: :workspace do
describe 'Add project member' do
it 'user adds project member', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347887' do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb
index f624f2fb44f..b251b3075dd 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Create project badge', :reliable do
+ describe 'Create project badge', :reliable, product_group: :workspace do
let(:badge_name) { "project-badge-#{SecureRandom.hex(8)}" }
let(:expected_badge_link_url) { "#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}" }
let(:expected_badge_image_url) { "#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}/badges/main/pipeline.svg" }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
index d07fff80b19..7c6b0d77219 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :smoke do
+ RSpec.describe 'Manage', :smoke, product_group: :workspace do
describe 'Project' do
shared_examples 'successful project creation' do
it 'creates a new project' do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
index d299997dd3c..2abbb6ca73c 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
+ RSpec.describe 'Manage', product_group: :workspace do
shared_examples 'loads all images' do |admin|
let(:api_client) { Runtime::API::Client.as_admin }
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 0477a9b8a1f..6ac11fea7e1 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,7 +3,7 @@
module QA
# Spec uses real github.com, which means outage of github can actually block deployment
# Keep spec in reliable bucket but don't run in blocking pipelines
- RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin do
+ RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do
describe 'Project import' do
let(:github_repo) { 'gitlab-qa-github/import-test' }
let(:api_client) { Runtime::API::Client.as_admin }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
index dbfb114dc82..164f86bffce 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Invite group', :reliable do
+ describe 'Invite group', :reliable, product_group: :workspace do
shared_examples 'invites group to project' do
it 'verifies group is added and members can access project with correct access level' do
Page::Project::Menu.perform(&:click_members)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb
index 29e590976d2..98a08dd0d9a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project owner permissions', :reliable do
+ describe 'Project owner permissions', :reliable, product_group: :workspace do
let!(:owner) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
index 88f4996ff03..33ca5f6009c 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project activity', :reliable do
+ describe 'Project activity', :reliable, product_group: :workspace do
it 'user creates an event in the activity page upon Git push',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
index a384dc16064..b9b82baa6f1 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin do
+ describe 'User', :requires_admin, product_group: :workspace do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let(:followed_user_api_client) { Runtime::API::Client.new(:gitlab, user: followed_user) }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb
index 8462f5db30b..54f05f84dca 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin, :reliable do
+ describe 'User', :requires_admin, :reliable, product_group: :workspace do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user) do
@@ -27,7 +27,7 @@ module QA
end
end
- context 'after parent group membership termination' do
+ context 'for after parent group membership termination' do
before do
Flow::Login.while_signed_in_as_admin do
group.sandbox.visit!
@@ -39,7 +39,14 @@ module QA
end
end
- it 'is not allowed to edit the project files', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347866' do
+ after do
+ user.remove_via_api!
+ project.remove_via_api!
+ group.remove_via_api!
+ end
+
+ it 'is not allowed to edit the project files',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347866' do
Flow::Login.sign_in(as: user)
project.visit!
@@ -51,12 +58,6 @@ module QA
expect(page).to have_text("You can’t edit files directly in this project.")
end
-
- after do
- user.remove_via_api!
- project.remove_via_api!
- group.remove_via_api!
- end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb
index 8de9d7c2049..b7585f00630 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin do
+ describe 'User', :requires_admin, product_group: :workspace do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:sub_group) do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
index 206e6b8a456..b2c612d38fe 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb
@@ -19,12 +19,13 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = template_project
commit.commit_message = 'Add custom issue template'
- commit.add_files([
- {
- file_path: ".gitlab/issue_templates/#{template_name}.md",
- content: template_content
- }
- ])
+ commit.add_files(
+ [
+ {
+ file_path: ".gitlab/issue_templates/#{template_name}.md",
+ content: template_content
+ }
+ ])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
index a1d8b495129..d6e9c1a13df 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
@@ -18,9 +18,7 @@ module QA
commit.branch = "development"
commit.start_branch = project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: file_name, content: 'pssst!' }
- ])
+ commit.add_files([{ file_path: file_name, content: 'pssst!' }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
index 6ce4217f8ac..d975e18e962 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
@@ -20,12 +20,13 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = template_project
commit.commit_message = 'Add custom merge request template'
- commit.add_files([
- {
- file_path: ".gitlab/merge_request_templates/#{template_name}.md",
- content: template_content
- }
- ])
+ commit.add_files(
+ [
+ {
+ file_path: ".gitlab/merge_request_templates/#{template_name}.md",
+ content: template_content
+ }
+ ])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
index 8885163b5e3..205ff12ff03 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
@@ -16,9 +16,7 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: file_name, content: 'pssst!' }
- ])
+ commit.add_files([{ file_path: file_name, content: 'pssst!' }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb
new file mode 100644
index 00000000000..37e737a4f84
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_creation_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ describe 'Testing wiki content creation inside a project' do
+ let(:new_wiki_title) { "just_another_wiki_page" }
+ let(:new_wiki_content) { "this content is changed or added" }
+ let(:commit_message) { "this is a new addition to the wiki" }
+
+ let(:project) { Resource::Project.fabricate_via_api! }
+ let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'by adding a home page to the wiki',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347809' do
+ project.visit!
+
+ Page::Project::Menu.perform(&:click_wiki)
+ Page::Project::Wiki::Show.perform(&:click_create_your_first_page)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title new_wiki_title
+ edit.set_content new_wiki_content
+ edit.set_message commit_message
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_submit)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by adding a second page to the wiki',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347808' do
+ wiki.visit!
+
+ Page::Project::Wiki::Show.perform(&:click_new_page)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title new_wiki_title
+ edit.set_content new_wiki_content
+ edit.set_message commit_message
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_submit)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by adding a home page to the wiki using git push',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347806' do
+ empty_wiki = Resource::Wiki::ProjectPage.new do |empty_wiki|
+ empty_wiki.project = project
+ end
+
+ Resource::Repository::WikiPush.fabricate! do |push|
+ push.file_name = "#{new_wiki_title}.md"
+ push.file_content = new_wiki_content
+ push.commit_message = commit_message
+ push.wiki = empty_wiki
+ push.new_branch = true
+ end.visit!
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by adding a second page to the wiki using git push',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347807' do
+ Resource::Repository::WikiPush.fabricate! do |push|
+ push.file_name = "#{new_wiki_title}.md"
+ push.file_content = new_wiki_content
+ push.commit_message = commit_message
+ push.wiki = wiki
+ push.new_branch = false
+ end.visit!
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb
new file mode 100644
index 00000000000..a4bdb0193dd
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_content_manipulation_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ describe 'Testing wiki content manipulation inside a project' do
+ let(:new_wiki_title) { "just_another_wiki_page" }
+ let(:new_wiki_content) { "this content is changed or added" }
+ let(:commit_message) { "this is a new addition to the wiki" }
+
+ let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'by manipulating content on the page',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347810' do
+ wiki.visit!
+
+ Page::Project::Wiki::Show.perform(&:click_edit)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title new_wiki_title
+ edit.set_content new_wiki_content
+ edit.set_message commit_message
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_submit)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_title new_wiki_title
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+
+ it 'by manipulating content on the page using git push',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347811' do
+ Resource::Repository::WikiPush.fabricate! do |push|
+ push.file_content = new_wiki_content
+ push.commit_message = commit_message
+ push.wiki = wiki
+ push.new_branch = false
+ end.visit!
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_content new_wiki_content
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb
index 2d24f69c883..0af964fc4bf 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_directory_management_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- context 'Wiki' do
+ describe 'A project wiki' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:new_path) { "a/new/path-with-spaces" }
@@ -10,7 +10,8 @@ module QA
Flow::Login.sign_in
end
- it 'has changed the directory', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347821' do
+ it 'can change the directory path of a page',
+testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347821' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_edit)
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb
index 4b8edf8b792..361fc459d54 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_file_upload_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create', :reliable do
- context 'Content Editor' do
+ describe 'Testing project wiki file upload' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:page_title) { 'Content Editor Page' }
let(:heading_text) { 'My New Heading' }
@@ -16,7 +16,8 @@ module QA
initial_wiki.project.remove_via_api!
end
- it 'creates a formatted Wiki page with an image uploaded', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347640' do
+ it 'by creating a formatted page with an image uploaded',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347640' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_new_page)
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb
index 703d425079d..5c9b97659a7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_list_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_list_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- context 'Wiki' do
+ describe 'Project Wiki' do
let(:small_number_of_pages) { 5 }
let(:large_number_of_pages) { 15 }
let(:random_page) { "bulk_#{rand(0..4)}" }
@@ -14,8 +14,9 @@ module QA
Flow::Login.sign_in
end
- context 'Sidebar' do
- it 'has all expected links that work', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347814' do
+ context 'with Wiki Sidebar' do
+ it 'has all expected links that work',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347814' do
small_wiki.visit!
small_number_of_pages.times do |index|
@@ -34,8 +35,9 @@ module QA
end
end
- context 'Page List' do
- it 'has all expected links that work', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347813' do
+ context 'with Wiki Page List' do
+ it 'has all expected links that work',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347813' do
large_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_view_all_pages)
diff --git a/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb
new file mode 100644
index 00000000000..13e04180ab5
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/project_wiki/project_based_page_deletion_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ describe 'Testing project wiki'
+ let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'can delete a page',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347815' do
+ initial_wiki.visit!
+
+ Page::Project::Wiki::Show.perform(&:click_edit)
+ Page::Project::Wiki::Edit.perform(&:delete_page)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_no_page
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
index aa332a76c94..0503b1b3761 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
@@ -22,9 +22,7 @@ module QA
commit.branch = branch_name
commit.start_branch = project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: 'test-folder/test-file.md', content: 'new content' }
- ])
+ commit.add_files([{ file_path: 'test-folder/test-file.md', content: 'new content' }])
end
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
index 1ae1dd87c07..50df8afafaf 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
@@ -33,11 +33,11 @@ module QA
end
end
- context 'on a project with a less commonly used LICENSE',
+ context 'on a project with an unrecognized LICENSE',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366843' do
it_behaves_like 'project license detection' do
- let(:license_file_name) { 'GFDL-1.2-only' }
- let(:rendered_license_name) { 'Other' }
+ let(:license_file_name) { 'other' }
+ let(:rendered_license_name) { 'LICENSE' }
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb
index 65a15ce96a5..f4ca7955a0f 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb
@@ -31,7 +31,6 @@ module QA
Page::Project::Tag::Show.perform do |show|
expect(show).to have_tag_name(tag_name)
expect(show).to have_tag_message(tag_message)
- expect(show).to have_tag_release_notes(tag_release_notes)
expect(show).not_to have_element(:create_tag_button)
end
end
@@ -83,7 +82,6 @@ module QA
Page::Project::Tag::New.perform do |new_tag|
new_tag.fill_tag_name(name)
new_tag.fill_tag_message(message)
- new_tag.fill_release_notes(release_notes)
new_tag.click_create_tag_button
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
index 9735aa7959a..561a5a2cc1c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
@@ -22,12 +22,13 @@ module QA
before do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
- commit.add_files([
- {
- file_path: 'first_directory/test_file.txt',
- content: "Test file content"
- }
- ])
+ commit.add_files(
+ [
+ {
+ file_path: 'first_directory/test_file.txt',
+ content: "Test file content"
+ }
+ ])
end
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
index fc5754e2c7a..f03c651992c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
@@ -4,18 +4,18 @@ module QA
RSpec.describe 'Create' do
describe 'Open Web IDE from Diff Tab' do
files = [
- {
- file_path: 'file1',
- content: 'test1'
- },
- {
- file_path: 'file2',
- content: 'test2'
- },
- {
- file_path: 'file3',
- content: 'test3'
- }
+ {
+ file_path: 'file1',
+ content: 'test1'
+ },
+ {
+ file_path: 'file2',
+ content: 'test2'
+ },
+ {
+ file_path: 'file3',
+ content: 'test3'
+ }
]
let(:project) do
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb
deleted file mode 100644
index 648ef513e12..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_creation_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create' do
- context 'Wiki' do
- describe 'testing wiki content creation inside a project' do
- let(:new_wiki_title) { "just_another_wiki_page" }
- let(:new_wiki_content) { "this content is changed or added" }
- let(:commit_message) { "this is a new addition to the wiki" }
-
- let(:project) { Resource::Project.fabricate_via_api! }
- let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
-
- before do
- Flow::Login.sign_in
- end
-
- it 'by adding a home page to the wiki', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347809' do
- project.visit!
-
- Page::Project::Menu.perform(&:click_wiki)
- Page::Project::Wiki::Show.perform(&:click_create_your_first_page)
-
- Page::Project::Wiki::Edit.perform do |edit|
- edit.set_title new_wiki_title
- edit.set_content new_wiki_content
- edit.set_message commit_message
- end
-
- Page::Project::Wiki::Edit.perform(&:click_submit)
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_title new_wiki_title
- expect(wiki).to have_content new_wiki_content
- end
- end
-
- it 'by adding a second page to the wiki', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347808' do
- wiki.visit!
-
- Page::Project::Wiki::Show.perform(&:click_new_page)
-
- Page::Project::Wiki::Edit.perform do |edit|
- edit.set_title new_wiki_title
- edit.set_content new_wiki_content
- edit.set_message commit_message
- end
-
- Page::Project::Wiki::Edit.perform(&:click_submit)
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_title new_wiki_title
- expect(wiki).to have_content new_wiki_content
- end
- end
-
- it 'by adding a home page to the wiki using git push', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347806' do
- empty_wiki = Resource::Wiki::ProjectPage.new do |empty_wiki|
- empty_wiki.project = project
- end
-
- Resource::Repository::WikiPush.fabricate! do |push|
- push.file_name = "#{new_wiki_title}.md"
- push.file_content = new_wiki_content
- push.commit_message = commit_message
- push.wiki = empty_wiki
- push.new_branch = true
- end.visit!
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_title new_wiki_title
- expect(wiki).to have_content new_wiki_content
- end
- end
-
- it 'by adding a second page to the wiki using git push', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347807' do
- Resource::Repository::WikiPush.fabricate! do |push|
- push.file_name = "#{new_wiki_title}.md"
- push.file_content = new_wiki_content
- push.commit_message = commit_message
- push.wiki = wiki
- push.new_branch = false
- end.visit!
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_title new_wiki_title
- expect(wiki).to have_content new_wiki_content
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb
deleted file mode 100644
index 251728c149f..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_content_manipulation_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create' do
- context 'Wiki' do
- describe 'testing wiki content manipulation inside a project' do
- let(:new_wiki_title) { "just_another_wiki_page" }
- let(:new_wiki_content) { "this content is changed or added" }
- let(:commit_message) { "this is a new addition to the wiki" }
-
- let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
-
- before do
- Flow::Login.sign_in
- end
-
- it 'by manipulating content on the page', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347810' do
- wiki.visit!
-
- Page::Project::Wiki::Show.perform(&:click_edit)
-
- Page::Project::Wiki::Edit.perform do |edit|
- edit.set_title new_wiki_title
- edit.set_content new_wiki_content
- edit.set_message commit_message
- end
-
- Page::Project::Wiki::Edit.perform(&:click_submit)
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_title new_wiki_title
- expect(wiki).to have_content new_wiki_content
- end
- end
-
- it 'by manipulating content on the page using git push', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347811' do
- Resource::Repository::WikiPush.fabricate! do |push|
- push.file_content = new_wiki_content
- push.commit_message = commit_message
- push.wiki = wiki
- push.new_branch = false
- end.visit!
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_content new_wiki_content
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb
deleted file mode 100644
index 78d6d51f260..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_page_deletion_spec.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create' do
- context 'Wiki' do
- let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
-
- before do
- Flow::Login.sign_in
- end
-
- context 'Page deletion' do
- it 'has removed the deleted page correctly', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347815' do
- initial_wiki.visit!
-
- Page::Project::Wiki::Show.perform(&:click_edit)
- Page::Project::Wiki::Edit.perform(&:delete_page)
-
- Page::Project::Wiki::Show.perform do |wiki|
- expect(wiki).to have_no_page
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
index 078465770c6..222d1993bf4 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
@@ -51,16 +51,11 @@ module QA
commit.project = package_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: helm_upload_yaml
- },
- {
- file_path: 'Chart.yaml',
- content: helm_chart_yaml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: helm_upload_yaml },
+ { file_path: 'Chart.yaml', content: helm_chart_yaml }
+ ])
end
end
@@ -94,12 +89,7 @@ module QA
commit.project = client_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: helm_install_yaml
- }
- ])
+ commit.add_files([{ file_path: '.gitlab-ci.yml', content: helm_install_yaml }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
index 921b36b34af..690451f6147 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
@@ -48,26 +48,18 @@ module QA
it 'pushes and pulls a maven package', testcase: params[:testcase] do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
- maven_upload_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_upload_package.yaml.erb')).result(binding)
- package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
- settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
+ gitlab_ci_yaml = ERB.new(read_fixture('package_managers/maven/group/producer', 'gitlab_ci.yaml.erb')).result(binding)
+ pom_xml = ERB.new(read_fixture('package_managers/maven/group/producer', 'pom.xml.erb')).result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven/group/producer', 'settings.xml.erb')).result(binding)
commit.project = package_project
commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_upload_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gitlab_ci_yaml },
+ { file_path: 'pom.xml', content: pom_xml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
end
end
@@ -97,26 +89,18 @@ module QA
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
- maven_install_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_install_package.yaml.erb')).result(binding)
- client_pom_xml = ERB.new(read_fixture('package_managers/maven', 'client_pom.xml.erb')).result(binding)
- settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
+ gitlab_ci_yaml = ERB.new(read_fixture('package_managers/maven/group/consumer', 'gitlab_ci.yaml.erb')).result(binding)
+ pom_xml = ERB.new(read_fixture('package_managers/maven/group/consumer', 'pom.xml.erb')).result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven/group/consumer', 'settings.xml.erb')).result(binding)
commit.project = client_project
commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_install_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: client_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gitlab_ci_yaml },
+ { file_path: 'pom.xml', content: pom_xml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
end
end
@@ -143,123 +127,57 @@ module QA
end
context 'when disabled' do
- where do
- {
- 'using a personal access token' => {
- authentication_token_type: :personal_access_token,
- maven_header_name: 'Private-Token',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347581'
- },
- 'using a project deploy token' => {
- authentication_token_type: :project_deploy_token,
- maven_header_name: 'Deploy-Token',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347584'
- },
- 'using a ci job token' => {
- authentication_token_type: :ci_job_token,
- maven_header_name: 'Job-Token',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347578'
- }
- }
+ before do
+ Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled)
end
- with_them do
- let(:token) do
- case authentication_token_type
- when :personal_access_token
- personal_access_token
- when :ci_job_token
- '${env.CI_JOB_TOKEN}'
- when :project_deploy_token
- project_deploy_token.token
- end
- end
+ it 'prevents users from publishing duplicates' do
+ create_duplicated_package
- before do
- Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled)
- end
+ push_duplicated_package
- it 'prevents users from publishing group level Maven packages duplicates', testcase: params[:testcase] do
- create_duplicated_package
-
- push_duplicated_package
-
- client_project.visit!
+ client_project.visit!
- show_latest_deploy_job
+ show_latest_deploy_job
- Page::Project::Job::Show.perform do |job|
- expect(job).not_to be_successful(timeout: 800)
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).not_to be_successful(timeout: 800)
end
end
end
context 'when enabled' do
- where do
- {
- 'using a personal access token' => {
- authentication_token_type: :personal_access_token,
- maven_header_name: 'Private-Token',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347580'
- },
- 'using a project deploy token' => {
- authentication_token_type: :project_deploy_token,
- maven_header_name: 'Deploy-Token',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347583'
- },
- 'using a ci job token' => {
- authentication_token_type: :ci_job_token,
- maven_header_name: 'Job-Token',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347577'
- }
- }
+ before do
+ Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
end
- with_them do
- let(:token) do
- case authentication_token_type
- when :personal_access_token
- personal_access_token
- when :ci_job_token
- '${env.CI_JOB_TOKEN}'
- when :project_deploy_token
- project_deploy_token.token
- end
- end
-
- before do
- Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
- end
-
- it 'allows users to publish group level Maven packages duplicates', testcase: params[:testcase] do
- create_duplicated_package
+ it 'allows users to publish duplicates' do
+ create_duplicated_package
- push_duplicated_package
+ push_duplicated_package
- show_latest_deploy_job
+ show_latest_deploy_job
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
end
end
end
def create_duplicated_package
- settings_xml_with_pat = ERB.new(read_fixture('package_managers/maven', 'settings_with_pat.xml.erb')).result(binding)
- package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
+ settings_xml_with_pat = ERB.new(read_fixture('package_managers/maven/group', 'settings_with_pat.xml.erb')).result(binding)
+ pom_xml = ERB.new(read_fixture('package_managers/maven/group/producer', 'pom.xml.erb')).result(binding)
with_fixtures([
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml_with_pat
- }
- ]) do |dir|
+ {
+ file_path: 'pom.xml',
+ content: pom_xml
+ },
+ {
+ file_path: 'settings.xml',
+ content: settings_xml_with_pat
+ }
+ ]) do |dir|
Service::DockerRun::Maven.new(dir).publish!
end
@@ -275,26 +193,18 @@ module QA
def push_duplicated_package
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
- maven_upload_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_upload_package.yaml.erb')).result(binding)
- package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
- settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
+ gitlab_ci_yaml = ERB.new(read_fixture('package_managers/maven/group/producer', 'gitlab_ci.yaml.erb')).result(binding)
+ pom_xml = ERB.new(read_fixture('package_managers/maven/group/producer', 'pom.xml.erb')).result(binding)
+ settings_xml_with_pat = ERB.new(read_fixture('package_managers/maven/group', 'settings_with_pat.xml.erb')).result(binding)
commit.project = client_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_upload_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gitlab_ci_yaml },
+ { file_path: 'pom.xml', content: pom_xml },
+ { file_path: 'settings.xml', content: settings_xml_with_pat }
+ ])
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
index 13607ba1b41..324e881f160 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
@@ -1,8 +1,14 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable do
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage, :reliable,
+ feature_flag: {
+ name: 'maven_central_request_forwarding',
+ scope: :global
+ } do
describe 'Maven project level endpoint' do
+ include Runtime::Fixtures
+
let(:group_id) { 'com.gitlab.qa' }
let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" }
let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
@@ -51,54 +57,6 @@ module QA
end
end
- let(:gitlab_ci_file) do
- {
- file_path: '.gitlab-ci.yml',
- content:
- <<~YAML
- deploy-and-install:
- image: maven:3.6-jdk-11
- script:
- - 'mvn deploy -s settings.xml'
- - 'mvn install -s settings.xml'
- only:
- - "#{package_project.default_branch}"
- tags:
- - "runner-for-#{package_project.name}"
- YAML
- }
- end
-
- let(:pom_file) do
- {
- file_path: 'pom.xml',
- content: <<~XML
- <project>
- <groupId>#{group_id}</groupId>
- <artifactId>#{artifact_id}</artifactId>
- <version>#{package_version}</version>
- <modelVersion>4.0.0</modelVersion>
- <repositories>
- <repository>
- <id>#{package_project.name}</id>
- <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/-/packages/maven</url>
- </repository>
- </repositories>
- <distributionManagement>
- <repository>
- <id>#{package_project.name}</id>
- <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/packages/maven</url>
- </repository>
- <snapshotRepository>
- <id>#{package_project.name}</id>
- <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/packages/maven</url>
- </snapshotRepository>
- </distributionManagement>
- </project>
- XML
- }
- end
-
before do
Flow::Login.sign_in_unless_signed_in
runner
@@ -142,40 +100,24 @@ module QA
end
end
- let(:settings_xml) do
- {
- file_path: 'settings.xml',
- content: <<~XML
- <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
- <servers>
- <server>
- <id>#{package_project.name}</id>
- <configuration>
- <httpHeaders>
- <property>
- <name>#{maven_header_name}</name>
- <value>#{token}</value>
- </property>
- </httpHeaders>
- </configuration>
- </server>
- </servers>
- </settings>
- XML
- }
- end
-
it 'pushes and pulls a maven package via maven', testcase: params[:testcase] do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
+ gitlab_ci_yaml = ERB.new(read_fixture('package_managers/maven/project', 'gitlab_ci.yaml.erb'))
+ .result(binding)
+ pom_xml = ERB.new(read_fixture('package_managers/maven/project', 'pom.xml.erb'))
+ .result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven/project', 'settings.xml.erb'))
+ .result(binding)
+
commit.project = package_project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- gitlab_ci_file,
- pom_file,
- settings_xml
- ])
+ commit.commit_message = 'Add files'
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gitlab_ci_yaml },
+ { file_path: 'pom.xml', content: pom_xml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
end
end
@@ -184,17 +126,7 @@ module QA
Flow::Pipeline.visit_latest_pipeline
Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
-
- job.click_element(:pipeline_path)
- end
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
+ pipeline.click_job('deploy-and-install')
end
Page::Project::Job::Show.perform do |job|
@@ -215,5 +147,107 @@ module QA
end
end
end
+
+ describe 'Maven request forwarding' do
+ include Runtime::Fixtures
+
+ let(:group_id) { 'com.gitlab.qa' }
+ let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" }
+ let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
+ let(:package_version) { '1.3.7' }
+ let(:package_type) { 'maven' }
+ let(:personal_access_token) { Runtime::Env.personal_access_token }
+ let(:group) { Resource::Group.fabricate_via_api! }
+
+ let(:gitlab_address_with_port) do
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ end
+
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = package_name
+ package.project = imported_project
+ end
+ end
+
+ let(:runner) do
+ Resource::Runner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{imported_project.name}"]
+ runner.executor = :docker
+ runner.token = group.reload!.runners_token
+ end
+ end
+
+ let(:imported_project) do
+ Resource::ProjectImportedFromURL.fabricate_via_browser_ui! do |project|
+ project.name = "#{package_type}_imported_project"
+ project.group = group
+ project.gitlab_repository_path = 'https://gitlab.com/gitlab-org/quality/imported-projects/maven.git'
+ end
+ end
+
+ before do
+ Runtime::Feature.enable(:maven_central_request_forwarding)
+ Flow::Login.sign_in_unless_signed_in
+
+ imported_project
+ runner
+ end
+
+ after do
+ Runtime::Feature.disable(:maven_central_request_forwarding)
+
+ runner.remove_via_api!
+ package.remove_via_api!
+ imported_project.remove_via_api!
+ end
+
+ it(
+ 'uses GitLab as a mirror of the central proxy',
+ :skip_live_env,
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/378221',
+ type: :investigating
+ },
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/375767'
+ ) do
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ gitlab_ci_yaml = ERB.new(read_fixture('package_managers/maven/project/request_forwarding',
+ 'gitlab_ci.yaml.erb'
+ )
+ )
+ .result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven/project/request_forwarding',
+ 'settings.xml.erb'
+ )
+ )
+ .result(binding)
+
+ commit.project = imported_project
+ commit.commit_message = 'Add files'
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gitlab_ci_yaml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
+ end
+ end
+
+ imported_project.visit!
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+ end
+ end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
index 45693ecee41..22052aa4110 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
@@ -34,20 +34,15 @@ module QA
it 'pushes and pulls a maven package via gradle', testcase: params[:testcase] do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
- gradle_upload_yaml = ERB.new(read_fixture('package_managers/maven', 'gradle_upload_package.yaml.erb')).result(binding)
- build_upload_gradle = ERB.new(read_fixture('package_managers/maven', 'build_upload.gradle.erb')).result(binding)
+ gradle_upload_yaml = ERB.new(read_fixture('package_managers/maven/gradle', 'gradle_upload_package.yaml.erb')).result(binding)
+ build_upload_gradle = ERB.new(read_fixture('package_managers/maven/gradle', 'build_upload.gradle.erb')).result(binding)
commit.project = package_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: gradle_upload_yaml
- },
- {
- file_path: 'build.gradle',
- content: build_upload_gradle
- }
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gradle_upload_yaml },
+ { file_path: 'build.gradle', content: build_upload_gradle }
])
end
end
@@ -78,21 +73,16 @@ module QA
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
- gradle_install_yaml = ERB.new(read_fixture('package_managers/maven', 'gradle_install_package.yaml.erb')).result(binding)
- build_install_gradle = ERB.new(read_fixture('package_managers/maven', 'build_install.gradle.erb')).result(binding)
+ gradle_install_yaml = ERB.new(read_fixture('package_managers/maven/gradle', 'gradle_install_package.yaml.erb')).result(binding)
+ build_install_gradle = ERB.new(read_fixture('package_managers/maven/gradle', 'build_install.gradle.erb')).result(binding)
commit.project = client_project
commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: gradle_install_yaml
- },
- {
- file_path: 'build.gradle',
- content: build_install_gradle
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gradle_install_yaml },
+ { file_path: 'build.gradle', content: build_install_gradle }
+ ])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
index f229f30facc..e2a7006249d 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
@@ -105,14 +105,7 @@ module QA
nuget_upload_yaml = ERB.new(read_fixture('package_managers/nuget', 'nuget_upload_package.yaml.erb')).result(binding)
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: nuget_upload_yaml
- }
- ]
- )
+ commit.update_files([{ file_path: '.gitlab-ci.yml', content: nuget_upload_yaml }])
end
end
@@ -137,9 +130,9 @@ module QA
commit.commit_message = 'Add new csproj file'
commit.add_files(
[
- {
- file_path: 'otherdotnet.csproj',
- content: <<~EOF
+ {
+ file_path: 'otherdotnet.csproj',
+ content: <<~EOF
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
@@ -148,18 +141,11 @@ module QA
</PropertyGroup>
</Project>
- EOF
- }
- ]
- )
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: nuget_install_yaml
- }
+ EOF
+ }
]
)
+ commit.update_files([{ file_path: '.gitlab-ci.yml', content: nuget_install_yaml }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
index e70b95db1a5..620bb7e4988 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
@@ -101,9 +101,9 @@ module QA
commit.commit_message = 'Add files'
commit.update_files(
[
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
stages:
- deploy
- install
@@ -132,11 +132,11 @@ module QA
- if: '$CI_COMMIT_BRANCH == "#{project.default_branch}"'
tags:
- "runner-for-#{project.name}"
- YAML
- },
- {
- file_path: 'dotnetcore.csproj',
- content: <<~EOF
+ YAML
+ },
+ {
+ file_path: 'dotnetcore.csproj',
+ content: <<~EOF
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
@@ -145,8 +145,8 @@ module QA
</PropertyGroup>
</Project>
- EOF
- }
+ EOF
+ }
]
)
end
diff --git a/qa/qa/specs/features/sanity/framework_spec.rb b/qa/qa/specs/features/sanity/framework_spec.rb
index feec56478c0..fa34f525a85 100644
--- a/qa/qa/specs/features/sanity/framework_spec.rb
+++ b/qa/qa/specs/features/sanity/framework_spec.rb
@@ -6,7 +6,7 @@ module QA
it 'succeeds' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
- expect(page).to have_text('A complete DevOps platform')
+ expect(page).to have_text('GitLab')
end
end
diff --git a/qa/qa/specs/qa_deprecation_toolkit_env.rb b/qa/qa/specs/qa_deprecation_toolkit_env.rb
index 21ef5a6f229..5224a2e9ae0 100644
--- a/qa/qa/specs/qa_deprecation_toolkit_env.rb
+++ b/qa/qa/specs/qa_deprecation_toolkit_env.rb
@@ -5,20 +5,24 @@ require 'deprecation_toolkit/rspec'
require 'concurrent/utility/monotonic_time'
require 'active_support/gem_version'
-module QaDeprecationToolkitEnv
- # Taken from https://github.com/jeremyevans/ruby-warning/blob/1.1.0/lib/warning.rb#L18
- # rubocop:disable Layout/LineLength
- def self.kwargs_warning
- %r{warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z}
- end
- # rubocop:enable Layout/LineLength
+module QA
+ module Specs
+ class QaDeprecationToolkitEnv
+ # Taken from https://github.com/jeremyevans/ruby-warning/blob/1.1.0/lib/warning.rb#L18
+ # rubocop:disable Layout/LineLength
+ def self.kwargs_warning
+ %r{warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z}
+ end
+ # rubocop:enable Layout/LineLength
- def self.configure!
- # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7
- Warning[:deprecated] = true
+ def self.configure!
+ # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7
+ Warning[:deprecated] = true
- DeprecationToolkit::Configuration.test_runner = :rspec
- DeprecationToolkit::Configuration.deprecation_path = 'deprecations'
- DeprecationToolkit::Configuration.warnings_treated_as_deprecation = [kwargs_warning]
+ DeprecationToolkit::Configuration.test_runner = :rspec
+ DeprecationToolkit::Configuration.deprecation_path = 'deprecations'
+ DeprecationToolkit::Configuration.warnings_treated_as_deprecation = [kwargs_warning]
+ end
+ end
end
end
diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb
index b9e67c2fa72..97901042883 100644
--- a/qa/qa/specs/spec_helper.rb
+++ b/qa/qa/specs/spec_helper.rb
@@ -2,8 +2,7 @@
require_relative '../../qa'
-require_relative 'qa_deprecation_toolkit_env'
-QaDeprecationToolkitEnv.configure!
+QA::Specs::QaDeprecationToolkitEnv.configure!
Knapsack::Adapters::RSpecAdapter.bind if QA::Runtime::Env.knapsack?
diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb
index 8fa6d3f23dc..ea19d9ef332 100644
--- a/qa/qa/support/api.rb
+++ b/qa/qa/support/api.rb
@@ -23,7 +23,7 @@ module QA
verify_ssl: false
}
- RestClient::Request.execute(default_args.merge(args))
+ RestClient::Request.execute(default_args.merge(with_canary(args)))
rescue StandardError => e
return_response_or_raise(e)
end
@@ -37,21 +37,22 @@ module QA
verify_ssl: false
}
- RestClient::Request.execute(
- default_args.merge(args)
- )
+ RestClient::Request.execute(default_args.merge(with_canary(args)))
rescue StandardError => e
return_response_or_raise(e)
end
end
- def patch(url, payload = nil)
+ def patch(url, payload = nil, args = {})
with_retry_on_too_many_requests do
- RestClient::Request.execute(
+ default_args = {
method: :patch,
url: url,
payload: payload,
- verify_ssl: false)
+ verify_ssl: false
+ }
+
+ RestClient::Request.execute(default_args.merge(with_canary(args)))
rescue StandardError => e
return_response_or_raise(e)
end
@@ -66,7 +67,7 @@ module QA
verify_ssl: false
}
- RestClient::Request.execute(default_args.merge(args))
+ RestClient::Request.execute(default_args.merge(with_canary(args)))
rescue StandardError => e
return_response_or_raise(e)
end
@@ -98,6 +99,14 @@ module QA
url.sub(/private_token=[^&]*/, "private_token=[****]")
end
+ # Merges the gitlab_canary cookie into existing cookies for mixed environment testing.
+ #
+ # @param [Hash] args the existing args passed to method
+ # @return [Hash] args or args with merged canary cookie if it exists
+ def with_canary(args)
+ args.deep_merge(cookies: QA::Runtime::Env.canary_cookie)
+ end
+
def with_retry_on_too_many_requests
response = nil
diff --git a/qa/qa/support/formatters/test_stats_formatter.rb b/qa/qa/support/formatters/test_stats_formatter.rb
index 9d19c2e8bb5..2cde2d0928e 100644
--- a/qa/qa/support/formatters/test_stats_formatter.rb
+++ b/qa/qa/support/formatters/test_stats_formatter.rb
@@ -84,6 +84,7 @@ module QA
job_url: QA::Runtime::Env.ci_job_url,
pipeline_url: env('CI_PIPELINE_URL'),
pipeline_id: env('CI_PIPELINE_ID'),
+ job_id: env('CI_JOB_ID'),
merge_request_iid: merge_request_iid
}
}
diff --git a/qa/qa/support/repeater.rb b/qa/qa/support/repeater.rb
index 6956987de05..26d447f8e0f 100644
--- a/qa/qa/support/repeater.rb
+++ b/qa/qa/support/repeater.rb
@@ -52,12 +52,13 @@ module QA
sleep_and_reload_if_needed(sleep_interval, reload_page)
attempts += 1
end
- rescue StandardError, RSpec::Expectations::ExpectationNotMetError
+ rescue StandardError, RSpec::Expectations::ExpectationNotMetError => e
raise unless retry_on_exception
attempts += 1
raise unless remaining_attempts?(attempts, max_attempts) && remaining_time?(start, max_duration)
+ QA::Runtime::Logger.debug("Retry block rescued following error: #{e}, trying again...")
sleep_and_reload_if_needed(sleep_interval, reload_page)
retry
end
diff --git a/qa/qa/tools/ci/non_empty_suites.rb b/qa/qa/tools/ci/non_empty_suites.rb
index 687c11a3e62..2319237fa25 100644
--- a/qa/qa/tools/ci/non_empty_suites.rb
+++ b/qa/qa/tools/ci/non_empty_suites.rb
@@ -10,42 +10,11 @@ module QA
class NonEmptySuites
include Helpers
- # rubocop:disable Layout/LineLength
- SCENARIOS = [
- { klass: "Test::Instance::All" },
- { klass: "Test::Instance::Smoke" },
- { klass: "Test::Instance::Reliable" },
- { klass: "Test::Instance::ReviewBlocking" },
- { klass: "Test::Instance::ReviewNonBlocking" },
- { klass: "Test::Instance::CloudActivation" },
- { klass: "Test::Instance::Integrations" },
- { klass: "Test::Instance::Jira" },
- { klass: "Test::Instance::LargeSetup" },
- { klass: "Test::Instance::Metrics" },
- { klass: "Test::Instance::ObjectStorage" },
- { klass: "Test::Instance::Packages" },
- { klass: "Test::Instance::RepositoryStorage" },
- { klass: "Test::Integration::ServicePingDisabled" },
- { klass: "Test::Integration::LDAPNoTLS" },
- { klass: "Test::Integration::LDAPTLS" },
- { klass: "Test::Integration::LDAPNoServer" },
- { klass: "Test::Integration::InstanceSAML" },
- { klass: "Test::Integration::RegistryWithCDN" },
- { klass: "Test::Integration::RegistryTLS" },
- { klass: "Test::Integration::Registry" },
- { klass: "Test::Integration::SMTP" },
- { klass: "QA::EE::Scenario::Test::Integration::Elasticsearch" },
- { klass: "QA::EE::Scenario::Test::Integration::GroupSAML" },
- {
- klass: "QA::EE::Scenario::Test::Geo",
- args: "--primary-address http://dummy1.test --primary-name gitlab-primary --secondary-address http://dummy2.test --secondary-name gitlab-secondary --without-setup"
- },
- {
- klass: "Test::Integration::Mattermost",
- args: "--mattermost-address http://mattermost.test"
- }
+ # @return [Array] scenarios that never run in package-and-test pipeline
+ IGNORED_SCENARIOS = [
+ "QA::EE::Scenario::Test::Geo",
+ "QA::Scenario::Test::Instance::Airgapped"
].freeze
- # rubocop:enable Layout/LineLength
def initialize(qa_tests)
@qa_tests = qa_tests
@@ -56,38 +25,58 @@ module QA
# @return [String]
def fetch
logger.info("Checking for runnable suites")
- scenarios = SCENARIOS.each_with_object([]) do |scenario, runnable_scenarios|
- logger.info(" fetching runnable specs for '#{scenario[:klass]}'")
+ scenarios.each_with_object([]) do |scenario, runnable_scenarios|
+ logger.info(" fetching runnable specs for '#{scenario}'")
+ next logger.info(" scenario is in ignore list, skipping") if IGNORED_SCENARIOS.include?(scenario)
- out, err, status = run_command(**scenario)
+ out, err, status = run_command(scenario)
unless status.success?
- logger.error(" example count failed!\n#{err}")
+ logger.error(" example count failed!\n#{err}")
next
end
count = out.split("\n").last.to_i
logger.info(" found #{count} examples to run")
- runnable_scenarios << scenario[:klass] if count > 0
- end
-
- scenarios.join(",")
+ runnable_scenarios << scenario if count > 0
+ end.join(",")
end
private
attr_reader :qa_tests
+ # Get all defined scenarios
+ #
+ # @return [Array<String>]
+ def scenarios
+ foss_scenarios = scenario_classes(QA::Scenario::Test)
+ return foss_scenarios unless QA.const_defined?("QA::EE")
+
+ foss_scenarios + scenario_classes(QA::EE::Scenario::Test)
+ end
+
+ # Fetch scenario classes recursively
+ #
+ # @param [Module] mod
+ # @return [Array<String>]
+ def scenario_classes(mod)
+ mod.constants.map do |const|
+ c = mod.const_get(const, false)
+ next c.to_s if c.is_a?(Class)
+
+ scenario_classes(c)
+ end.flatten
+ end
+
# Run scenario count command
#
# @param [String] klass
- # @param [String] args
# @return [String]
- def run_command(klass:, args: nil)
+ def run_command(klass)
cmd = ["bundle exec bin/qa"]
cmd << klass
cmd << "--count-examples-only --address http://dummy1.test"
- cmd << args if args
cmd << "-- #{qa_tests}" unless qa_tests.blank?
Open3.capture3(cmd.join(" "))
diff --git a/qa/qa/tools/ci/qa_changes.rb b/qa/qa/tools/ci/qa_changes.rb
index 75274961efe..784923714d6 100644
--- a/qa/qa/tools/ci/qa_changes.rb
+++ b/qa/qa/tools/ci/qa_changes.rb
@@ -11,17 +11,25 @@ module QA
QA_PATTERN = %r{^qa/}.freeze
SPEC_PATTERN = %r{^qa/qa/specs/features/}.freeze
-
- def initialize(mr_diff, mr_labels)
+ DEPENDENCY_PATTERN = Regexp.union(
+ /_VERSION/,
+ /Gemfile\.lock/,
+ /yarn\.lock/,
+ /Dockerfile\.assets/
+ )
+
+ def initialize(mr_diff, mr_labels, additional_group_spec_list)
@mr_diff = mr_diff
@mr_labels = mr_labels
+ @additional_group_spec_list = additional_group_spec_list
end
# Specific specs to run
#
# @return [String]
def qa_tests
- return if mr_diff.empty?
+ return if mr_diff.empty? || dependency_changes
+
# make paths relative to qa directory
return changed_files&.map { |path| path.delete_prefix("qa/") }&.join(" ") if only_spec_changes?
return qa_spec_directories_for_devops_stage&.join(" ") if non_qa_changes? && mr_labels.any?
@@ -73,6 +81,9 @@ module QA
# @return [Array]
attr_reader :mr_labels
+ # @return [Hash<String, Array<String>>]
+ attr_reader :additional_group_spec_list
+
# Are the changed files only qa specs?
#
# @return [Boolean] whether the changes files are only qa specs
@@ -94,6 +105,13 @@ module QA
mr_labels.find { |label| label =~ /^devops::/ }&.delete_prefix('devops::')
end
+ # Extract group name from MR labels
+ #
+ # @return [String] a group name
+ def group_name_from_mr_labels
+ mr_labels.find { |label| label =~ /^group::/ }&.delete_prefix('group::')
+ end
+
# Get qa spec directories for devops stage
#
# @return [Array] qa spec directories
@@ -101,14 +119,37 @@ module QA
devops_stage = devops_stage_from_mr_labels
return unless devops_stage
- Dir.glob("qa/specs/**/*/").select { |dir| dir =~ %r{\d+_#{devops_stage}/$} }
+ spec_dirs = stage_specs(devops_stage)
+
+ grp_name = group_name_from_mr_labels
+ return spec_dirs if grp_name.nil?
+
+ additional_grp_specs = additional_group_spec_list[grp_name]
+ return spec_dirs if additional_grp_specs.nil?
+
+ spec_dirs + stage_specs(*additional_grp_specs)
+ end
+
+ # Changes to gitlab dependencies
+ #
+ # @return [Boolean]
+ def dependency_changes
+ changed_files.any? { |file| file.match?(DEPENDENCY_PATTERN) }
end
# Change files in merge request
#
# @return [Array<String>]
def changed_files
- @changed_files ||= mr_diff.map { |change| change[:path] } # rubocop:disable Rails/Pluck
+ @changed_files ||= mr_diff.map { |change| change[:path] }
+ end
+
+ # Devops stage specs
+ #
+ # @param [Array<String>] devops_stages
+ # @return [Array]
+ def stage_specs(*devops_stages)
+ Dir.glob("qa/specs/**/*/").select { |dir| dir =~ %r{\d+_(#{devops_stages.join('|')})/$} }
end
end
end
diff --git a/qa/qa/tools/delete_test_ssh_keys.rb b/qa/qa/tools/delete_test_ssh_keys.rb
index 9e5728a5509..c10188eae6d 100644
--- a/qa/qa/tools/delete_test_ssh_keys.rb
+++ b/qa/qa/tools/delete_test_ssh_keys.rb
@@ -12,7 +12,7 @@
module QA
module Tools
- class DeleteTestSSHKeys
+ class DeleteTestSshKeys
include Support::API
ITEMS_PER_PAGE = '100'
diff --git a/qa/qa/tools/initialize_gitlab_auth.rb b/qa/qa/tools/initialize_gitlab_auth.rb
index 18e90f0d739..6d586f95ecf 100644
--- a/qa/qa/tools/initialize_gitlab_auth.rb
+++ b/qa/qa/tools/initialize_gitlab_auth.rb
@@ -6,7 +6,7 @@ module QA
# Also creates a personal access token
# @example
# $ bundle exec rake 'initialize_gitlab_auth[http://gitlab.test]'
- class InitializeGitLabAuth
+ class InitializeGitlabAuth
attr_reader :address
def initialize(address:)
diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb
index 60c6dbfc16c..068fe37a37b 100644
--- a/qa/qa/tools/test_resources_handler.rb
+++ b/qa/qa/tools/test_resources_handler.rb
@@ -25,13 +25,17 @@ module QA
module Tools
class TestResourcesHandler
include Support::API
-
- IGNORED_RESOURCES = [
- 'QA::Resource::CiVariable',
- 'QA::Resource::Repository::Commit',
- 'QA::EE::Resource::GroupIteration',
- 'QA::EE::Resource::Settings::Elasticsearch',
- 'QA::EE::Resource::VulnerabilityItem'
+ include Ci::Helpers
+
+ IGNORED_RESOURCES = %w[
+ QA::Resource::CiVariable
+ QA::Resource::Repository::Commit
+ QA::Resource::Design
+ QA::EE::Resource::GroupIteration
+ QA::EE::Resource::Settings::Elasticsearch
+ QA::EE::Resource::VulnerabilityItem
+ QA::EE::Resource::ScanResultPolicyProject
+ QA::EE::Resource::ScanResultPolicyCommit
].freeze
PROJECT = 'gitlab-qa-resources'
@@ -44,10 +48,19 @@ module QA
def run_delete
failures = files.flat_map do |file|
resources = read_file(file)
- next if resources.nil?
+ if resources.nil?
+ logger.info("#{file} is empty, next...")
+ next
+ end
filtered_resources = filter_resources(resources)
+ if filtered_resources.nil?
+ logger.info("No resources left to delete after filtering!")
+ next
+ end
+
delete_resources(filtered_resources)
+ delete_groups_permanently(filtered_resources['QA::Resource::Group'])
end
return puts "\nDone" if failures.empty?
@@ -62,17 +75,15 @@ module QA
# E.g: staging/failed-test-resources-<randomhex>.json
def upload(ci_project_name)
if files.empty?
- puts "\nNothing to upload!"
- exit 0
+ logger.info("\nNothing to upload!")
+ return
end
files.each do |file|
file_name = "#{ci_project_name}/#{file.split('/').last}"
- Runtime::Logger.info("Uploading #{file_name}...")
+ logger.info("Uploading #{file_name}...")
gcs_storage.put_object(BUCKET, file_name, File.read(file))
end
-
- puts "\nDone"
end
# Download files from GCS bucket by environment name
@@ -85,40 +96,38 @@ module QA
end
if files_list.blank?
- puts "\nNothing to download!"
- exit 0
+ logger.info("\nNothing to download!")
+ return
end
FileUtils.mkdir_p('tmp/')
files_list.each do |file_name|
local_path = "tmp/#{file_name.split('/').last}"
- Runtime::Logger.info("Downloading #{file_name} to #{local_path}")
+ logger.info("Downloading #{file_name} to #{local_path}")
file = gcs_storage.get_object(BUCKET, file_name)
File.write(local_path, file[:body])
- Runtime::Logger.info("Deleting #{file_name} from bucket")
+ logger.info("Deleting #{file_name} from bucket")
gcs_storage.delete_object(BUCKET, file_name)
end
-
- puts "\nDone"
end
private
def files
- Runtime::Logger.info('Gathering JSON files...')
+ logger.info('Gathering JSON files...')
files = Dir.glob(@file_pattern)
if files.empty?
- puts "There is no file with this pattern #{@file_pattern}"
+ logger.info("There is no file with this pattern #{@file_pattern}")
exit 0
end
files.reject! { |file| File.zero?(file) }
if files.empty?
- puts "\nAll files were empty and rejected, nothing more to do!"
+ logger.info("\nAll files were empty and rejected, nothing more to do!")
exit 0
end
@@ -126,14 +135,15 @@ module QA
end
def read_file(file)
+ logger.info("Reading and processing #{file}...")
JSON.parse(File.read(file))
rescue JSON::ParserError
- Runtime::Logger.error("Failed to read #{file} - Invalid format")
+ logger.error("Failed to read #{file} - Invalid format")
nil
end
def filter_resources(resources)
- Runtime::Logger.info('Filtering resources - Only keep deletable resources...')
+ logger.info('Filtering resources - Only keep deletable resources...')
transformed_values = resources.transform_values! do |v|
v.reject do |attributes|
@@ -147,28 +157,55 @@ module QA
end
def delete_resources(resources)
- if resources.nil?
- puts "\nNo resources left to delete after filtering!"
- exit 0
- end
-
resources.each_with_object([]) do |(key, value), failures|
value.each do |resource|
- next if resource_not_found?(resource['api_path'])
-
resource_info = resource['info'] ? "#{key} - #{resource['info']}" : "#{key} at #{resource['api_path']}"
+ logger.info("Processing #{resource_info}...")
+
+ if resource_not_found?(resource['api_path'])
+ logger.info("#{resource['api_path']} returns 404, next...")
+ next
+ end
+
delete_response = delete(Runtime::API::Request.new(api_client, resource['api_path']).url)
if delete_response.code == 202 || delete_response.code == 204
- Runtime::Logger.info("Deleting #{resource_info}... SUCCESS")
+ if key == 'QA::Resource::Group' && !resource_not_found?(resource['api_path'])
+ logger.info("Successfully marked #{resource_info} for deletion...")
+ else
+ logger.info("Deleting #{resource_info}... \e[32mSUCCESS\e[0m")
+ end
else
- Runtime::Logger.info("Deleting #{resource_info}... FAILED - #{delete_response}")
- failures << resource_info
+ logger.info("Deleting #{resource_info}... \e[31mFAILED - #{delete_response}\e[0m")
+ # We might try to delete some groups already marked for deletion, it's fine to ignore these failures
+ failures << resource_info unless key == 'QA::Resource::Group'
end
end
end
end
+ def delete_groups_permanently(groups)
+ groups.each_with_object([]) do |group, failures|
+ logger.info("Processing QA::Resource::Group #{group['info']}...")
+
+ if resource_not_found?(group['api_path'])
+ logger.info("#{group['api_path']} returns 404, next...")
+ next
+ end
+
+ permanent_delete_path = "#{group['api_path']}?permanently_remove=true"\
+ "&full_path=#{group['info'].split("'").last}"
+ response = delete(Runtime::API::Request.new(api_client, permanent_delete_path).url)
+
+ if response.code == 202
+ logger.info("Permanently deleting group #{group['info']}... \e[32mSUCCESS\e[0m")
+ else
+ logger.info("Permanently deleting group #{group['info']}... \e[31mFAILED - #{response}\e[0m")
+ failures << "QA::Resource::Group #{group['info']}"
+ end
+ end
+ end
+
def resource_not_found?(api_path)
# if api path contains param "?hard_delete=<boolean>", remove it
get(Runtime::API::Request.new(api_client, api_path.split('?').first).url).code.eql? 404
diff --git a/qa/qa/vendor/jira/jira_issue_page.rb b/qa/qa/vendor/jira/jira_issue_page.rb
new file mode 100644
index 00000000000..5f5449513ff
--- /dev/null
+++ b/qa/qa/vendor/jira/jira_issue_page.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'capybara/dsl'
+
+module QA
+ module Vendor
+ module Jira
+ class JiraIssuePage < JiraAPI
+ include Capybara::DSL
+ include Scenario::Actable
+
+ def login(username, password)
+ QA::Runtime::Logger.debug("Logging into JIRA with username: #{username} and password:#{password}")
+
+ fill_in 'login-form-username', with: username
+ fill_in 'login-form-password', with: password
+ click_on 'login-form-submit'
+ end
+
+ def go_to_login_page
+ click_on 'log in'
+ end
+
+ def login_if_required(username, password)
+ return unless login_required?
+
+ go_to_login_page
+ login(username, password)
+ end
+
+ def summary_field
+ page.find('#summary').value
+ end
+
+ def issue_description
+ page.find('#description', visible: false).value
+ end
+
+ def login_required?
+ login_required = page.has_text?('You are not logged in')
+ QA::Runtime::Logger.debug("login_required: #{login_required}")
+ login_required
+ end
+ end
+ end
+ end
+end
diff --git a/qa/spec/resource/user_spec.rb b/qa/spec/resource/user_spec.rb
index c0140abf298..d82dcc3b21e 100644
--- a/qa/spec/resource/user_spec.rb
+++ b/qa/spec/resource/user_spec.rb
@@ -23,8 +23,8 @@ RSpec.describe QA::Resource::User do
end
describe '#password' do
- it 'generates a random 16 character password by default' do
- expect(subject.password).to match(/\w{16}/)
+ it 'generates a default password' do
+ expect(subject.password).to match('Pa$$w0rd')
end
it 'is possible to set the password' do
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index a41d7385c41..61d91da8738 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -339,4 +339,35 @@ RSpec.describe QA::Runtime::Env do
end
end
end
+
+ describe '.canary_cookie' do
+ subject { described_class.canary_cookie }
+
+ context 'with QA_COOKIES set' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:cookie_value, :result) do
+ 'gitlab_canary=true' | { gitlab_canary: "true" }
+ 'other_cookie=value\;gitlab_canary=true' | { gitlab_canary: "true" }
+ 'gitlab_canary=false' | { gitlab_canary: "false" }
+ 'gitlab_canary=false\;other_cookie=value' | { gitlab_canary: "false" }
+ end
+
+ with_them do
+ before do
+ stub_env('QA_COOKIES', cookie_value)
+ end
+
+ it { is_expected.to eq(result) }
+ end
+ end
+
+ context 'without QA_COOKIES set' do
+ before do
+ stub_env('QA_COOKIES', nil)
+ end
+
+ it { is_expected.to be_empty }
+ end
+ end
end
diff --git a/qa/spec/scenario/test/integration/github_spec.rb b/qa/spec/scenario/test/integration/github_spec.rb
deleted file mode 100644
index 4ad42b4f5cc..00000000000
--- a/qa/spec/scenario/test/integration/github_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe QA::Scenario::Test::Integration::Github do
- describe '#perform' do
- let(:env) { spy('Runtime::Env', knapsack?: false, dry_run: false) }
-
- before do
- stub_const('QA::Runtime::Env', env)
- end
-
- it_behaves_like 'a QA scenario class' do
- let(:tags) { [:github] }
-
- it 'requires a GitHub access token' do
- subject.perform(args)
-
- expect(env).to have_received(:require_github_access_token!)
- end
- end
- end
-end
diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_stats_formatter_spec.rb
index ba59588d186..d0d89b5ee73 100644
--- a/qa/spec/support/formatters/test_stats_formatter_spec.rb
+++ b/qa/spec/support/formatters/test_stats_formatter_spec.rb
@@ -15,6 +15,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
let(:ci_job_url) { 'url' }
let(:ci_pipeline_url) { 'url' }
let(:ci_pipeline_id) { '123' }
+ let(:ci_job_id) { '321' }
let(:run_type) { 'staging-full' }
let(:smoke) { 'false' }
let(:reliable) { 'false' }
@@ -64,6 +65,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
job_url: ci_job_url,
pipeline_url: ci_pipeline_url,
pipeline_id: ci_pipeline_id,
+ job_id: ci_job_id,
merge_request_iid: nil
}
}
@@ -80,7 +82,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
around do |example|
RSpec::Core::Sandbox.sandboxed do |config|
- config.formatter = QA::Support::Formatters::TestStatsFormatter
+ config.formatter = described_class
config.before(:context) { RSpec.current_example = nil }
example.run
@@ -125,6 +127,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
stub_env('CI_JOB_NAME', ci_job_name)
stub_env('CI_PIPELINE_URL', ci_pipeline_url)
stub_env('CI_PIPELINE_ID', ci_pipeline_id)
+ stub_env('CI_JOB_ID', ci_job_id)
stub_env('CI_MERGE_REQUEST_IID', nil)
stub_env('TOP_UPSTREAM_MERGE_REQUEST_IID', nil)
stub_env('QA_RUN_TYPE', run_type)
diff --git a/qa/spec/tools/ci/non_empty_suites_spec.rb b/qa/spec/tools/ci/non_empty_suites_spec.rb
index d9bfe1eebe7..f71e07aa4b4 100644
--- a/qa/spec/tools/ci/non_empty_suites_spec.rb
+++ b/qa/spec/tools/ci/non_empty_suites_spec.rb
@@ -9,11 +9,11 @@ RSpec.describe QA::Tools::Ci::NonEmptySuites do
allow(Gitlab::QA::TestLogger).to receive(:logger).and_return(Logger.new(StringIO.new))
allow(Open3).to receive(:capture3).and_return(["output\n0", "", status])
allow(Open3).to receive(:capture3)
- .with("bundle exec bin/qa Test::Instance::All --count-examples-only --address http://dummy1.test")
+ .with("bundle exec bin/qa QA::Scenario::Test::Instance::All --count-examples-only --address http://dummy1.test")
.and_return(["output\n1", "", status])
end
it "returns runnable test suites" do
- expect(non_empty_suites.fetch).to eq("Test::Instance::All")
+ expect(non_empty_suites.fetch).to eq("QA::Scenario::Test::Instance::All")
end
end
diff --git a/qa/spec/tools/ci/qa_changes_spec.rb b/qa/spec/tools/ci/qa_changes_spec.rb
index bc98ec16d7f..d93d3cd9258 100644
--- a/qa/spec/tools/ci/qa_changes_spec.rb
+++ b/qa/spec/tools/ci/qa_changes_spec.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
RSpec.describe QA::Tools::Ci::QaChanges do
- subject(:qa_changes) { described_class.new(mr_diff, mr_labels) }
+ subject(:qa_changes) { described_class.new(mr_diff, mr_labels, additional_group_spec_list) }
let(:mr_labels) { [] }
+ let(:additional_group_spec_list) { [] }
before do
allow(File).to receive(:directory?).and_return(false)
@@ -35,7 +36,7 @@ RSpec.describe QA::Tools::Ci::QaChanges do
context "with framework changes" do
let(:mr_diff) { [{ path: "qa/qa.rb" }] }
- it ".qa_tests do not return specifix specs" do
+ it ".qa_tests do not return specific specs" do
expect(qa_changes.qa_tests).to be_nil
end
@@ -75,6 +76,43 @@ RSpec.describe QA::Tools::Ci::QaChanges do
)
end
end
+
+ context "when configured to run tests from other stages" do
+ let(:additional_group_spec_list) do
+ {
+ 'foo' => %w[create],
+ 'bar' => %w[monitor verify]
+ }
+ end
+
+ context "with a single extra stage configured for the group name" do
+ let(:mr_labels) { %w[devops::manage group::foo] }
+
+ it ".qa_tests return specs for both devops stage and create stage" do
+ expect(qa_changes.qa_tests.split(" ")).to include(
+ "qa/specs/features/browser_ui/1_manage/",
+ "qa/specs/features/api/1_manage/",
+ "qa/specs/features/browser_ui/3_create/",
+ "qa/specs/features/api/3_create/"
+ )
+ end
+ end
+
+ context "with a multiple extra stages configured for the group name" do
+ let(:mr_labels) { %w[devops::manage group::bar] }
+
+ it ".qa_tests return specs for both devops stage and multiple other stages" do
+ expect(qa_changes.qa_tests.split(" ")).to include(
+ "qa/specs/features/browser_ui/1_manage/",
+ "qa/specs/features/api/1_manage/",
+ "qa/specs/features/browser_ui/8_monitor/",
+ "qa/specs/features/api/8_monitor/",
+ "qa/specs/features/browser_ui/4_verify/",
+ "qa/specs/features/api/4_verify/"
+ )
+ end
+ end
+ end
end
context "with quarantine changes" do
@@ -84,4 +122,14 @@ RSpec.describe QA::Tools::Ci::QaChanges do
expect(qa_changes.quarantine_changes?).to eq(true)
end
end
+
+ %w[GITALY_SERVER_VERSION Gemfile.lock yarn.lock Dockerfile.assets].each do |dependency_file|
+ context "when #{dependency_file} change" do
+ let(:mr_diff) { [{ path: dependency_file }] }
+
+ it ".qa_tests do not return specific specs" do
+ expect(qa_changes.qa_tests).to be_nil
+ end
+ end
+ end
end
diff --git a/qa/spec/tools/reliable_report_spec.rb b/qa/spec/tools/reliable_report_spec.rb
index d5c898779b8..f08af8a717a 100644
--- a/qa/spec/tools/reliable_report_spec.rb
+++ b/qa/spec/tools/reliable_report_spec.rb
@@ -145,7 +145,8 @@ describe QA::Tools::ReliableReport do
let(:common_api_args) do
{
verify_ssl: false,
- headers: { "PRIVATE-TOKEN" => "gitlab_token" }
+ headers: { "PRIVATE-TOKEN" => "gitlab_token" },
+ cookies: {}
}
end
diff --git a/qa/tasks/ci.rake b/qa/tasks/ci.rake
index 44a794d9f94..435fe8ebb77 100644
--- a/qa/tasks/ci.rake
+++ b/qa/tasks/ci.rake
@@ -13,8 +13,10 @@ namespace :ci do
diff = mr_diff
labels = mr_labels
+ # Assign mapping of groups to tests in stages other than the groups defined stage
+ additional_group_spec_list = { 'gitaly' => %w[create] }
- qa_changes = QA::Tools::Ci::QaChanges.new(diff, labels)
+ qa_changes = QA::Tools::Ci::QaChanges.new(diff, labels, additional_group_spec_list)
logger = qa_changes.logger
logger.info("Analyzing merge request changes")