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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-20 14:43:17 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-20 14:43:17 +0300
commitdfc94207fec2d84314b1a5410cface22e8b369bd (patch)
treec54022f61ced104305889a64de080998a0dc773b /qa
parentb874efeff674f6bf0355d5d242ecf81c6f7155df (diff)
Add latest changes from gitlab-org/gitlab@15-11-stable-eev15.11.0-rc42
Diffstat (limited to 'qa')
-rw-r--r--qa/Dockerfile7
-rw-r--r--qa/Gemfile14
-rw-r--r--qa/Gemfile.lock30
-rw-r--r--qa/README.md41
-rwxr-xr-xqa/gdk/launch2
-rw-r--r--qa/qa.rb3
-rw-r--r--qa/qa/ce/strategy.rb3
-rw-r--r--qa/qa/flow/pipeline.rb4
-rw-r--r--qa/qa/flow/user_onboarding.rb2
-rw-r--r--qa/qa/page/admin/applications.rb70
-rw-r--r--qa/qa/page/admin/menu.rb68
-rw-r--r--qa/qa/page/admin/sidebar/overview.rb25
-rw-r--r--qa/qa/page/admin/sidebar/settings.rb41
-rw-r--r--qa/qa/page/base.rb11
-rw-r--r--qa/qa/page/component/breadcrumbs.rb2
-rw-r--r--qa/qa/page/component/content_editor.rb2
-rw-r--r--qa/qa/page/component/groups_filter.rb3
-rw-r--r--qa/qa/page/component/snippet.rb2
-rw-r--r--qa/qa/page/dashboard/snippet/index.rb13
-rw-r--r--qa/qa/page/file/show.rb2
-rw-r--r--qa/qa/page/group/menu.rb12
-rw-r--r--qa/qa/page/group/sub_menus/super_sidebar/build.rb25
-rw-r--r--qa/qa/page/group/sub_menus/super_sidebar/main.rb27
-rw-r--r--qa/qa/page/main/login.rb20
-rw-r--r--qa/qa/page/main/menu.rb71
-rw-r--r--qa/qa/page/merge_request/show.rb10
-rw-r--r--qa/qa/page/profile/menu.rb12
-rw-r--r--qa/qa/page/profile/super_sidebar/menu.rb31
-rw-r--r--qa/qa/page/project/import/github.rb22
-rw-r--r--qa/qa/page/project/import/repo_by_url.rb9
-rw-r--r--qa/qa/page/project/issue/new.rb2
-rw-r--r--qa/qa/page/project/issue/show.rb4
-rw-r--r--qa/qa/page/project/job/show.rb4
-rw-r--r--qa/qa/page/project/menu.rb22
-rw-r--r--qa/qa/page/project/pipeline/show.rb2
-rw-r--r--qa/qa/page/project/settings/branch_rules.rb33
-rw-r--r--qa/qa/page/project/settings/branch_rules_details.rb35
-rw-r--r--qa/qa/page/project/settings/ci_variables.rb9
-rw-r--r--qa/qa/page/project/settings/deploy_keys.rb1
-rw-r--r--qa/qa/page/project/settings/main.rb1
-rw-r--r--qa/qa/page/project/settings/repository.rb8
-rw-r--r--qa/qa/page/project/show.rb27
-rw-r--r--qa/qa/page/project/sub_menus/ci_cd.rb2
-rw-r--r--qa/qa/page/project/sub_menus/common.rb2
-rw-r--r--qa/qa/page/project/sub_menus/create_new_menu.rb54
-rw-r--r--qa/qa/page/project/sub_menus/issues.rb4
-rw-r--r--qa/qa/page/project/sub_menus/packages.rb2
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/build.rb49
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/code.rb49
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/main.rb27
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/monitor.rb45
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/operate.rb37
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/plan.rb25
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/secure.rb25
-rw-r--r--qa/qa/page/project/sub_menus/super_sidebar/settings.rb41
-rw-r--r--qa/qa/page/project/tag/show.rb5
-rw-r--r--qa/qa/page/project/web_ide/edit.rb2
-rw-r--r--qa/qa/page/project/web_ide/vscode.rb2
-rw-r--r--qa/qa/page/registration/welcome.rb2
-rw-r--r--qa/qa/page/sub_menus/common.rb51
-rw-r--r--qa/qa/page/sub_menus/create_new_menu.rb41
-rw-r--r--qa/qa/page/sub_menus/super_sidebar/context_switcher.rb46
-rw-r--r--qa/qa/page/sub_menus/super_sidebar/main.rb21
-rw-r--r--qa/qa/page/sub_menus/super_sidebar/manage.rb35
-rw-r--r--qa/qa/page/sub_menus/super_sidebar/plan.rb31
-rw-r--r--qa/qa/page/sub_menus/super_sidebar/settings.rb43
-rw-r--r--qa/qa/resource/api_fabricator.rb25
-rw-r--r--qa/qa/resource/ci_variable.rb13
-rw-r--r--qa/qa/resource/events/project.rb10
-rw-r--r--qa/qa/resource/group.rb4
-rw-r--r--qa/qa/resource/instance_oauth_application.rb49
-rw-r--r--qa/qa/resource/issue.rb2
-rw-r--r--qa/qa/resource/pipeline.rb2
-rw-r--r--qa/qa/resource/project.rb5
-rw-r--r--qa/qa/resource/project_imported_from_github.rb4
-rw-r--r--qa/qa/resource/runner_base.rb3
-rw-r--r--qa/qa/resource/snippet.rb4
-rw-r--r--qa/qa/runtime/application_settings.rb3
-rw-r--r--qa/qa/runtime/browser.rb44
-rw-r--r--qa/qa/runtime/env.rb74
-rw-r--r--qa/qa/service/docker_run/base.rb4
-rw-r--r--qa/qa/service/docker_run/gitlab.rb35
-rw-r--r--qa/qa/service/docker_run/gitlab_runner.rb15
-rw-r--r--qa/qa/service/docker_run/k3s.rb3
-rw-r--r--qa/qa/specs/features/api/1_manage/group_access_token_spec.rb6
-rw-r--r--qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb6
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb10
-rw-r--r--qa/qa/specs/features/api/1_manage/project_access_token_spec.rb6
-rw-r--r--qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb21
-rw-r--r--qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb (renamed from qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb)20
-rw-r--r--qa/qa/specs/features/api/9_data_stores/users_spec.rb (renamed from qa/qa/specs/features/api/1_manage/users_spec.rb)10
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb16
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/login_via_oidc_with_gitlab_as_idp_spec.rb113
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_github_spec.rb18
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb42
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb74
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb15
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb45
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_new/add_new_directory_in_web_ide_spec.rb73
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb287
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb148
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb51
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb100
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb78
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb (renamed from qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident.rb)7
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/group/group_member_access_request_spec.rb)8
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb)10
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb)2
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb)12
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb)2
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb)4
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb)23
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb)4
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb)21
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb)20
-rw-r--r--qa/qa/specs/features/shared_contexts/import/gitlab_group_migration_common.rb2
-rw-r--r--qa/qa/specs/features/shared_contexts/sends_and_resolves_test_alerts.rb2
-rw-r--r--qa/qa/specs/spec_helper.rb2
-rw-r--r--qa/qa/support/matchers/have_matcher.rb1
-rw-r--r--qa/qa/support/page/logging.rb4
-rw-r--r--qa/qa/support/wait_for_requests.rb6
-rw-r--r--qa/qa/tools/test_resources_handler.rb2
-rw-r--r--qa/qa/vendor/github/page/base.rb14
-rw-r--r--qa/qa/vendor/github/page/login.rb36
-rw-r--r--qa/qa/vendor/one_password/cli.rb59
-rw-r--r--qa/tasks/ci.rake2
-rw-r--r--qa/tasks/webdrivers.rake1
155 files changed, 2147 insertions, 1038 deletions
diff --git a/qa/Dockerfile b/qa/Dockerfile
index 6efc8ac09fa..2bf668abc49 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -22,6 +22,13 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*
##
+# Install 1Password CLI
+#
+RUN wget -P /tmp/ https://downloads.1password.com/linux/debian/$(dpkg --print-architecture)/stable/1password-cli-$(dpkg --print-architecture)-latest.deb
+RUN dpkg -i /tmp/1password-cli-$(dpkg --print-architecture)-latest.deb
+RUN op --version
+
+##
# Install root certificate
#
RUN mkdir -p /usr/share/ca-certificates/gitlab
diff --git a/qa/Gemfile b/qa/Gemfile
index 9e35c619c5b..abb654b4a96 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,26 +2,26 @@
source 'https://rubygems.org'
-gem 'gitlab-qa', '~> 9', '>= 9.1.2', require: 'gitlab/qa'
+gem 'gitlab-qa', '~> 10', '>= 10.3.0', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.7.2' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.20.0'
-gem 'capybara', '~> 3.38.0'
+gem 'capybara', '~> 3.39.0'
gem 'capybara-screenshot', '~> 1.0.26'
gem 'rake', '~> 13', '>= 13.0.6'
gem 'rspec', '~> 3.12'
-gem 'selenium-webdriver', '~> 4.8', '>= 4.8.1'
+gem 'selenium-webdriver', '~> 4.8', '>= 4.8.6'
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.2', require: 'rspec/retry'
gem 'rspec_junit_formatter', '~> 0.6.0'
-gem 'faker', '~> 3.1', '>= 3.1.1'
+gem 'faker', '~> 3.2'
gem 'knapsack', '~> 4.0'
gem 'parallel_tests', '~> 4.2'
gem 'rotp', '~> 6.2.2'
-gem 'parallel', '~> 1.22', '>= 1.22.1'
+gem 'parallel', '~> 1.23'
gem 'rainbow', '~> 3.1.1'
gem 'rspec-parameterized', '~> 1.0.0'
-gem 'octokit', '~> 6.1.0'
+gem 'octokit', '~> 6.1.1'
gem "faraday-retry", "~> 2.1"
gem 'webdrivers', '~> 5.2'
gem 'zeitwerk', '~> 2.6', '>= 2.6.7'
@@ -38,7 +38,7 @@ gem 'chemlab', '~> 0.10'
gem 'chemlab-library-www-gitlab-com', '~> 0.1', '>= 0.1.1'
# dependencies for jenkins client
-gem 'nokogiri', '~> 1.14', '>= 1.14.2'
+gem 'nokogiri', '~> 1.14', '>= 1.14.3'
gem 'deprecation_toolkit', '~> 2.0.3', require: false
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index c3faf5841fc..e86a5526fc8 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -29,7 +29,7 @@ GEM
debug_inspector (>= 0.0.1)
builder (3.2.4)
byebug (11.1.3)
- capybara (3.38.0)
+ capybara (3.39.0)
addressable
matrix
mini_mime (>= 0.1.3)
@@ -63,7 +63,7 @@ GEM
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
excon (0.92.4)
- faker (3.1.1)
+ faker (3.2.0)
i18n (>= 1.8.11, < 2)
faraday (2.5.2)
faraday-net_http (>= 2.0, < 3.1)
@@ -102,7 +102,7 @@ GEM
gitlab (4.18.0)
httparty (~> 0.18)
terminal-table (>= 1.5.1)
- gitlab-qa (9.1.2)
+ gitlab-qa (10.3.0)
activesupport (~> 6.1)
gitlab (~> 4.18.0)
http (~> 5.0)
@@ -181,15 +181,15 @@ GEM
multi_json (1.15.0)
multi_xml (0.6.0)
netrc (0.11.0)
- nokogiri (1.14.2)
+ nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
- octokit (6.1.0)
+ octokit (6.1.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
oj (3.13.23)
os (1.1.4)
- parallel (1.22.1)
+ parallel (1.23.0)
parallel_tests (4.2.0)
parallel
parser (3.1.3.0)
@@ -260,7 +260,7 @@ GEM
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
- selenium-webdriver (4.8.1)
+ selenium-webdriver (4.8.6)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
@@ -308,22 +308,22 @@ DEPENDENCIES
activesupport (~> 6.1.7.2)
airborne (~> 0.3.7)
allure-rspec (~> 2.20.0)
- capybara (~> 3.38.0)
+ capybara (~> 3.39.0)
capybara-screenshot (~> 1.0.26)
chemlab (~> 0.10)
chemlab-library-www-gitlab-com (~> 0.1, >= 0.1.1)
confiner (~> 0.4)
deprecation_toolkit (~> 2.0.3)
- faker (~> 3.1, >= 3.1.1)
+ faker (~> 3.2)
faraday-retry (~> 2.1)
fog-core (= 2.1.0)
fog-google (~> 1.19)
- gitlab-qa (~> 9, >= 9.1.2)
+ gitlab-qa (~> 10, >= 10.3.0)
influxdb-client (~> 2.9)
knapsack (~> 4.0)
- nokogiri (~> 1.14, >= 1.14.2)
- octokit (~> 6.1.0)
- parallel (~> 1.22, >= 1.22.1)
+ nokogiri (~> 1.14, >= 1.14.3)
+ octokit (~> 6.1.1)
+ parallel (~> 1.23)
parallel_tests (~> 4.2)
pry-byebug (~> 3.10.1)
rainbow (~> 3.1.1)
@@ -335,7 +335,7 @@ DEPENDENCIES
rspec-retry (~> 0.6.2)
rspec_junit_formatter (~> 0.6.0)
ruby-debug-ide (~> 0.7.3)
- selenium-webdriver (~> 4.8, >= 4.8.1)
+ selenium-webdriver (~> 4.8, >= 4.8.6)
slack-notifier (~> 2.4)
terminal-table (~> 3.0.2)
warning (~> 1.3)
@@ -343,4 +343,4 @@ DEPENDENCIES
zeitwerk (~> 2.6, >= 2.6.7)
BUNDLED WITH
- 2.4.8
+ 2.4.12
diff --git a/qa/README.md b/qa/README.md
index e6520867642..d8670d4da02 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -48,6 +48,37 @@ Tests are executed in merge request pipelines as part of the development lifecyc
- [Review app environment](../doc/development/testing_guide/review_apps.md)
- [e2e:package-and-test](../doc/development/testing_guide/end_to_end/index.md#testing-code-in-merge-requests)
+### Including tests in other projects
+
+Pipeline template for `package-and-test` E2E tests is designed in a way so it can be included as a child pipeline in other projects.
+
+Minimal configuration example would look like this:
+
+```yaml
+qa-test:
+ stage: test
+ variables:
+ RELEASE: EE
+ trigger:
+ strategy: depend
+ forward:
+ yaml_variables: true
+ pipeline_variables: true
+ include:
+ - project: gitlab-org/gitlab
+ ref: master
+ file: .gitlab/ci/package-and-test/main.gitlab-ci.yml
+```
+
+To set GitLab version used for testing, following environment variables can be used:
+
+- `RELEASE`: `omnibus` release, can be string value `EE` or `CE` for nightly release of enterprise or community edition of GitLab or can be fully qualified Docker image name
+- `QA_IMAGE`: Docker image of qa code. By default inferred from `RELEASE` but can be explicitly overridden with this variable
+
+#### Test specific environment variables
+
+Special GitLab configurations require various specific environment variables to be present for tests to work. These can be provisioned automatically using `terraform` setup in [engineering-productivity-infrastructure](https://gitlab.com/gitlab-org/quality/engineering-productivity-infrastructure/-/tree/main/qa-resources/modules/e2e-ci) project.
+
### Logging
By default tests on CI use `info` log level. `debug` level is still available in case of failure debugging. Logs are stored in jobs artifacts.
@@ -98,7 +129,7 @@ See the section above for situations that might require adjustment to the comman
1. Use the following command to start an instance that you can visit at `http://127.0.0.1`:
- ```
+ ```bash
docker run \
--hostname 127.0.0.1 \
--publish 80:80 --publish 22:22 \
@@ -137,7 +168,7 @@ See the section above for situations that might require adjustment to the comman
2. Use the following command to start an instance that you can visit at `http://127.0.0.1`. You might need to grant admin rights if asked:
- ```
+ ```bash
docker run --hostname 127.0.0.1 --publish 80:80 --publish 22:22 --name gitlab --shm-size 256m --env GITLAB_OMNIBUS_CONFIG="gitlab_rails['initial_root_password']='5iveL\!fe';" gitlab/gitlab-ee:nightly
```
@@ -184,7 +215,7 @@ Those tests are tagged `:transient` and therefore can be run via:
bundle exec rspec --tag transient
```
-#### Overriding gitlab address
+#### Overriding GitLab address
When running tests against GDK, the default address is `http://127.0.0.1:3000`. This value can be overridden by providing environment variable `QA_GITLAB_URL`:
@@ -228,7 +259,7 @@ All [supported environment variables are here](https://gitlab.com/gitlab-org/git
#### Sending additional cookies
The environment variable `QA_COOKIES` can be set to send additional cookies
-on every request. This is necessary on gitlab.com to direct traffic to the
+on every request. This is necessary on `gitlab.com` to direct traffic to the
canary fleet. To do this set `QA_COOKIES="gitlab_canary=true"`.
To set multiple cookies, separate them with the `;` character, for example: `QA_COOKIES="cookie1=value;cookie2=value2"`
@@ -274,7 +305,7 @@ bundle exec rspec --tag quarantine
### Running tests with a custom bin/qa test runner
-`bin/qa` is an additional custom wrapper script that abstracts away some of the more complicated setups that some tests require. This option requires test scenario and test instance's Gitlab address to be specified in the command. For example, to run any `Instance` scenario test, the following command can be used:
+`bin/qa` is an additional custom wrapper script that abstracts away some of the more complicated setups that some tests require. This option requires test scenario and test instance's GitLab address to be specified in the command. For example, to run any `Instance` scenario test, the following command can be used:
```shell
bundle exec bin/qa Test::Instance::All http://localhost:3000
diff --git a/qa/gdk/launch b/qa/gdk/launch
index 4b1fc6ae191..8ad2ce7e5ad 100755
--- a/qa/gdk/launch
+++ b/qa/gdk/launch
@@ -1,6 +1,6 @@
#!/bin/bash
-COMMIT_REF=${1:-$CI_COMMIT_REF_SLUG}
+COMMIT_REF=${1:-$CI_COMMIT_SHA}
RSPEC_ARGS=$2
if [ -z "${COMMIT_REF}" ]; then
diff --git a/qa/qa.rb b/qa/qa.rb
index a395dc6e0b0..f6fba30c079 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -83,7 +83,8 @@ module QA
"vscode" => "VSCode",
"registry_with_cdn" => "RegistryWithCDN",
"fips" => "FIPS",
- "ci_cd_settings" => "CICDSettings"
+ "ci_cd_settings" => "CICDSettings",
+ "cli" => "CLI"
)
loader.setup
diff --git a/qa/qa/ce/strategy.rb b/qa/qa/ce/strategy.rb
index 8143595a18b..2587da17739 100644
--- a/qa/qa/ce/strategy.rb
+++ b/qa/qa/ce/strategy.rb
@@ -16,6 +16,9 @@ module QA
QA::Runtime::Env.personal_access_token)
end
+ QA::Runtime::Logger.info("Browser: #{QA::Runtime::Env.browser}")
+ QA::Runtime::Logger.info("Browser version: #{QA::Runtime::Env.browser_version}")
+
# The login page could take some time to load the first time it is visited.
# We visit the login page and wait for it to properly load only once before the tests.
QA::Runtime::Logger.info("Performing sanity check for environment!")
diff --git a/qa/qa/flow/pipeline.rb b/qa/qa/flow/pipeline.rb
index 0765a8758ec..d1cfe8dae09 100644
--- a/qa/qa/flow/pipeline.rb
+++ b/qa/qa/flow/pipeline.rb
@@ -9,7 +9,7 @@ module QA
# canceled, created, failed, manual, passed
# pending, running, skipped
def visit_latest_pipeline(status: nil, wait: nil, skip_wait: true)
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
Page::Project::Pipeline::Index.perform do |index|
index.has_any_pipeline?(wait: wait)
index.wait_for_latest_pipeline(status: status, wait: wait) if status || !skip_wait
@@ -18,7 +18,7 @@ module QA
end
def wait_for_latest_pipeline(status: nil, wait: nil)
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
Page::Project::Pipeline::Index.perform do |index|
index.has_any_pipeline?(wait: wait)
index.wait_for_latest_pipeline(status: status, wait: wait)
diff --git a/qa/qa/flow/user_onboarding.rb b/qa/qa/flow/user_onboarding.rb
index 8c6a50f251f..a04c29389f5 100644
--- a/qa/qa/flow/user_onboarding.rb
+++ b/qa/qa/flow/user_onboarding.rb
@@ -9,7 +9,7 @@ module QA
Page::Registration::Welcome.perform do |welcome_page|
if welcome_page.has_get_started_button?
welcome_page.select_role('Other')
- welcome_page.choose_setup_for_company_if_available
+ welcome_page.choose_setup_for_just_me_if_available
welcome_page.choose_create_a_new_project_if_available
welcome_page.click_get_started_button
end
diff --git a/qa/qa/page/admin/applications.rb b/qa/qa/page/admin/applications.rb
new file mode 100644
index 00000000000..56880a4b22c
--- /dev/null
+++ b/qa/qa/page/admin/applications.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Admin
+ class Applications < Page::Base
+ view 'app/views/admin/applications/index.html.haml' do
+ element :new_application_button
+ end
+
+ view 'app/views/admin/applications/_form.html.haml' do
+ element :name_field
+ element :redirect_uri_field
+ element :trusted_checkbox
+ element :save_application_button
+ end
+
+ view 'app/views/shared/tokens/_scopes_form.html.haml' do
+ element :api_label, '#{scope}_label' # rubocop:disable QA/ElementWithPattern, Lint/InterpolationCheck
+ end
+
+ view 'app/views/shared/doorkeeper/applications/_show.html.haml' do
+ element :application_id_field
+ element :id_of_application_field
+ end
+
+ view 'app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue' do
+ element :clipboard_button
+ end
+
+ def click_new_application_button
+ click_element :new_application_button
+ end
+
+ def fill_name(name)
+ fill_element :name_field, name
+ end
+
+ def fill_redirect_uri(redirect_uri)
+ fill_element :redirect_uri_field, redirect_uri
+ end
+
+ def set_trusted_checkbox(value)
+ check_element :trusted_checkbox, value
+ end
+
+ def set_scope(scope)
+ click_element "#{scope}_label".to_sym
+ end
+
+ def save_application
+ click_element :save_application_button
+ end
+
+ def get_secret_id
+ find_element(:clipboard_button)['data-clipboard-text']
+ end
+
+ def get_application_id
+ find_element(:application_id_field).value
+ end
+
+ # Returns the ID of the resource
+ def get_id_of_application
+ find_element(:id_of_application_field, visible: false).value
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/admin/menu.rb b/qa/qa/page/admin/menu.rb
index 42dd1083bbe..6ef59e118fb 100644
--- a/qa/qa/page/admin/menu.rb
+++ b/qa/qa/page/admin/menu.rb
@@ -4,81 +4,71 @@ module QA
module Page
module Admin
class Menu < Page::Base
- view 'app/views/layouts/nav/sidebar/_admin.html.haml' do
- element :admin_sidebar_content
- element :admin_monitoring_menu_link
- element :admin_monitoring_submenu_content
+ include SubMenus::Common
+
+ if QA::Runtime::Env.super_sidebar_enabled?
+ prepend Sidebar::Overview
+ prepend Sidebar::Settings
+ end
+
+ view 'lib/sidebars/admin/menus/admin_overview_menu.rb' do
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_settings_repository_link
+ end
+
+ view 'lib/sidebars/admin/menus/analytics_menu.rb' do
+ element :admin_sidebar_analytics_submenu_content
+ end
+
+ view 'lib/sidebars/admin/menus/monitoring_menu.rb' do
+ element :admin_monitoring_menu_link
end
def go_to_preferences_settings
hover_element(:admin_settings_menu_link) do
- within_submenu(:admin_settings_submenu_content) do
- click_element :admin_settings_preferences_link
- end
+ click_element :admin_settings_preferences_link
end
end
def go_to_repository_settings
hover_element(:admin_settings_menu_link) do
- within_submenu(:admin_settings_submenu_content) do
- click_element :admin_settings_repository_link
- end
+ click_element :admin_settings_repository_link
end
end
def go_to_integration_settings
hover_element(:admin_settings_menu_link) do
- within_submenu(:admin_settings_submenu_content) do
- click_element :admin_settings_integrations_link
- end
+ click_element :admin_settings_integrations_link
end
end
def go_to_general_settings
hover_element(:admin_settings_menu_link) do
- within_submenu(:admin_settings_submenu_content) do
- click_element :admin_settings_general_link
- end
+ click_element :admin_settings_general_link
end
end
def go_to_metrics_and_profiling_settings
hover_element(:admin_settings_menu_link) do
- within_submenu(:admin_settings_submenu_content) do
- click_element :admin_settings_metrics_and_profiling_link
- end
+ click_element :admin_settings_metrics_and_profiling_link
end
end
def go_to_network_settings
hover_element(:admin_settings_menu_link) do
- within_submenu(:admin_settings_submenu_content) do
- click_element :admin_settings_network_link
- end
+ click_element :admin_settings_network_link
end
end
def go_to_users_overview
- within_submenu(:admin_overview_submenu_content) do
- click_element :admin_overview_users_link
- end
+ click_element :admin_overview_users_link
end
def go_to_groups_overview
- within_submenu(:admin_overview_submenu_content) do
- click_element :admin_overview_groups_link
- end
+ click_element :admin_overview_groups_link
+ end
+
+ def go_to_applications
+ click_element(:sidebar_menu_link, menu_item: 'Applications')
end
private
@@ -93,7 +83,7 @@ module QA
end
def within_sidebar(&block)
- within_element(:admin_sidebar_content, &block)
+ page.within('.sidebar-top-level-items', &block)
end
def within_submenu(element, &block)
diff --git a/qa/qa/page/admin/sidebar/overview.rb b/qa/qa/page/admin/sidebar/overview.rb
new file mode 100644
index 00000000000..5bd542a2e52
--- /dev/null
+++ b/qa/qa/page/admin/sidebar/overview.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Admin
+ module Sidebar
+ module Overview
+ def go_to_users_overview
+ open_overview_submenu("Users")
+ end
+
+ def go_to_groups_overview
+ open_overview_submenu("Groups")
+ end
+
+ private
+
+ def open_overview_submenu(sub_menu)
+ open_submenu("Overview", sub_menu)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/admin/sidebar/settings.rb b/qa/qa/page/admin/sidebar/settings.rb
new file mode 100644
index 00000000000..1eb6ac2c119
--- /dev/null
+++ b/qa/qa/page/admin/sidebar/settings.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Admin
+ module Sidebar
+ module Settings
+ def go_to_preferences_settings
+ open_settings_submenu("Preferences")
+ end
+
+ def go_to_repository_settings
+ open_settings_submenu("Repository")
+ end
+
+ def go_to_integration_settings
+ open_settings_submenu("Integration")
+ end
+
+ def go_to_general_settings
+ open_settings_submenu("General")
+ end
+
+ def go_to_metrics_and_profiling_settings
+ open_settings_submenu("Metrics and profiling")
+ end
+
+ def go_to_network_settings
+ open_settings_submenu("Network")
+ end
+
+ private
+
+ def open_settings_submenu(sub_menu)
+ open_submenu("Settings", sub_menu)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index ab83da7dacf..616c12bd900 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -6,7 +6,7 @@ module QA
module Page
class Base
prepend Support::Page::Logging
- prepend Mobile::Page::Base if QA::Runtime::Env.remote_mobile_device_name
+ prepend Mobile::Page::Base if QA::Runtime::Env.mobile_layout?
include Capybara::DSL
include Scenario::Actable
@@ -234,13 +234,14 @@ module QA
page.validate_elements_present! if page
end
- # Uses capybara to locate and click an element instead of `click_element`.
- # This can be used when it's not possible to add a QA selector but we still want to log the click
+ # Uses capybara to locate and interact with an element instead of using `*_element`.
+ # This can be used when it's not possible to add a QA selector but we still want to log the action
#
# @param [String] method the capybara method to use
# @param [String] locator the selector used to find the element
- def click_via_capybara(method, locator)
- page.public_send(method, locator)
+ # @param [Hash] **kwargs optional arguments
+ def act_via_capybara(method, locator, **kwargs)
+ page.public_send(method, locator, **kwargs)
end
def fill_element(name, content)
diff --git a/qa/qa/page/component/breadcrumbs.rb b/qa/qa/page/component/breadcrumbs.rb
index 2576e376e4e..f2343da489e 100644
--- a/qa/qa/page/component/breadcrumbs.rb
+++ b/qa/qa/page/component/breadcrumbs.rb
@@ -9,7 +9,7 @@ module QA
def self.included(base)
super
- base.view 'app/views/layouts/nav/_breadcrumbs.html.haml' do
+ base.view 'app/views/layouts/nav/breadcrumbs/_breadcrumbs.html.haml' do
element :breadcrumb_links_content
end
end
diff --git a/qa/qa/page/component/content_editor.rb b/qa/qa/page/component/content_editor.rb
index a9abda42610..f2733e4b065 100644
--- a/qa/qa/page/component/content_editor.rb
+++ b/qa/qa/page/component/content_editor.rb
@@ -17,7 +17,7 @@ module QA
element :text_style_dropdown
end
- base.view 'app/assets/javascripts/content_editor/components/toolbar_image_button.vue' do
+ base.view 'app/assets/javascripts/content_editor/components/toolbar_attachment_button.vue' do
element :file_upload_field
end
diff --git a/qa/qa/page/component/groups_filter.rb b/qa/qa/page/component/groups_filter.rb
index 14e49e53b75..266c0dfa1af 100644
--- a/qa/qa/page/component/groups_filter.rb
+++ b/qa/qa/page/component/groups_filter.rb
@@ -34,7 +34,8 @@ module QA
# @return [Boolean] whether the filter returned any group
def filter_group(name)
fill_element(:groups_filter_field, name).send_keys(:return)
- finished_loading?
+ # Loading starts a moment after `return` is sent. We mustn't jump ahead
+ wait_for_requests if spinner_exists?
has_element?(:groups_list_tree_container, wait: 1)
end
end
diff --git a/qa/qa/page/component/snippet.rb b/qa/qa/page/component/snippet.rb
index 4e1c7f3e2bb..b1d83a6e2d0 100644
--- a/qa/qa/page/component/snippet.rb
+++ b/qa/qa/page/component/snippet.rb
@@ -84,7 +84,7 @@ module QA
element :copy_contents_button
end
- base.view 'app/views/layouts/nav/_breadcrumbs.html.haml' do
+ base.view 'app/views/layouts/nav/breadcrumbs/_breadcrumbs.html.haml' do
element :breadcrumb_links_content
element :breadcrumb_current_link
end
diff --git a/qa/qa/page/dashboard/snippet/index.rb b/qa/qa/page/dashboard/snippet/index.rb
index 088fff17578..51d7bd3f20b 100644
--- a/qa/qa/page/dashboard/snippet/index.rb
+++ b/qa/qa/page/dashboard/snippet/index.rb
@@ -5,25 +5,12 @@ module QA
module Dashboard
module Snippet
class Index < Page::Base
- view 'app/views/layouts/header/_new_dropdown.html.haml' do
- element :new_menu_toggle
- end
-
- view 'app/helpers/nav/new_dropdown_helper.rb' do
- element :global_new_snippet_link
- end
-
view 'app/views/shared/snippets/_snippet.html.haml' do
element :snippet_link
element :snippet_visibility_content
element :snippet_file_count_content
end
- def go_to_new_snippet_page
- click_element :new_menu_toggle
- click_element :global_new_snippet_link
- end
-
def has_snippet_title?(snippet_title)
has_element?(:snippet_link, snippet_title: snippet_title)
end
diff --git a/qa/qa/page/file/show.rb b/qa/qa/page/file/show.rb
index 31899d9a0c7..011b1ea5d81 100644
--- a/qa/qa/page/file/show.rb
+++ b/qa/qa/page/file/show.rb
@@ -5,8 +5,6 @@ module QA
module File
class Show < Page::Base
include Shared::CommitMessage
- include Project::SubMenus::Settings
- include Project::SubMenus::Common
include Layout::Flash
include Page::Component::BlobContent
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index 9418593133e..490b16a53fd 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -6,6 +6,14 @@ module QA
class Menu < Page::Base
include SubMenus::Common
+ if Runtime::Env.super_sidebar_enabled?
+ prepend Page::SubMenus::SuperSidebar::Manage
+ prepend Page::SubMenus::SuperSidebar::Plan
+ prepend Page::SubMenus::SuperSidebar::Settings
+ prepend SubMenus::SuperSidebar::Main
+ prepend SubMenus::SuperSidebar::Build
+ end
+
def click_group_members_item
hover_group_information do
within_submenu do
@@ -15,6 +23,8 @@ module QA
end
def click_subgroup_members_item
+ return go_to_members if Runtime::Env.super_sidebar_enabled?
+
hover_subgroup_information do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'Members')
@@ -29,6 +39,8 @@ module QA
end
def click_group_general_settings_item
+ return go_to_general_settings if Runtime::Env.super_sidebar_enabled?
+
hover_group_settings do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'General')
diff --git a/qa/qa/page/group/sub_menus/super_sidebar/build.rb b/qa/qa/page/group/sub_menus/super_sidebar/build.rb
new file mode 100644
index 00000000000..0b8bf030622
--- /dev/null
+++ b/qa/qa/page/group/sub_menus/super_sidebar/build.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Group
+ module SubMenus
+ module SuperSidebar
+ module Build
+ extend QA::Page::PageConcern
+
+ def go_to_runners
+ open_build_submenu("Runners")
+ end
+
+ private
+
+ def open_build_submenu(sub_menu)
+ open_submenu("Build", sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/group/sub_menus/super_sidebar/main.rb b/qa/qa/page/group/sub_menus/super_sidebar/main.rb
new file mode 100644
index 00000000000..e470c03b9e5
--- /dev/null
+++ b/qa/qa/page/group/sub_menus/super_sidebar/main.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Group
+ module SubMenus
+ module SuperSidebar
+ module Main
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
+ include QA::Page::SubMenus::SuperSidebar::Main
+ end
+ end
+
+ def go_to_group_overview
+ click_element(:nav_item_link, submenu_item: 'Group overview')
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 7532154f0cc..59371dbed39 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -40,6 +40,8 @@ module QA
view 'app/helpers/auth_helper.rb' do
element :saml_login_button
+ element :github_login_button
+ element :oidc_login_button
end
view 'app/views/layouts/devise.html.haml' do
@@ -106,7 +108,7 @@ module QA
# Happens on clean GDK installations when seeded root admin password is expired
#
def set_up_new_password_if_required(user:, skip_page_validation:)
- return unless has_content?('Set up new password')
+ return unless has_content?('Set up new password', wait: 1)
Profile::Password.perform do |new_password_page|
password = user&.password || Runtime::User.password
@@ -177,11 +179,21 @@ module QA
click_element :standard_tab
end
+ def sign_in_with_github
+ set_initial_password_if_present
+ click_element :github_login_button
+ end
+
def sign_in_with_saml
set_initial_password_if_present
click_element :saml_login_button
end
+ def sign_in_with_oidc
+ set_initial_password_if_present
+ click_element :oidc_login_button
+ end
+
def sign_out_and_sign_in_as(user:)
Menu.perform(&:sign_out_if_signed_in)
has_sign_in_tab?
@@ -226,6 +238,10 @@ module QA
Support::WaitForRequests.wait_for_requests
+ wait_until(sleep_interval: 5, message: '502 - GitLab is taking too much time to respond') do
+ has_no_text?('GitLab is taking too much time to respond')
+ end
+
# For debugging invalid login attempts
has_notice?('Invalid login or password')
@@ -233,7 +249,7 @@ module QA
terms.accept_terms if terms.visible?
end
- Page::Main::Menu.perform(&:enable_new_navigation) if Runtime::Env.super_sidebar_enabled?
+ Page::Main::Menu.perform(&:enable_new_navigation) if Runtime::Env.super_sidebar_enabled? && !on_login_page?
Page::Main::Menu.validate_elements_present! unless skip_page_validation
end
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index f86849061e8..a46b2057327 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -4,14 +4,21 @@ module QA
module Page
module Main
class Menu < Page::Base
- prepend Mobile::Page::Main::Menu if Runtime::Env.mobile_layout?
+ # We need to check phone_layout? instead of mobile_layout? here
+ # since tablets have the regular top navigation bar
+ prepend Mobile::Page::Main::Menu if Runtime::Env.phone_layout?
+
+ if Runtime::Env.super_sidebar_enabled?
+ prepend SubMenus::CreateNewMenu
+ include SubMenus::SuperSidebar::ContextSwitcher
+ end
if QA::Runtime::Env.super_sidebar_enabled?
# Define alternative navbar (super sidebar) which does not yet implement all the same elements
view 'app/assets/javascripts/super_sidebar/components/super_sidebar.vue' do
element :navbar, required: true # TODO: rename to sidebar once it's default implementation
- element :user_menu, required: !QA::Runtime::Env.mobile_layout?
- element :user_avatar_content, required: !QA::Runtime::Env.mobile_layout?
+ element :user_menu, required: !Runtime::Env.phone_layout?
+ element :user_avatar_content, required: !Runtime::Env.phone_layout?
end
view 'app/assets/javascripts/super_sidebar/components/user_menu.vue' do
@@ -22,12 +29,12 @@ module QA
view 'app/views/layouts/header/_default.html.haml' do
element :navbar, required: true
element :canary_badge_link
- element :user_avatar_content, required: !QA::Runtime::Env.mobile_layout?
- element :user_menu, required: !QA::Runtime::Env.mobile_layout?
+ element :user_avatar_content, required: !Runtime::Env.phone_layout?
+ element :user_menu, required: !Runtime::Env.phone_layout?
element :stop_impersonation_link
- element :issues_shortcut_button, required: !QA::Runtime::Env.mobile_layout?
- element :merge_requests_shortcut_button, required: !QA::Runtime::Env.mobile_layout?
- element :todos_shortcut_button, required: !QA::Runtime::Env.mobile_layout?
+ element :issues_shortcut_button, required: !Runtime::Env.phone_layout?
+ element :merge_requests_shortcut_button, required: !Runtime::Env.phone_layout?
+ element :todos_shortcut_button, required: !Runtime::Env.phone_layout?
end
view 'app/views/layouts/header/_current_user_dropdown.html.haml' do
@@ -56,10 +63,6 @@ module QA
element :menu_item_link
end
- view 'app/views/layouts/_search.html.haml' do
- element :search_term_field
- end
-
view 'app/views/layouts/_header_search.html.haml' do
element :search_box
end
@@ -75,30 +78,38 @@ module QA
view 'app/helpers/nav/new_dropdown_helper.rb' do
element :global_new_group_link
element :global_new_project_link
+ element :global_new_snippet_link
end
view 'app/assets/javascripts/nav/components/new_nav_toggle.vue' do
element :new_navigation_toggle
end
- def go_to_groups
- within_groups_menu do
- click_element(:menu_item_link, title: 'View all groups')
- end
- end
+ def go_to_projects
+ return click_element(:nav_item_link, submenu_item: 'Projects') if Runtime::Env.super_sidebar_enabled?
- def go_to_create_group
- click_element(:new_menu_toggle)
- click_element(:global_new_group_link)
+ click_element(:sidebar_menu_link, menu_item: 'Projects')
end
- def go_to_projects
- within_projects_menu do
- click_element(:menu_item_link, title: 'View all projects')
+ def go_to_groups
+ return click_element(:nav_item_link, submenu_item: 'Groups') if Runtime::Env.super_sidebar_enabled?
+
+ # Use new functionality to visit Groups where possible
+ if has_element?(:sidebar_menu_link, menu_item: 'Groups')
+ click_element(:sidebar_menu_link, menu_item: 'Groups')
+ else
+ # Otherwise fallback to previous functionality
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/403589
+ # and related issues
+ within_groups_menu do
+ click_element(:menu_item_link, title: 'View all groups')
+ end
end
end
def go_to_snippets
+ return click_element(:nav_item_link, submenu_item: 'Snippets') if Runtime::Env.super_sidebar_enabled?
+
click_element(:sidebar_menu_link, menu_item: 'Snippets')
end
@@ -107,6 +118,16 @@ module QA
click_element(:global_new_project_link)
end
+ def go_to_create_group
+ click_element(:new_menu_toggle)
+ click_element(:global_new_group_link)
+ end
+
+ def go_to_create_snippet
+ click_element(:new_menu_toggle)
+ click_element(:global_new_snippet_link)
+ end
+
def go_to_menu_dropdown_option(option_name)
return click_element(option_name) if QA::Runtime::Env.super_sidebar_enabled?
@@ -129,7 +150,7 @@ module QA
end
def go_to_admin_area
- click_admin_area
+ Runtime::Env.super_sidebar_enabled? ? super : click_admin_area
return unless has_text?('Enter Admin Mode', wait: 1.0)
@@ -146,7 +167,7 @@ module QA
end
def signed_in_as_user?(user)
- return false if has_no_personal_area?
+ return false unless has_personal_area?
within_user_menu do
has_element?(:user_profile_link, text: /#{user.username}/)
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 451a9c3ee6e..d96acc36b2e 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -199,7 +199,15 @@ module QA
end
def click_diffs_tab
- click_element(:diffs_tab)
+ # Do not wait for spinner due to https://gitlab.com/gitlab-org/gitlab/-/issues/398584
+ click_element(:diffs_tab, skip_finished_loading_check: true)
+
+ # If the diff isn't available when we navigate to the Changes tab
+ # we must reload the page. https://gitlab.com/gitlab-org/gitlab/-/issues/398557
+ wait_until(reload: true, skip_finished_loading_check_on_refresh: true) do
+ QA::Runtime::Logger.debug('Ensuring that diff has loaded async')
+ has_element?(:file_tree_button, skip_finished_loading_check: true, wait: 1)
+ end
end
def click_pipeline_link
diff --git a/qa/qa/page/profile/menu.rb b/qa/qa/page/profile/menu.rb
index 651603a77db..f9493dbefcc 100644
--- a/qa/qa/page/profile/menu.rb
+++ b/qa/qa/page/profile/menu.rb
@@ -4,9 +4,9 @@ module QA
module Page
module Profile
class Menu < Page::Base
- # We need to check remote_mobile_device_name instead of mobile_layout? here
- # since tablets have the regular top navigation bar but still close the left nav
- prepend QA::Mobile::Page::SubMenus::Common if QA::Runtime::Env.remote_mobile_device_name
+ prepend QA::Mobile::Page::SubMenus::Common if QA::Runtime::Env.mobile_layout?
+ # TODO: integrate back once super sidebar becomes default
+ prepend QA::Page::Profile::SuperSidebar::Menu if QA::Runtime::Env.super_sidebar_enabled?
view 'lib/sidebars/user_settings/menus/access_tokens_menu.rb' do
element :access_token_link
@@ -60,10 +60,8 @@ module QA
private
- def within_sidebar
- page.within('.sidebar-top-level-items') do
- yield
- end
+ def within_sidebar(&block)
+ page.within('.sidebar-top-level-items', &block)
end
end
end
diff --git a/qa/qa/page/profile/super_sidebar/menu.rb b/qa/qa/page/profile/super_sidebar/menu.rb
new file mode 100644
index 00000000000..ade9c47313d
--- /dev/null
+++ b/qa/qa/page/profile/super_sidebar/menu.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Profile
+ module SuperSidebar
+ module Menu
+ def click_ssh_keys
+ click_element(:nav_item_link, submenu_item: 'SSH Keys')
+ end
+
+ def click_account
+ click_element(:nav_item_link, submenu_item: 'Account')
+ end
+
+ def click_emails
+ click_element(:nav_item_link, submenu_item: 'Emails')
+ end
+
+ def click_password
+ click_element(:nav_item_link, submenu_item: 'Password')
+ end
+
+ def click_access_tokens
+ click_element(:nav_item_link, submenu_item: 'Access Tokens')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index bb1095371a8..759729f0abf 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -32,6 +32,8 @@ module QA
# In this case skip this step and proceed to import project row
return unless has_element?(:personal_access_token_field)
+ raise ArgumentError, "No personal access token was provided" if personal_access_token.empty?
+
fill_element(:personal_access_token_field, personal_access_token)
click_element(:authenticate_button)
finished_loading?
@@ -71,7 +73,11 @@ module QA
# @param [String] source_project_name
# @param [Integer] wait
# @return [Boolean]
- def has_imported_project?(gh_project_name, wait: QA::Support::WaitForRequests::DEFAULT_MAX_WAIT_TIME)
+ def has_imported_project?(
+ gh_project_name,
+ wait: QA::Support::WaitForRequests::DEFAULT_MAX_WAIT_TIME,
+ allow_partial_import: false
+ )
within_element(:project_import_row, source_project: gh_project_name, skip_finished_loading_check: true) do
wait_until(
max_duration: wait,
@@ -80,18 +86,12 @@ module QA
skip_finished_loading_check_on_refresh: true
) do
status_selector = 'import_status_indicator'
- is_partial_import = has_css?(status_selector, text: "Partial import")
- # Temporarily adding this for investigation purposes. This makes sure that the details section is
- # expanded when the screenshot is taken when the test fails. This can be removed or repurposed later
- # after investigation. Related: https://gitlab.com/gitlab-org/gitlab/-/issues/385252#note_1211218434
- if is_partial_import
- within_element_by_index(:import_status_indicator, 0) do
- find('button').click
- end
- end
+ return has_element?(status_selector, text: "Complete", wait: 1) unless allow_partial_import # rubocop:disable Cop/AvoidReturnFromBlocks
- has_element?(status_selector, text: "Complete")
+ ["Partially completed", "Complete"].any? do |status|
+ has_element?(status_selector, text: status, wait: 1)
+ end
end
end
end
diff --git a/qa/qa/page/project/import/repo_by_url.rb b/qa/qa/page/project/import/repo_by_url.rb
index 4a8d08d6499..42e701bf882 100644
--- a/qa/qa/page/project/import/repo_by_url.rb
+++ b/qa/qa/page/project/import/repo_by_url.rb
@@ -17,8 +17,6 @@ module QA
click_create_button
wait_for_success
-
- go_to_project(name)
end
private
@@ -52,13 +50,6 @@ module QA
page.has_no_content?('Import in progress', wait: 3.0)
end
end
-
- def go_to_project(name)
- Page::Main::Menu.perform(&:go_to_projects)
- Page::Dashboard::Projects.perform do |dashboard|
- dashboard.go_to_project(name)
- end
- end
end
end
end
diff --git a/qa/qa/page/project/issue/new.rb b/qa/qa/page/project/issue/new.rb
index c90a09dce2e..7f52cda7c15 100644
--- a/qa/qa/page/project/issue/new.rb
+++ b/qa/qa/page/project/issue/new.rb
@@ -17,3 +17,5 @@ module QA
end
end
end
+
+QA::Page::Project::Issue::New.prepend_mod_with('Page::Project::Issue::New', namespace: QA)
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
index 2f8ffc634ac..20dce1b3639 100644
--- a/qa/qa/page/project/issue/show.rb
+++ b/qa/qa/page/project/issue/show.rb
@@ -8,7 +8,9 @@ module QA
include Page::Component::Note
include Page::Component::DesignManagement
include Page::Component::Issuable::Sidebar
- prepend Mobile::Page::Project::Issue::Show if Runtime::Env.mobile_layout?
+ # We need to check phone_layout? instead of mobile_layout? here
+ # since tablets have the regular top navigation bar
+ prepend Mobile::Page::Project::Issue::Show if Runtime::Env.phone_layout?
view 'app/assets/javascripts/issuable/components/related_issuable_item.vue' do
element :remove_related_issue_button
diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb
index 444c67cfe4f..41a2986e300 100644
--- a/qa/qa/page/project/job/show.rb
+++ b/qa/qa/page/project/job/show.rb
@@ -69,11 +69,11 @@ module QA
end
def has_locked_artifact?
- has_text?('will not be deleted')
+ has_element? :artifacts_locked_message_content
end
def has_unlocked_artifact?
- has_text?('will be removed')
+ has_element? :artifacts_unlocked_message_content
end
private
diff --git a/qa/qa/page/project/menu.rb b/qa/qa/page/project/menu.rb
index db70d3e1d02..23b3ee61077 100644
--- a/qa/qa/page/project/menu.rb
+++ b/qa/qa/page/project/menu.rb
@@ -14,20 +14,38 @@ module QA
include SubMenus::Repository
include SubMenus::Settings
include SubMenus::Packages
+ include SubMenus::CreateNewMenu
+
+ if Runtime::Env.super_sidebar_enabled?
+ include Page::SubMenus::SuperSidebar::Manage
+ include SubMenus::SuperSidebar::Plan
+ include SubMenus::SuperSidebar::Settings
+ include SubMenus::SuperSidebar::Code
+ include SubMenus::SuperSidebar::Build
+ include SubMenus::SuperSidebar::Operate
+ include SubMenus::SuperSidebar::Monitor
+ include SubMenus::SuperSidebar::Main
+ end
def click_merge_requests
+ return go_to_merge_requests if Runtime::Env.super_sidebar_enabled?
+
within_sidebar do
click_element(:sidebar_menu_link, menu_item: 'Merge requests')
end
end
def click_wiki
+ return go_to_wiki if Runtime::Env.super_sidebar_enabled?
+
within_sidebar do
click_element(:sidebar_menu_link, menu_item: 'Wiki')
end
end
def click_activity
+ return go_to_activity if Runtime::Env.super_sidebar_enabled?
+
hover_project_information do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'Activity')
@@ -36,12 +54,16 @@ module QA
end
def click_snippets
+ return go_to_snippets if Runtime::Env.super_sidebar_enabled?
+
within_sidebar do
click_element(:sidebar_menu_link, menu_item: 'Snippets')
end
end
def click_members
+ return go_to_members if Runtime::Env.super_sidebar_enabled?
+
hover_project_information do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'Members')
diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb
index 25d62ac59af..2455555f06c 100644
--- a/qa/qa/page/project/pipeline/show.rb
+++ b/qa/qa/page/project/pipeline/show.rb
@@ -44,7 +44,7 @@ module QA
element :jobs_dropdown_menu
end
- view 'app/views/layouts/nav/_breadcrumbs.html.haml' do
+ view 'app/views/layouts/nav/breadcrumbs/_breadcrumbs.html.haml' do
element :breadcrumb_links_content
element :breadcrumb_current_link
end
diff --git a/qa/qa/page/project/settings/branch_rules.rb b/qa/qa/page/project/settings/branch_rules.rb
new file mode 100644
index 00000000000..b01f493addf
--- /dev/null
+++ b/qa/qa/page/project/settings/branch_rules.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module Settings
+ class BranchRules < Page::Base
+ view 'app/assets/javascripts/projects/settings/repository/branch_rules/app.vue' do
+ element :add_branch_rule_button
+ end
+
+ view 'app/assets/javascripts/projects/settings/repository/branch_rules/components/branch_rule.vue' do
+ element :branch_content
+ element :details_button
+ end
+
+ def click_add_branch_rule
+ click_element(:add_branch_rule_button)
+ click_button('Create protected branch')
+ end
+
+ def navigate_to_branch_rules_details(branch_name)
+ within_element(:branch_content, branch_name: branch_name) do
+ click_element(:details_button)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+QA::Page::Project::Settings::BranchRules.prepend_mod_with('Page::Project::Settings::BranchRules', namespace: QA)
diff --git a/qa/qa/page/project/settings/branch_rules_details.rb b/qa/qa/page/project/settings/branch_rules_details.rb
new file mode 100644
index 00000000000..f6806a30efa
--- /dev/null
+++ b/qa/qa/page/project/settings/branch_rules_details.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module Settings
+ class BranchRulesDetails < Page::Base
+ view 'app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue' do
+ element :allowed_to_push_content
+ element :allowed_to_merge_content
+ end
+
+ view 'app/assets/javascripts/projects/settings/branch_rules/components/view/protection_row.vue' do
+ element :access_level_content
+ end
+
+ def has_allowed_to_push?(role)
+ within_element(:allowed_to_push_content) do
+ has_element?(:access_level_content, role: role)
+ end
+ end
+
+ def has_allowed_to_merge?(role)
+ within_element(:allowed_to_merge_content) do
+ has_element?(:access_level_content, role: role)
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+QA::Page::Project::Settings::BranchRulesDetails.prepend_mod_with( # rubocop:disable Cop/InjectEnterpriseEditionModule
+ 'Page::Project::Settings::BranchRulesDetails', namespace: QA)
diff --git a/qa/qa/page/project/settings/ci_variables.rb b/qa/qa/page/project/settings/ci_variables.rb
index 8df0aaa9f27..1315ed8ca73 100644
--- a/qa/qa/page/project/settings/ci_variables.rb
+++ b/qa/qa/page/project/settings/ci_variables.rb
@@ -11,7 +11,6 @@ module QA
element :ci_variable_key_field
element :ci_variable_value_field
element :ci_variable_save_button
- element :ci_variable_delete_button
end
def fill_variable(key, value, masked = false)
@@ -37,14 +36,6 @@ module QA
def click_ci_variable_save_button
click_element :ci_variable_save_button
end
-
- def click_reveal_ci_variable_value_button
- click_element :reveal_ci_variable_value_button
- end
-
- def click_ci_variable_delete_button
- click_element :ci_variable_delete_button
- end
end
end
end
diff --git a/qa/qa/page/project/settings/deploy_keys.rb b/qa/qa/page/project/settings/deploy_keys.rb
index 297d29550e3..b94dbbea533 100644
--- a/qa/qa/page/project/settings/deploy_keys.rb
+++ b/qa/qa/page/project/settings/deploy_keys.rb
@@ -13,6 +13,7 @@ module QA
view 'app/views/shared/deploy_keys/_project_group_form.html.haml' do
element :deploy_key_title_field
element :deploy_key_field
+ element :deploy_key_expires_at_field
element :add_deploy_key_button
end
diff --git a/qa/qa/page/project/settings/main.rb b/qa/qa/page/project/settings/main.rb
index 8b9b72758d8..0d45efdcb70 100644
--- a/qa/qa/page/project/settings/main.rb
+++ b/qa/qa/page/project/settings/main.rb
@@ -6,7 +6,6 @@ module QA
module Settings
class Main < Page::Base
include QA::Page::Settings::Common
- include SubMenus::Project
include Component::Breadcrumbs
include Layout::Flash
diff --git a/qa/qa/page/project/settings/repository.rb b/qa/qa/page/project/settings/repository.rb
index 6931d26b259..d9aaacbde32 100644
--- a/qa/qa/page/project/settings/repository.rb
+++ b/qa/qa/page/project/settings/repository.rb
@@ -27,6 +27,10 @@ module QA
element :protected_tag_settings_content
end
+ view 'app/views/projects/branch_rules/_show.html.haml' do
+ element :branch_rules_content
+ end
+
def expand_deploy_tokens(&block)
expand_content(:deploy_tokens_settings_content) do
Settings::DeployTokens.perform(&block)
@@ -57,6 +61,10 @@ module QA
end
end
+ def expand_branch_rules
+ expand_content(:branch_rules_content)
+ end
+
def expand_default_branch(&block)
within('#branch-defaults-settings') do
find('.btn-default').click do
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index b89e17910c9..a76717f4760 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -7,9 +7,11 @@ module QA
include Layout::Flash
include Page::Component::ClonePanel
include Page::Component::Breadcrumbs
- include Page::Project::SubMenus::Settings
include Page::File::Shared::CommitMessage
- prepend Mobile::Page::Project::Show if Runtime::Env.mobile_layout?
+ include Page::Component::Dropdown
+ # We need to check phone_layout? instead of mobile_layout? here
+ # since tablets have the regular top navigation bar
+ prepend Mobile::Page::Project::Show if Runtime::Env.phone_layout?
view 'app/assets/javascripts/repository/components/preview/index.vue' do
element :blob_viewer_content
@@ -27,10 +29,6 @@ module QA
element :new_menu_toggle
end
- view 'app/helpers/nav/new_dropdown_helper.rb' do
- element :new_issue_link
- end
-
view 'app/views/projects/_last_push.html.haml' do
element :create_merge_request_button
end
@@ -68,11 +66,6 @@ module QA
element :web_ide_button
end
- view 'app/views/shared/_ref_switcher.html.haml' do
- element :branches_dropdown
- element :branches_dropdown_content
- end
-
view 'app/views/projects/blob/viewers/_loading.html.haml' do
element :spinner_placeholder
end
@@ -122,11 +115,6 @@ module QA
end
end
- def go_to_new_issue
- click_element(:new_menu_toggle)
- click_element(:new_issue_link)
- end
-
def has_create_merge_request_button?
has_css?(element_selector_css(:create_merge_request_button))
end
@@ -184,11 +172,8 @@ module QA
end
def switch_to_branch(branch_name)
- find_element(:branches_dropdown).click
-
- within_element(:branches_dropdown_content) do
- click_on branch_name
- end
+ expand_select_list
+ select_item(branch_name)
end
def wait_for_import
diff --git a/qa/qa/page/project/sub_menus/ci_cd.rb b/qa/qa/page/project/sub_menus/ci_cd.rb
index 4ae51798e54..3547ea76182 100644
--- a/qa/qa/page/project/sub_menus/ci_cd.rb
+++ b/qa/qa/page/project/sub_menus/ci_cd.rb
@@ -15,7 +15,7 @@ module QA
end
end
- def click_ci_cd_pipelines
+ def go_to_pipelines
within_sidebar do
click_element(:sidebar_menu_link, menu_item: 'CI/CD')
end
diff --git a/qa/qa/page/project/sub_menus/common.rb b/qa/qa/page/project/sub_menus/common.rb
index 79054ec9802..e8952f9e064 100644
--- a/qa/qa/page/project/sub_menus/common.rb
+++ b/qa/qa/page/project/sub_menus/common.rb
@@ -20,7 +20,7 @@ module QA
element :sidebar_menu_link
end
- view 'app/views/layouts/nav/_breadcrumbs.html.haml' do
+ view 'app/views/layouts/nav/_top_bar.html.haml' do
element :toggle_mobile_nav_button
end
end
diff --git a/qa/qa/page/project/sub_menus/create_new_menu.rb b/qa/qa/page/project/sub_menus/create_new_menu.rb
new file mode 100644
index 00000000000..cfb91c29d5e
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/create_new_menu.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module CreateNewMenu
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
+ # TODO: remove this when the super sidebar is enabled by default
+ view 'app/helpers/nav/new_dropdown_helper.rb' do
+ element :new_issue_link
+ end
+
+ view 'app/helpers/sidebars_helper.rb' do
+ element :create_menu_item
+ end
+ end
+ end
+
+ def go_to_new_issue
+ within_new_item_menu do
+ next click_element(:new_issue_link) unless QA::Runtime::Env.super_sidebar_enabled?
+
+ click_element(:create_menu_item, create_menu_item: 'new_issue')
+ end
+ end
+
+ def go_to_new_merge_request
+ within_new_item_menu do
+ click_element(:create_menu_item, create_menu_item: 'new_mr')
+ end
+ end
+
+ def go_to_new_project_snippet
+ within_new_item_menu do
+ click_element(:create_menu_item, create_menu_item: 'new_snippet')
+ end
+ end
+
+ def go_to_invite_members
+ within_new_item_menu do
+ click_element(:create_menu_item, create_menu_item: 'invite')
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/issues.rb b/qa/qa/page/project/sub_menus/issues.rb
index 7fa19063653..b5b918e076d 100644
--- a/qa/qa/page/project/sub_menus/issues.rb
+++ b/qa/qa/page/project/sub_menus/issues.rb
@@ -15,7 +15,7 @@ module QA
end
end
- def click_issues
+ def go_to_issues
within_sidebar do
click_element(:sidebar_menu_link, menu_item: 'Issues')
end
@@ -27,7 +27,7 @@ module QA
end
end
- def go_to_boards
+ def go_to_issue_boards
hover_issues do
within_submenu do
click_element(:sidebar_menu_item_link, menu_item: 'Boards')
diff --git a/qa/qa/page/project/sub_menus/packages.rb b/qa/qa/page/project/sub_menus/packages.rb
index 9600540c5bc..aaa4a2d2f66 100644
--- a/qa/qa/page/project/sub_menus/packages.rb
+++ b/qa/qa/page/project/sub_menus/packages.rb
@@ -26,7 +26,7 @@ module QA
def go_to_infrastructure_registry
hover_registry do
within_submenu do
- click_link('Infrastructure Registry')
+ click_link('Terraform modules')
end
end
end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/build.rb b/qa/qa/page/project/sub_menus/super_sidebar/build.rb
new file mode 100644
index 00000000000..7d772d9d192
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/build.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Build
+ extend QA::Page::PageConcern
+
+ def go_to_pipelines
+ open_build_submenu('Pipelines')
+ end
+
+ def go_to_pipeline_editor
+ open_build_submenu('Pipeline editor')
+ end
+
+ def go_to_jobs
+ open_build_submenu('Jobs')
+ end
+
+ def go_to_schedules
+ open_build_submenu('Pipeline schedules')
+ end
+
+ def go_to_environments
+ open_operations_submenu('Environments')
+ end
+
+ def go_to_feature_flags
+ open_operations_submenu('Feature Flags')
+ end
+
+ def go_to_releases
+ open_operations_submenu('Releases')
+ end
+
+ private
+
+ def open_build_submenu(sub_menu)
+ open_submenu('Build', sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/code.rb b/qa/qa/page/project/sub_menus/super_sidebar/code.rb
new file mode 100644
index 00000000000..44d46725b47
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/code.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Code
+ extend QA::Page::PageConcern
+
+ def go_to_repository
+ open_code_submenu('Repository')
+ end
+
+ def go_to_repository_commits
+ open_code_submenu('Commits')
+ end
+
+ def go_to_repository_branches
+ open_code_submenu('Branches')
+ end
+
+ def go_to_repository_tags
+ open_code_submenu('Tags')
+ end
+
+ def go_to_snippets
+ open_code_submenu('Snippets')
+ end
+
+ def go_to_graph
+ open_code_submenu('Repository graph')
+ end
+
+ def go_to_compare_revisions
+ open_code_submenu('Compare revisions')
+ end
+
+ private
+
+ def open_code_submenu(sub_menu)
+ open_submenu('Code', sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/main.rb b/qa/qa/page/project/sub_menus/super_sidebar/main.rb
new file mode 100644
index 00000000000..63641248b15
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/main.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Main
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
+ include QA::Page::SubMenus::SuperSidebar::Main
+ end
+ end
+
+ def click_project
+ click_element(:nav_item_link, submenu_item: 'Project overview')
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/monitor.rb b/qa/qa/page/project/sub_menus/super_sidebar/monitor.rb
new file mode 100644
index 00000000000..745dda06bb5
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/monitor.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Monitor
+ extend QA::Page::PageConcern
+
+ def go_to_monitor_metrics
+ open_monitor_submenu('Metrics')
+ end
+
+ def go_to_monitor_error_tracking
+ open_monitor_submenu('Error tracking')
+ end
+
+ def go_to_monitor_alerts
+ open_monitor_submenu('Alerts')
+ end
+
+ def go_to_monitor_incidents
+ open_monitor_submenu('Incidents')
+ end
+
+ def go_to_monitor_escalation_policies
+ open_monitor_submenu('Escalation Policies')
+ end
+
+ def go_to_monitor_on_call_schedules
+ open_monitor_submenu('On-call Schedules')
+ end
+
+ private
+
+ def open_monitor_submenu(sub_menu)
+ open_submenu('Monitor', sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/operate.rb b/qa/qa/page/project/sub_menus/super_sidebar/operate.rb
new file mode 100644
index 00000000000..316987733ab
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/operate.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Operate
+ extend QA::Page::PageConcern
+
+ def go_to_package_registry
+ open_operate_submenu('Package Registry')
+ end
+
+ def go_to_infrastructure_registry
+ open_operate_submenu('Terraform modules')
+ end
+
+ def go_to_kubernetes_clusters
+ open_operate_submenu('Kubernetes clusters')
+ end
+
+ def go_to_terraform
+ open_operate_submenu('Terraform')
+ end
+
+ private
+
+ def open_operate_submenu(sub_menu)
+ open_submenu('Operate', sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/plan.rb b/qa/qa/page/project/sub_menus/super_sidebar/plan.rb
new file mode 100644
index 00000000000..ca81837b2e2
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/plan.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Plan
+ def self.included(base)
+ super
+
+ base.class_eval do
+ include QA::Page::SubMenus::SuperSidebar::Plan
+ end
+ end
+
+ def go_to_requirements
+ open_plan_submenu("Requirements")
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/secure.rb b/qa/qa/page/project/sub_menus/super_sidebar/secure.rb
new file mode 100644
index 00000000000..ab1717a447a
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/secure.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Secure
+ extend QA::Page::PageConcern
+
+ def go_to_security_configuration
+ open_secure_submenu('Security configuration')
+ end
+
+ private
+
+ def open_secure_submenu(sub_menu)
+ open_submenu('Secure', sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/sub_menus/super_sidebar/settings.rb b/qa/qa/page/project/sub_menus/super_sidebar/settings.rb
new file mode 100644
index 00000000000..3aca6cf00af
--- /dev/null
+++ b/qa/qa/page/project/sub_menus/super_sidebar/settings.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module SubMenus
+ module SuperSidebar
+ module Settings
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.class_eval do
+ include QA::Page::SubMenus::SuperSidebar::Settings
+ end
+ end
+
+ def go_to_merge_request_settings
+ open_settings_submenu('Merge requests')
+ end
+
+ def go_to_pages_settings
+ open_settings_submenu('Pages')
+ end
+
+ def go_to_monitor_settings
+ open_settings_submenu('Monitor')
+ end
+
+ private
+
+ def open_settings_submenu(sub_menu)
+ open_submenu('Settings', sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/tag/show.rb b/qa/qa/page/project/tag/show.rb
index 1974448a7c5..b9703f46a50 100644
--- a/qa/qa/page/project/tag/show.rb
+++ b/qa/qa/page/project/tag/show.rb
@@ -8,7 +8,6 @@ module QA
view 'app/views/projects/tags/show.html.haml' do
element :tag_name_content
element :tag_message_content
- element :tag_release_notes_content
end
def has_tag_name?(text)
@@ -18,10 +17,6 @@ module QA
def has_tag_message?(text)
has_element?(:tag_message_content, text: text)
end
-
- def has_tag_release_notes?(text)
- has_element?(:tag_release_notes_content, text: text)
- end
end
end
end
diff --git a/qa/qa/page/project/web_ide/edit.rb b/qa/qa/page/project/web_ide/edit.rb
index 975d3c8ea14..dda329ab582 100644
--- a/qa/qa/page/project/web_ide/edit.rb
+++ b/qa/qa/page/project/web_ide/edit.rb
@@ -111,7 +111,7 @@ module QA
# Used for stablility, due to feature_caching of vscode_web_ide
def wait_until_ide_loads
- Support::Waiter.wait_until(sleep_interval: 2, max_duration: 60, reload_page: page,
+ Support::Waiter.wait_until(sleep_interval: 2, max_duration: 120, reload_page: page,
retry_on_exception: true) do
has_element?(:commit_mode_tab)
end
diff --git a/qa/qa/page/project/web_ide/vscode.rb b/qa/qa/page/project/web_ide/vscode.rb
index dd5222cfd93..1a9fad56a10 100644
--- a/qa/qa/page/project/web_ide/vscode.rb
+++ b/qa/qa/page/project/web_ide/vscode.rb
@@ -57,7 +57,7 @@ module QA
page.has_content?(folder_name)
# Commit Button
- page.find('a.monaco-description-button').click
+ page.find('a.monaco-text-button').click
page.has_css?('.notification-list-item-details-row', visible: true)
end
end
diff --git a/qa/qa/page/registration/welcome.rb b/qa/qa/page/registration/welcome.rb
index 77cdbe8fd9e..4150208e7ce 100644
--- a/qa/qa/page/registration/welcome.rb
+++ b/qa/qa/page/registration/welcome.rb
@@ -17,7 +17,7 @@ module QA
select_element(:role_dropdown, role)
end
- def choose_setup_for_company_if_available
+ def choose_setup_for_just_me_if_available
# Only implemented in EE
end
diff --git a/qa/qa/page/sub_menus/common.rb b/qa/qa/page/sub_menus/common.rb
index 518b3b4e84e..bbd886706ba 100644
--- a/qa/qa/page/sub_menus/common.rb
+++ b/qa/qa/page/sub_menus/common.rb
@@ -4,9 +4,7 @@ module QA
module Page
module SubMenus
module Common
- # We need to check remote_mobile_device_name instead of mobile_layout? here
- # since tablets have the regular top navigation bar but still close the left nav
- prepend Mobile::Page::SubMenus::Common if QA::Runtime::Env.remote_mobile_device_name
+ prepend Mobile::Page::SubMenus::Common if QA::Runtime::Env.mobile_layout?
def hover_element(element)
within_sidebar do
@@ -15,38 +13,49 @@ module QA
end
end
- def within_sidebar
+ def within_sidebar(&block)
wait_for_requests
- within_element(sidebar_element) do
- yield
- end
+ within_element(sidebar_element, &block)
end
- def within_submenu(element = nil)
+ def within_submenu(element = nil, &block)
if element
- within_element(element) do
- yield
- end
+ within_element(element, &block)
else
- within_submenu_without_element do
- yield
- end
+ within_submenu_without_element(&block)
end
end
private
- def within_submenu_without_element
- if has_css?('.fly-out-list')
- within('.fly-out-list') do
- yield
- end
- else
- yield
+ # Opens the new item menu and yields to the block
+ #
+ # @return [void]
+ def within_new_item_menu
+ click_element(:new_menu_toggle)
+
+ yield
+ end
+
+ # Implementation for super-sidebar, will replace within_submenu
+ #
+ # @param [String] parent_menu_name
+ # @param [String] parent_section_id
+ # @param [String] sub_menu
+ # @return [void]
+ def open_submenu(parent_menu_name, sub_menu)
+ click_element(:nav_item_link, menu_item: parent_menu_name)
+
+ within_element(:menu_section, section: parent_menu_name) do
+ click_element(:nav_item_link, submenu_item: sub_menu)
end
end
+ def within_submenu_without_element(&block)
+ has_css?('.fly-out-list') ? within('.fly-out-list', &block) : yield
+ end
+
def sidebar_element
raise NotImplementedError
end
diff --git a/qa/qa/page/sub_menus/create_new_menu.rb b/qa/qa/page/sub_menus/create_new_menu.rb
new file mode 100644
index 00000000000..1f8641827be
--- /dev/null
+++ b/qa/qa/page/sub_menus/create_new_menu.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module SubMenus
+ module CreateNewMenu
+ extend QA::Page::PageConcern
+
+ def self.prepended(base)
+ super
+
+ base.class_eval do
+ include QA::Page::SubMenus::Common
+
+ view 'app/helpers/sidebars_helper.rb' do
+ element :create_menu_item
+ end
+ end
+ end
+
+ def go_to_create_project
+ within_new_item_menu do
+ click_element(:create_menu_item, create_menu_item: 'general_new_project')
+ end
+ end
+
+ def go_to_create_snippet
+ within_new_item_menu do
+ click_element(:create_menu_item, create_menu_item: 'general_new_snippet')
+ end
+ end
+
+ def go_to_create_group
+ within_new_item_menu do
+ click_element(:create_menu_item, create_menu_item: 'general_new_group')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb b/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb
new file mode 100644
index 00000000000..fcfc1e1c76c
--- /dev/null
+++ b/qa/qa/page/sub_menus/super_sidebar/context_switcher.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module SubMenus
+ module SuperSidebar
+ module ContextSwitcher
+ extend QA::Page::PageConcern
+
+ def self.prepended(base)
+ super
+
+ base.class_eval do
+ view 'app/assets/javascripts/super_sidebar/components/super_sidebar.vue' do
+ element :context_switcher
+ element :context_section
+ end
+ end
+ end
+
+ def go_to_your_work
+ go_to_context("Your work")
+ end
+
+ def go_to_explore
+ go_to_context("Explore")
+ end
+
+ def go_to_admin_area
+ go_to_context("Admin")
+ end
+
+ private
+
+ def go_to_context(sub_menu)
+ click_element(:context_switcher) unless has_element?(:context_section, wait: 0)
+
+ within_element(:context_section) do
+ click_element(:nav_item_link, submenu_item: sub_menu)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/sub_menus/super_sidebar/main.rb b/qa/qa/page/sub_menus/super_sidebar/main.rb
new file mode 100644
index 00000000000..aadb24369ea
--- /dev/null
+++ b/qa/qa/page/sub_menus/super_sidebar/main.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module SubMenus
+ module SuperSidebar
+ module Main
+ extend QA::Page::PageConcern
+
+ def go_to_issues
+ click_element(:nav_item_link, submenu_item: 'Issues')
+ end
+
+ def go_to_merge_requests
+ click_element(:nav_item_link, submenu_item: 'Merge requests')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/sub_menus/super_sidebar/manage.rb b/qa/qa/page/sub_menus/super_sidebar/manage.rb
new file mode 100644
index 00000000000..535b29e607f
--- /dev/null
+++ b/qa/qa/page/sub_menus/super_sidebar/manage.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module SubMenus
+ module SuperSidebar
+ module Manage
+ extend QA::Page::PageConcern
+
+ def go_to_activity
+ open_manage_submenu('Activity')
+ end
+
+ def go_to_members
+ open_manage_submenu('Members')
+ end
+
+ def go_to_labels
+ open_manage_submenu('Labels')
+ end
+
+ def go_to_milestones
+ open_manage_submenu('Milestones')
+ end
+
+ private
+
+ def open_manage_submenu(sub_menu)
+ open_submenu('Manage', sub_menu)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/sub_menus/super_sidebar/plan.rb b/qa/qa/page/sub_menus/super_sidebar/plan.rb
new file mode 100644
index 00000000000..e4b9fcf099c
--- /dev/null
+++ b/qa/qa/page/sub_menus/super_sidebar/plan.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module SubMenus
+ module SuperSidebar
+ module Plan
+ extend QA::Page::PageConcern
+
+ def go_to_issue_boards
+ open_plan_submenu("Issue boards")
+ end
+
+ def go_to_service_desk
+ open_plan_submenu("Service Desk")
+ end
+
+ def go_to_wiki
+ open_plan_submenu("Wiki")
+ end
+
+ private
+
+ def open_plan_submenu(sub_menu)
+ open_submenu("Plan", sub_menu)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/sub_menus/super_sidebar/settings.rb b/qa/qa/page/sub_menus/super_sidebar/settings.rb
new file mode 100644
index 00000000000..910e1c2ffdf
--- /dev/null
+++ b/qa/qa/page/sub_menus/super_sidebar/settings.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module SubMenus
+ module SuperSidebar
+ module Settings
+ extend QA::Page::PageConcern
+
+ def go_to_general_settings
+ open_settings_submenu('General')
+ end
+
+ def go_to_integrations_settings
+ open_settings_submenu('Integrations')
+ end
+
+ def go_to_webhooks_settings
+ open_settings_submenu('Webhooks')
+ end
+
+ def go_to_access_token_settings
+ open_settings_submenu('Access Tokens')
+ end
+
+ def go_to_repository_settings
+ open_settings_submenu('Repository')
+ end
+
+ def go_to_ci_cd_settings
+ open_settings_submenu('CI/CD')
+ end
+
+ private
+
+ def open_settings_submenu(sub_menu)
+ open_submenu('Settings', sub_menu)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index cbb68cccdf1..3f9d2b92a0a 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -114,8 +114,9 @@ module QA
body = flatten_hash(parse_body(graphql_response))
unless graphql_response.code == HTTP_STATUS_OK && (body[:errors].nil? || body[:errors].empty?)
+ action = post_body =~ /mutation {\s+destroy/ ? 'Deletion' : 'Fabrication'
raise(ResourceFabricationFailedError, <<~MSG.strip)
- Fabrication of #{self.class.name} using the API failed (#{graphql_response.code}) with `#{graphql_response}`.
+ #{action} of #{self.class.name} using the API failed (#{graphql_response.code}) with `#{graphql_response}`.
#{QA::Support::Loglinking.failure_metadata(graphql_response.headers[:x_request_id])}
MSG
end
@@ -157,17 +158,21 @@ module QA
end
def api_delete
- request = Runtime::API::Request.new(api_client, api_delete_path)
- response = delete(request.url)
+ if api_delete_path == "/graphql"
+ api_post_to(api_delete_path, api_delete_body)
+ else
+ request = Runtime::API::Request.new(api_client, api_delete_path)
+ response = delete(request.url)
- unless [HTTP_STATUS_NO_CONTENT, HTTP_STATUS_ACCEPTED].include? response.code
- raise(ResourceNotDeletedError, <<~MSG.strip)
- Resource at #{request.mask_url} could not be deleted (#{response.code}): `#{response}`.
- #{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}
- MSG
- end
+ unless [HTTP_STATUS_NO_CONTENT, HTTP_STATUS_ACCEPTED].include? response.code
+ raise(ResourceNotDeletedError, <<~MSG.strip)
+ Resource at #{request.mask_url} could not be deleted (#{response.code}): `#{response}`.
+ #{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}
+ MSG
+ end
- response
+ response
+ end
end
def resource_web_url(resource)
diff --git a/qa/qa/resource/ci_variable.rb b/qa/qa/resource/ci_variable.rb
index b632446623d..4123b8fe62b 100644
--- a/qa/qa/resource/ci_variable.rb
+++ b/qa/qa/resource/ci_variable.rb
@@ -18,19 +18,6 @@ module QA
@variable_type = 'env_var'
end
- def fabricate!
- project.visit!
-
- Page::Project::Menu.perform(&:go_to_ci_cd_settings)
-
- Page::Project::Settings::CiCd.perform do |setting|
- setting.expand_ci_variables do |page|
- page.click_add_variable
- page.fill_variable(key, value, masked)
- end
- end
- end
-
def fabricate_via_api!
resource_web_url(api_get)
rescue ResourceNotFoundError
diff --git a/qa/qa/resource/events/project.rb b/qa/qa/resource/events/project.rb
index 410edd417c1..c1bd921c3cf 100644
--- a/qa/qa/resource/events/project.rb
+++ b/qa/qa/resource/events/project.rb
@@ -7,32 +7,32 @@ module QA
include Events::Base
def push_events(commit_message)
- QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait for and fetch push events"])
+ QA::Runtime::Logger.info(%Q[#{self.class.name} - wait for and fetch push events"])
fetch_events do
events(action: 'pushed').select { |event| event.dig(:push_data, :commit_title) == commit_message }
end
end
def wait_for_merge(title)
- QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_merge with title "#{title}"])
+ QA::Runtime::Logger.info(%Q[#{self.class.name} - wait_for_merge with title "#{title}"])
wait_for_event do
events(action: 'accepted', target_type: 'merge_request').any? { |event| event[:target_title] == title }
end
end
def wait_for_push(commit_message)
- QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"])
+ QA::Runtime::Logger.info(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"])
wait_for_event do
events(action: 'pushed').any? { |event| event.dig(:push_data, :commit_title) == commit_message }
end
rescue EventNotFoundError
- QA::Runtime::Logger.debug("Push events: #{events(action: 'pushed')}")
+ QA::Runtime::Logger.info("Push events: #{events(action: 'pushed')}")
raise
end
def wait_for_push_new_branch(branch_name = self.default_branch)
- QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push_new_branch with branch_name "#{branch_name}"])
+ QA::Runtime::Logger.info(%Q[#{self.class.name} - wait_for_push_new_branch with branch_name "#{branch_name}"])
wait_for_event do
events(action: 'pushed').any? { |event| event.dig(:push_data, :ref) == branch_name }
end
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index f53bb531d9a..c88cf4aca10 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -57,6 +57,10 @@ module QA
sandbox.visit!
end
+ unless group_show.has_subgroup?(path)
+ raise ResourceFabricationFailedError, "Resource at #{path} could not be found under #{sandbox.path}"
+ end
+
group_show.click_subgroup(path)
@id = group_show.group_id
end
diff --git a/qa/qa/resource/instance_oauth_application.rb b/qa/qa/resource/instance_oauth_application.rb
new file mode 100644
index 00000000000..7aa3661717b
--- /dev/null
+++ b/qa/qa/resource/instance_oauth_application.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class InstanceOauthApplication < Base
+ attr_accessor :name, :redirect_uri, :scopes, :trusted
+
+ attributes :id, :application_id, :application_secret
+
+ def initialize
+ @name = "Instance OAuth Application #{SecureRandom.hex(8)}"
+ @redirect_uri = ''
+ @scopes = []
+ @trusted = true
+ end
+
+ def resource_web_url(resource)
+ super
+ rescue ResourceURLMissingError
+ # this particular resource does not expose a web_url property
+ end
+
+ def api_get_path
+ '/applications'
+ end
+
+ def api_delete_path
+ "/applications/#{id}"
+ end
+
+ def fabricate!
+ Flow::Login.sign_in_as_admin
+ Page::Main::Menu.perform(&:go_to_admin_area)
+ Page::Admin::Menu.perform(&:go_to_applications)
+ Page::Admin::Applications.perform do |app|
+ app.click_new_application_button
+ app.fill_name(name)
+ app.fill_redirect_uri(redirect_uri)
+ app.set_trusted_checkbox(trusted)
+ scopes.each { |scope| app.set_scope(scope) }
+ app.save_application
+ self.application_id = app.get_application_id
+ self.application_secret = app.get_secret_id
+ self.id = app.get_id_of_application
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index 15c2c25757f..fb957ccf285 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -30,7 +30,7 @@ module QA
def fabricate!
project.visit!
- Page::Project::Show.perform(&:go_to_new_issue)
+ Page::Project::Menu.perform(&:go_to_new_issue)
Page::Project::Issue::New.perform do |new_page|
new_page.fill_title(@title)
diff --git a/qa/qa/resource/pipeline.rb b/qa/qa/resource/pipeline.rb
index 7d5036c5cf4..e57784ca3b5 100644
--- a/qa/qa/resource/pipeline.rb
+++ b/qa/qa/resource/pipeline.rb
@@ -28,7 +28,7 @@ module QA
def fabricate!
project.visit!
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
Page::Project::Pipeline::New.perform(&:click_run_pipeline_button)
end
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index 019617325e0..37ff2315329 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -123,12 +123,13 @@ module QA
resource_web_url(api_get)
rescue ResourceNotFoundError
response = super
+ return response unless template_name || import
# If a project is being imported, wait until it completes before we let the test continue.
# Otherwise we see Git repository errors
# See https://gitlab.com/gitlab-org/gitlab/-/issues/356101
- Support::Retrier.retry_until(max_duration: 60, sleep_interval: 5) do
- %w[none finished].include?(reload!.api_resource[:import_status])
+ Support::Retrier.retry_until(max_duration: 60, sleep_interval: 5, retry_on_exception: true) do
+ reload!.api_resource[:import_status] == "finished"
end
response
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index 1e6b2ff620e..ed8074b1440 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -3,7 +3,7 @@
module QA
module Resource
class ProjectImportedFromGithub < Resource::Project
- attr_accessor :issue_events_import, :full_notes_import, :attachments_import
+ attr_accessor :issue_events_import, :full_notes_import, :attachments_import, :allow_partial_import
attribute :github_repo_id do
github_client.repository(github_repository_path).id
@@ -24,7 +24,7 @@ module QA
import_page.select_advanced_option(:attachments_import) if attachments_import
import_page.import!(github_repository_path, group.full_path, name)
- import_page.wait_for_success(github_repository_path, wait: 240)
+ import_page.wait_for_success(github_repository_path, wait: 240, allow_partial_import: allow_partial_import)
end
reload!
diff --git a/qa/qa/resource/runner_base.rb b/qa/qa/resource/runner_base.rb
index 9e38ba9ab64..278729eb50f 100644
--- a/qa/qa/resource/runner_base.rb
+++ b/qa/qa/resource/runner_base.rb
@@ -36,7 +36,8 @@ module QA
@run_untagged = nil
@name = "qa-runner-#{SecureRandom.hex(4)}"
@executor = :shell
- @executor_image = 'registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7'
+ @executor_image = "#{QA::Runtime::Env.container_registry_host}/
+ gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7"
end
# Initially we only support fabricate via API
diff --git a/qa/qa/resource/snippet.rb b/qa/qa/resource/snippet.rb
index 84711075442..df9843bcfca 100644
--- a/qa/qa/resource/snippet.rb
+++ b/qa/qa/resource/snippet.rb
@@ -22,9 +22,7 @@ module QA
end
def fabricate!
- Page::Main::Menu.perform(&:go_to_snippets)
-
- Page::Dashboard::Snippet::Index.perform(&:go_to_new_snippet_page)
+ Page::Main::Menu.perform(&:go_to_create_snippet)
Page::Dashboard::Snippet::New.perform do |new_page|
new_page.fill_title(@title)
diff --git a/qa/qa/runtime/application_settings.rb b/qa/qa/runtime/application_settings.rb
index 53ed6a9266b..4cbce0972b6 100644
--- a/qa/qa/runtime/application_settings.rb
+++ b/qa/qa/runtime/application_settings.rb
@@ -22,7 +22,8 @@ module QA
r = put(Runtime::API::Request.new(api_client, APPLICATION_SETTINGS_PATH).url, **application_settings)
return if r.code == QA::Support::API::HTTP_STATUS_OK
- raise "Couldn't set application settings #{application_settings.inspect}"
+ body = parse_body(r)
+ raise("Couldn't set application settings #{application_settings.inspect}, code: '#{r.code}', body: #{body}")
end
def get_application_settings(api_client: admin_api_client)
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index 945823fb9c0..b67db792419 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -17,6 +17,9 @@ module QA
NotRespondingError = Class.new(RuntimeError)
CAPYBARA_MAX_WAIT_TIME = Env.max_capybara_wait_time
+ DEFAULT_WINDOW_SIZE = '1480,2200'
+ PHONE_VIDEO_SIZE = '500x900'
+ TABLET_VIDEO_SIZE = '800x1100'
def self.blank_page?
['', 'about:blank', 'data:,'].include?(Capybara.current_session.driver.browser.current_url)
@@ -96,11 +99,14 @@ module QA
capabilities['goog:chromeOptions'][:args] << 'disable-dev-shm-usage' if QA::Runtime::Env.disable_dev_shm?
# Set chrome default download path
-
- capabilities['goog:chromeOptions'][:prefs] = {
- 'download.default_directory' => File.expand_path(QA::Runtime::Env.chrome_default_download_path),
- 'download.prompt_for_download' => false
- }
+ # TODO: Set for remote grid as well once Sauce Labs tests are deprecated and Options.chrome is added
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112258
+ unless QA::Runtime::Env.remote_grid
+ capabilities['goog:chromeOptions'][:prefs] = {
+ 'download.default_directory' => File.expand_path(QA::Runtime::Env.chrome_default_download_path),
+ 'download.prompt_for_download' => false
+ }
+ end
# Specify the user-agent to allow challenges to be bypassed
# See https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/11938
@@ -114,7 +120,7 @@ module QA
capabilities['appium:deviceName'] = QA::Runtime::Env.remote_mobile_device_name
capabilities['appium:platformVersion'] = 'latest'
else
- capabilities['goog:chromeOptions'][:args] << 'window-size=1480,2200'
+ capabilities['goog:chromeOptions'][:args] << "window-size=#{DEFAULT_WINDOW_SIZE}"
end
# Slack tries to open an external URL handler
@@ -159,6 +165,9 @@ module QA
when :firefox
capabilities['acceptInsecureCerts'] = true if QA::Runtime::Env.accept_insecure_certs?
+
+ when :edge
+ capabilities['ms:edgeOptions'] = { args: ["--window-size=#{DEFAULT_WINDOW_SIZE}"] }
end
# Use the same profile on QA runs if CHROME_REUSE_PROFILE is true.
@@ -174,10 +183,21 @@ module QA
if QA::Runtime::Env.remote_grid
selenium_options[:browser] = :remote
selenium_options[:url] = QA::Runtime::Env.remote_grid
- capabilities[:browserVersion] = 'latest'
+ capabilities[:browserVersion] = QA::Runtime::Env.browser_version
+ end
+
+ if QA::Runtime::Env.remote_tunnel_id
capabilities['sauce:options'] = { tunnelIdentifier: QA::Runtime::Env.remote_tunnel_id }
end
+ if QA::Runtime::Env.record_video?
+ capabilities['selenoid:options'] = {
+ enableVideo: true,
+ videoScreenSize: video_screen_size,
+ videoName: "#{QA::Runtime::Env.browser}-#{QA::Runtime::Env.browser_version}-#{Time.now}.mp4"
+ }
+ end
+
Capybara::Selenium::Driver.new(
app,
**selenium_options
@@ -233,6 +253,16 @@ module QA
::File.expand_path('../../tmp/qa-profile', __dir__)
end
+ def self.video_screen_size
+ if QA::Runtime::Env.phone_layout?
+ PHONE_VIDEO_SIZE
+ elsif QA::Runtime::Env.tablet_layout?
+ TABLET_VIDEO_SIZE
+ else
+ ''
+ end
+ end
+
class Session
include Capybara::DSL
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 810912c7ccf..cde36ba80c4 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -58,6 +58,22 @@ module QA
browser == :chrome && interception_enabled?
end
+ def release
+ ENV['RELEASE']
+ end
+
+ def release_registry_url
+ ENV['RELEASE_REGISTRY_URL']
+ end
+
+ def release_registry_username
+ ENV['RELEASE_REGISTRY_USERNAME']
+ end
+
+ def release_registry_password
+ ENV['RELEASE_REGISTRY_PASSWORD']
+ end
+
def ci_job_url
ENV['CI_JOB_URL']
end
@@ -187,14 +203,38 @@ module QA
ENV['QA_BROWSER'].nil? ? :chrome : ENV['QA_BROWSER'].to_sym
end
+ def browser_version
+ ENV['QA_BROWSER_VERSION'] || 'latest'
+ end
+
def remote_mobile_device_name
- ENV['QA_REMOTE_MOBILE_DEVICE_NAME']
+ ENV['QA_REMOTE_MOBILE_DEVICE_NAME']&.downcase
+ end
+
+ def layout
+ ENV['QA_LAYOUT']&.downcase || ''
+ end
+
+ def tablet_layout?
+ return true if remote_mobile_device_name && !phone_layout?
+
+ layout.include?('tablet')
+ end
+
+ def phone_layout?
+ return true if layout.include?('phone')
+
+ return false unless remote_mobile_device_name
+
+ !(remote_mobile_device_name.include?('ipad') || remote_mobile_device_name.include?('tablet'))
end
def mobile_layout?
- return false if ENV['QA_REMOTE_MOBILE_DEVICE_NAME'].blank?
+ phone_layout? || tablet_layout? || remote_mobile_device_name
+ end
- !(ENV['QA_REMOTE_MOBILE_DEVICE_NAME'].downcase.include?('ipad') || ENV['QA_REMOTE_MOBILE_DEVICE_NAME'].downcase.include?('tablet'))
+ def record_video?
+ enabled?(ENV['QA_RECORD_VIDEO'], default: false)
end
def user_username
@@ -210,11 +250,11 @@ module QA
end
def github_username
- ENV['GITHUB_USERNAME']
+ ENV['QA_GITHUB_USERNAME']
end
def github_password
- ENV['GITHUB_PASSWORD']
+ ENV['QA_GITHUB_PASSWORD']
end
def forker?
@@ -282,11 +322,11 @@ module QA
end
def jira_admin_username
- ENV['JIRA_ADMIN_USERNAME']
+ ENV['QA_JIRA_ADMIN_USERNAME']
end
def jira_admin_password
- ENV['JIRA_ADMIN_PASSWORD']
+ ENV['QA_JIRA_ADMIN_PASSWORD']
end
def jira_hostname
@@ -489,6 +529,10 @@ module QA
enabled?(ENV['QA_SKIP_SMOKE_RELIABLE'], default: false)
end
+ def container_registry_host
+ ENV.fetch('QA_CONTAINER_REGISTRY_HOST', 'registry.gitlab.com')
+ end
+
# ENV variables for authenticating against a private container registry
# These need to be set if using the
# Service::DockerRun::Mixins::ThirdPartyDocker module
@@ -537,6 +581,22 @@ module QA
raise "Missing Slack env: #{missing_env.map(&:upcase).join(', ')}"
end
+ def one_p_email
+ ENV['QA_1P_EMAIL']
+ end
+
+ def one_p_password
+ ENV['QA_1P_PASSWORD']
+ end
+
+ def one_p_secret
+ ENV['QA_1P_SECRET']
+ end
+
+ def one_p_github_uuid
+ ENV['QA_1P_GITHUB_UUID']
+ end
+
private
def remote_grid_credentials
diff --git a/qa/qa/service/docker_run/base.rb b/qa/qa/service/docker_run/base.rb
index bf85b640586..ce558849abd 100644
--- a/qa/qa/service/docker_run/base.rb
+++ b/qa/qa/service/docker_run/base.rb
@@ -85,6 +85,10 @@ module QA
shell "docker restart #{@name}"
end
+
+ def health
+ shell("docker inspect --format='{{json .State.Health.Status}}' #{@name}").delete('"')
+ end
end
end
end
diff --git a/qa/qa/service/docker_run/gitlab.rb b/qa/qa/service/docker_run/gitlab.rb
new file mode 100644
index 00000000000..4fbe6603d5b
--- /dev/null
+++ b/qa/qa/service/docker_run/gitlab.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module QA
+ module Service
+ module DockerRun
+ class Gitlab < Base
+ def initialize(name:, omnibus_config: '', image: '')
+ @image = image
+ @name = name
+ @omnibus_configuration = omnibus_config
+ super()
+ end
+
+ def login
+ super(Runtime::Env.release_registry_url,
+ user: Runtime::Env.release_registry_username,
+ password: Runtime::Env.release_registry_password)
+ end
+
+ def register!
+ shell <<~CMD.tr("\n", ' ')
+ docker run -d --rm
+ --network #{network}
+ --hostname #{host_name}
+ --publish 80:80
+ #{RUBY_PLATFORM.include?('arm64') ? '--platform linux/amd64' : ''}
+ --env GITLAB_OMNIBUS_CONFIG="#{@omnibus_configuration}"
+ --name #{@name}
+ #{@image}
+ CMD
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/service/docker_run/gitlab_runner.rb b/qa/qa/service/docker_run/gitlab_runner.rb
index d40517ae535..078a3048cad 100644
--- a/qa/qa/service/docker_run/gitlab_runner.rb
+++ b/qa/qa/service/docker_run/gitlab_runner.rb
@@ -16,11 +16,12 @@ module QA
MSG
def initialize(name)
- @image = 'registry.gitlab.com/gitlab-org/gitlab-runner:alpine'
+ @image = "#{QA::Runtime::Env.container_registry_host}/gitlab-org/gitlab-runner:alpine"
@name = name || "qa-runner-#{SecureRandom.hex(4)}"
@run_untagged = true
@executor = :shell
- @executor_image = 'registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7'
+ @executor_image = "#{QA::Runtime::Env.container_registry_host}/
+ gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7"
super()
end
@@ -104,7 +105,15 @@ module QA
# Ping Cloudflare DNS, should fail
# Ping Registry, should fail to resolve
def prove_airgap
- gitlab_ip = Resolv.getaddress 'registry.gitlab.com'
+ begin
+ gitlab_ip = Resolv.getaddress 'registry.gitlab.com'
+ rescue Resolv::ResolvError => e
+ Runtime::Logger.debug("prove_airgap unable to get ip address for endpoint - #{e.message}")
+ # If Resolv.getaddress fails, it implies we cannot access the URL in question
+ # This may occur in offline-environment/airgapped testing
+ return 'true'
+ end
+
<<~CMD
echo "Checking airgapped connectivity..."
nc -zv -w 10 #{gitlab_ip} 80 && (echo "Airgapped network faulty. Connectivity netcat check failed." && exit 1) || (echo "Connectivity netcat check passed." && exit 0)
diff --git a/qa/qa/service/docker_run/k3s.rb b/qa/qa/service/docker_run/k3s.rb
index a09b62cb613..f2463c39639 100644
--- a/qa/qa/service/docker_run/k3s.rb
+++ b/qa/qa/service/docker_run/k3s.rb
@@ -7,7 +7,8 @@ module QA
attr_accessor :cni_enabled
def initialize
- @image = 'registry.gitlab.com/gitlab-org/cluster-integration/test-utils/k3s-gitlab-ci/releases/v0.9.1'
+ @image = "#{QA::Runtime::Env.container_registry_host}/
+ gitlab-org/cluster-integration/test-utils/k3s-gitlab-ci/releases/v0.9.1"
@name = 'k3s'
@cni_enabled = false
super
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 e0db758dde3..fc400fbb9c7 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
@@ -26,6 +26,9 @@ module QA
file.name = "text-#{SecureRandom.hex(8)}.txt"
file.content = 'New file'
end
+ rescue StandardError => e
+ QA::Runtime::Logger.error("Full failure message: #{e.message}")
+ raise
end.not_to raise_error
end
@@ -42,6 +45,9 @@ module QA
commit.commit_message = 'Add new file'
commit.add_files([{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }])
end
+ rescue StandardError => e
+ QA::Runtime::Logger.error("Full failure message: #{e.message}")
+ raise
end.not_to raise_error
end
end
diff --git a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
index 407e479bda2..ed26061f3f8 100644
--- a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb
@@ -1,7 +1,11 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', product_group: :import do
+ RSpec.describe 'Manage', product_group: :import,
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/407297',
+ type: :investigating
+ } do
describe 'GitHub import' do
include_context 'with github import'
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 43701a6b740..040c92f296f 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
@@ -6,19 +6,19 @@ module QA
include_context 'with gitlab project migration'
# this spec is used as a sanity test for gitlab migration because it can run outside of orchestrated setup
- context 'with import within same instance', :reliable, orchestrated: false, import: false do
+ context 'with import within same instance', orchestrated: false, import: false do
let!(:source_project_with_readme) { true }
let!(:source_gitlab_address) { Runtime::Scenario.gitlab_address }
let!(:source_admin_api_client) { admin_api_client }
+ # do not use top level group (sandbox) to avoid issues when applying permissions etc. because it will contain
+ # a lot subgroups and projects on live envs
let!(:source_sandbox) do
- Resource::Sandbox.fabricate_via_api! do |group|
+ Resource::Group.fabricate_via_api! do |group|
group.api_client = admin_api_client
end
end
- let!(:target_sandbox) { source_sandbox }
-
let!(:source_group) do
Resource::Group.fabricate_via_api! do |group|
group.api_client = admin_api_client
@@ -28,6 +28,8 @@ module QA
end
end
+ let!(:target_sandbox) { source_sandbox }
+
let(:destination_group_path) { "target-group-for-import-#{SecureRandom.hex(4)}" }
let(:cleanup!) { user.remove_via_api! }
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 d693bbd43ff..eeeb78e17d7 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
@@ -24,6 +24,9 @@ module QA
file.name = "text-#{SecureRandom.hex(8)}.txt"
file.content = 'New file'
end
+ rescue StandardError => e
+ QA::Runtime::Logger.error("Full failure message: #{e.message}")
+ raise
end.not_to raise_error
end
@@ -37,6 +40,9 @@ module QA
commit.commit_message = 'Add new file'
commit.add_files([{ file_path: "text-#{SecureRandom.hex(8)}.txt", content: 'new file' }])
end
+ rescue StandardError => e
+ QA::Runtime::Logger.error("Full failure message: #{e.message}")
+ raise
end.not_to raise_error
end
end
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 b7d0d72297a..8759c36f43f 100644
--- a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
@@ -2,7 +2,8 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin, :reliable, product_group: :authentication_and_authorization do
+ # TODO: `:reliable` should be added back once https://gitlab.com/gitlab-org/gitlab/-/issues/359278 is resolved
+ describe 'User', :requires_admin, product_group: :authentication_and_authorization do
before(:all) do
admin_api_client = Runtime::API::Client.as_admin
@@ -12,14 +13,20 @@ module QA
@user_api_client = Runtime::API::Client.new(:gitlab, user: @user)
- @group = QA::Resource::Group.fabricate_via_api! do |group|
+ @sandbox = Resource::Sandbox.fabricate! do |sandbox_group|
+ sandbox_group.path = "sandbox-for-access-termination-#{SecureRandom.hex(4)}"
+ sandbox_group.api_client = admin_api_client
+ end
+
+ group = QA::Resource::Group.fabricate_via_api! do |group|
group.path = "group-to-test-access-termination-#{SecureRandom.hex(8)}"
+ group.sandbox = @sandbox
end
- @group.sandbox.add_member(@user)
+ @sandbox.add_member(@user)
@project = Resource::Project.fabricate_via_api! do |project|
- project.group = @group
+ project.group = group
project.name = "project-for-user-group-access-termination"
project.initialize_with_readme = true
end
@@ -27,7 +34,7 @@ module QA
context 'after parent group membership termination' do
before do
- @group.sandbox.remove_member(@user)
+ @sandbox.remove_member(@user)
end
it 'is not allowed to push code via the CLI', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347863' do
@@ -77,9 +84,7 @@ module QA
end
after(:all) do
- @user.remove_via_api!
- @project.remove_via_api!
- @group.remove_via_api!
+ @sandbox.remove_via_api!
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb b/qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb
index c50eb2f4fdf..48e9d3dc164 100644
--- a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/api/9_data_stores/user_inherited_access_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'User', :requires_admin, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'User', :requires_admin, product_group: :tenant_scale do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:parent_group) do
@@ -41,6 +41,10 @@ module QA
parent_group.add_member(parent_group_user)
end
+ after do
+ parent_group_user.remove_via_api!
+ end
+
it(
'is allowed to push code to sub-group project via the CLI',
:reliable,
@@ -98,10 +102,6 @@ module QA
end.not_to raise_error
end
end
-
- after do
- parent_group_user.remove_via_api!
- end
end
context 'when added to sub-group' do
@@ -127,6 +127,10 @@ module QA
sub_group.add_member(sub_group_user)
end
+ after do
+ sub_group_user.remove_via_api!
+ end
+
it(
'is not allowed to push code to parent group project via the CLI',
:reliable,
@@ -177,10 +181,6 @@ module QA
end.to raise_error(Resource::ApiFabricator::ResourceFabricationFailedError,
/403 Forbidden - You are not allowed to push into this branch/)
end
-
- after do
- sub_group_user.remove_via_api!
- end
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/users_spec.rb b/qa/qa/specs/features/api/9_data_stores/users_spec.rb
index 08e1b7a1e0c..4be20bd1932 100644
--- a/qa/qa/specs/features/api/1_manage/users_spec.rb
+++ b/qa/qa/specs/features/api/9_data_stores/users_spec.rb
@@ -3,8 +3,8 @@
require 'airborne'
module QA
- RSpec.describe 'Manage' do
- describe 'Users API', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Users API', :reliable, product_group: :tenant_scale do
let(:api_client) { Runtime::API::Client.new(:gitlab) }
let(:request) { Runtime::API::Request.new(api_client, '/users') }
@@ -14,7 +14,8 @@ module QA
expect_status(200)
end
- it 'GET /users/:username with a valid username', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347886' do
+ it 'GET /users/:username with a valid username',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347886' do
get request.url, { params: { username: Runtime::User.username } }
expect_status(200)
@@ -23,7 +24,8 @@ module QA
)
end
- it 'GET /users/:username with an invalid username', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347883' do
+ it 'GET /users/:username with an invalid username',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347883' do
get request.url, { params: { username: SecureRandom.hex(10) } }
expect_status(200)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb
index b5a8df15ddc..d92d8de5567 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb
@@ -37,7 +37,11 @@ module QA
end
end
- it 'imports a project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do
+ it 'imports a project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877',
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/405127',
+ type: :investigating
+ } do
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(Runtime::Env.github_access_token)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
index 7e46276be92..f4042795995 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/integrations/jira/jira_issue_import_spec.rb
@@ -18,14 +18,12 @@ module QA
set_up_jira_integration
import_jira_issues
- QA::Support::Retrier.retry_on_exception do
- Page::Project::Menu.perform(&:click_issues)
-
- Page::Project::Issue::Index.perform do |issues_page|
- expect(issues_page).to have_content("2 issues successfully imported")
-
- issues_page.click_issue_link(jira_issue_title)
- end
+ Page::Project::Menu.perform(&:go_to_issues)
+ Page::Project::Issue::Index.perform do |issues_page|
+ expect { issues_page }.to eventually_have_content(jira_issue_title).within(
+ max_attempts: 5, sleep_interval: 1, reload_page: issues_page
+ )
+ issues_page.click_issue_link(jira_issue_title)
end
expect(page).to have_content(jira_issue_description)
@@ -58,7 +56,7 @@ module QA
end
def import_jira_issues
- Page::Project::Menu.perform(&:click_issues)
+ Page::Project::Menu.perform(&:go_to_issues)
Page::Project::Issue::Index.perform(&:go_to_jira_import_form)
Page::Project::Issue::JiraImport.perform do |form|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oidc_with_gitlab_as_idp_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oidc_with_gitlab_as_idp_spec.rb
new file mode 100644
index 00000000000..268bd6fdbf0
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/login_via_oidc_with_gitlab_as_idp_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Manage', :skip_live_env, requires_admin: 'creates users and instance OAuth application',
+ product_group: :authentication_and_authorization do
+ let!(:user) { Resource::User.fabricate_via_api! }
+ let(:oidc_consumer_name) { 'gitlab-oidc-consumer' }
+ let(:oidc_consumer_host) { "http://#{oidc_consumer_name}.#{Runtime::Env.running_in_ci? ? 'test' : 'bridge'}" }
+ let(:instance_oauth_app) do
+ Resource::InstanceOauthApplication.fabricate! do |application|
+ application.redirect_uri = "#{oidc_consumer_host}/users/auth/openid_connect/callback"
+ application.scopes = %w[openid profile email]
+ end
+ end
+
+ after do
+ instance_oauth_app.remove_via_api!
+ remove_gitlab_service(oidc_consumer_name)
+ end
+
+ # The host GitLab instance with address Runtime::Scenario.gitlab_address is the OIDC idP - OIDC application will be
+ # created here.
+ # GitLab instance stood up in docker with address gitlab-oidc-consumer.test (or gitlab-oidc-consumer.bridge) is
+ # the consumer - The GitLab OIDC Login button will be displayed here.
+ describe 'OIDC' do
+ it(
+ 'creates GitLab OIDC application and uses it to login',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/405137'
+ ) do
+ instance_oauth_app
+
+ Page::Main::Menu.perform(&:sign_out_if_signed_in)
+
+ app_id = instance_oauth_app.application_id
+ app_secret = instance_oauth_app.application_secret
+
+ consumer_gitlab_service = run_gitlab_service(name: oidc_consumer_name, app_id: app_id, app_secret: app_secret)
+
+ wait_for_service(consumer_gitlab_service)
+
+ page.visit oidc_consumer_host
+
+ expect(page.driver.current_url).to include(oidc_consumer_host)
+
+ Page::Main::Login.perform(&:sign_in_with_oidc)
+
+ expect(page.driver.current_url).to include(Runtime::Scenario.gitlab_address)
+
+ Flow::Login.sign_in(as: user)
+
+ expect(page.driver.current_url).to include(oidc_consumer_host)
+
+ Page::Dashboard::Welcome.perform do |welcome|
+ expect(welcome).to have_welcome_title("Welcome to GitLab")
+ end
+ end
+
+ def run_gitlab_service(name:, app_id:, app_secret:)
+ Service::DockerRun::Gitlab.new(
+ image: Runtime::Env.release,
+ name: name,
+ omnibus_config: omnibus_configuration(app_id: app_id, app_secret: app_secret)).tap do |gitlab|
+ gitlab.login
+ gitlab.pull
+ gitlab.register!
+ end
+ end
+
+ def remove_gitlab_service(name)
+ Service::DockerRun::Gitlab.new(name: name).remove!
+ end
+
+ def wait_for_service(service)
+ Support::Waiter.wait_until(max_duration: 900, sleep_interval: 5, raise_on_failure: true) do
+ service.health == "healthy"
+ end
+ end
+
+ def omnibus_configuration(app_id:, app_secret:)
+ <<~OMNIBUS
+ gitlab_rails['initial_root_password']='5iveL\!fe';
+ gitlab_rails['omniauth_enabled'] = true;
+ gitlab_rails['omniauth_allow_single_sign_on'] = true;
+ gitlab_rails['omniauth_block_auto_created_users'] = false;
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: 'openid_connect',
+ label: 'GitLab OIDC',
+ args: {
+ name: 'openid_connect',
+ scope: ['openid','profile','email'],
+ response_type: 'code',
+ issuer: '#{Runtime::Scenario.gitlab_address}',
+ discovery: false,
+ uid_field: 'preferred_username',
+ send_scope_to_token_endpoint: 'false',
+ client_options: {
+ identifier: '#{app_id}',
+ secret: '#{app_secret}',
+ redirect_uri: '#{oidc_consumer_host}/users/auth/openid_connect/callback',
+ jwks_uri: '#{Runtime::Scenario.gitlab_address}/oauth/discovery/keys',
+ userinfo_endpoint: '#{Runtime::Scenario.gitlab_address}/oauth/userinfo',
+ token_endpoint: '#{Runtime::Scenario.gitlab_address}/oauth/token',
+ authorization_endpoint: '#{Runtime::Scenario.gitlab_address}/oauth/authorize'
+ }
+ }
+ }
+ ];
+ OMNIBUS
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_github_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_github_spec.rb
new file mode 100644
index 00000000000..3ac050c1649
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_github_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Manage', :orchestrated, :oauth, product_group: :authentication_and_authorization do
+ describe 'OAuth' do
+ it 'connects and logs in with GitHub OAuth',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/402405' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+
+ Page::Main::Login.perform(&:sign_in_with_github)
+
+ Vendor::Github::Page::Login.perform(&:login)
+
+ expect(page).to have_content('Welcome to GitLab')
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index e2fd0ec9cef..821f885c4c8 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -26,7 +26,7 @@ module QA
) do
issue = Resource::Issue.fabricate_via_browser_ui! { |issue| issue.project = project }
- Page::Project::Menu.perform(&:click_issues)
+ Page::Project::Menu.perform(&:go_to_issues)
Page::Project::Issue::Index.perform do |index|
expect(index).to have_issue(issue)
@@ -46,7 +46,7 @@ module QA
expect(issue_page).to have_reopen_issue_button
end
- Page::Project::Menu.perform(&:click_issues)
+ Page::Project::Menu.perform(&:go_to_issues)
Page::Project::Issue::Index.perform do |index|
expect(index).not_to have_issue(closed_issue)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
index 61fd743f920..275f3a52f17 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/export_as_csv_spec.rb
@@ -19,7 +19,7 @@ module QA
end
project.visit!
- Page::Project::Menu.perform(&:click_issues)
+ Page::Project::Menu.perform(&:go_to_issues)
end
it 'successfully exports issues list as CSV', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347968' do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
index 45541939606..c85ea5e8a69 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
@@ -14,7 +14,7 @@ module QA
end
it 'shows issue suggestions when creating a new issue', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347995' do
- Page::Project::Show.perform(&:go_to_new_issue)
+ Page::Project::Menu.perform(&:go_to_new_issue)
Page::Project::Issue::New.perform do |new_page|
new_page.fill_title("issue")
expect(new_page).to have_content(issue_title)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
index 83e178ae4c3..7377b0ff8af 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue_boards/focus_mode_spec.rb
@@ -16,7 +16,7 @@ module QA
it 'focuses on issue board', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347996' do
project.visit!
- Page::Project::Menu.perform(&:go_to_boards)
+ Page::Project::Menu.perform(&:go_to_issue_boards)
Page::Component::IssueBoard::Show.perform do |show|
show.click_focus_mode_button
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
index d27ec32fdda..56e1f3d4a9a 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
@@ -17,11 +17,7 @@ module QA
merge_request.fork.remove_via_api!
end
- it 'can merge feature branch fork to mainline', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347818', quarantine: {
- only: :production,
- type: :investigating,
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/372258'
- } do
+ it 'can merge source branch from fork into upstream repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347818' do
merge_request.visit!
Page::MergeRequest::Show.perform do |merge_request|
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
index 1b82543a5d4..38831f6f158 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb
@@ -50,7 +50,10 @@ module QA
runner&.remove_via_api!
end
- it 'merges after pipeline succeeds' do
+ it 'merges after pipeline succeeds', quarantine: {
+ type: :flaky,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/403017'
+ } do
transient_test = repeat > 1
repeat.times do |i|
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
index a969b48f0fc..748b989deb8 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
@@ -15,7 +15,7 @@ module QA
merge_request.visit!
end
- it 'views the merge request email patches', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347742' do
+ it 'views the merge request patches', :can_use_large_setup, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347742' do
Page::MergeRequest::Show.perform(&:view_email_patches)
expect(page.text).to start_with('From')
diff --git a/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb b/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb
index a214af19fca..7dc9e95bcd2 100644
--- a/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb
@@ -2,15 +2,14 @@
module QA
RSpec.describe 'Create',
- :gitlab_pages,
- :orchestrated,
- except: { job: 'review-qa-*' },
- quarantine: {
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/383215',
- type: :test_environment,
- only: { subdomain: 'staging-ref' }
- },
- feature_flag: { name: 'show_pages_in_deployments_menu' } do
+ :gitlab_pages,
+ :orchestrated,
+ except: { job: 'review-qa-*' },
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/383215',
+ type: :flaky
+ },
+ feature_flag: { name: 'show_pages_in_deployments_menu' } do
# TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300906
describe 'Pages', product_group: :editor do
let!(:project) do
@@ -23,9 +22,10 @@ module QA
let(:pipeline) do
Resource::Pipeline.fabricate_via_api! do |pipeline|
pipeline.project = project
- pipeline.variables =
+ pipeline.variables = [
{ key: :CI_PAGES_DOMAIN, value: 'nip.io', variable_type: :env_var },
{ key: :CI_PAGES_URL, value: 'http://127.0.0.1.nip.io', variable_type: :env_var }
+ ]
end
end
@@ -46,7 +46,7 @@ module QA
end
it 'creates a Pages website',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347669' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347669' do
Page::Project::Pipeline::Show.perform do |show|
expect(show).to have_job(:pages)
show.click_job(:pages)
@@ -56,14 +56,18 @@ module QA
expect(show).to have_passed(timeout: 300)
end
- Page::Project::Show.perform(&:go_to_pages_settings)
- QA::Page::Project::Settings::Pages.perform do |pages|
- pages.go_to_access_page
- Support::Waiter.wait_until(sleep_interval: 2, max_duration: 60, reload_page: page,
- retry_on_exception: true) do
- expect(page).to have_content(
- 'This is a simple plain-HTML website on GitLab Pages, without any fancy static site generator.')
- end
+ Page::Project::Menu.perform(&:go_to_pages_settings)
+ Page::Project::Settings::Pages.perform(&:go_to_access_page)
+
+ Support::Waiter.wait_until(
+ sleep_interval: 2,
+ max_duration: 60,
+ reload_page: page,
+ retry_on_exception: true
+ ) do
+ expect(page).to have_content(
+ 'This is a simple plain-HTML website on GitLab Pages, without any fancy static site generator.'
+ )
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
new file mode 100644
index 00000000000..3d68de30d57
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ describe 'Branch Rules Overview', product_group: :source_code,
+ feature_flag: {
+ name: 'branch_rules',
+ scope: :project
+ },
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/403583',
+ type: :flaky
+ } do
+ let(:branch_name) { 'new-branch' }
+ let(:allowed_to_push_role) { Resource::ProtectedBranch::Roles::NO_ONE }
+ let(:allowed_to_merge_role) { Resource::ProtectedBranch::Roles::MAINTAINERS }
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'branch-rule-project'
+ project.initialize_with_readme = true
+ end
+ end
+
+ before do
+ Runtime::Feature.enable(:branch_rules, project: project)
+
+ Flow::Login.sign_in
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.branch = branch_name
+ commit.start_branch = project.default_branch
+ commit.commit_message = 'First commit'
+ commit.add_files([{ file_path: 'new_file.rb', content: '# new content' }])
+ end
+ end
+
+ after do
+ Runtime::Feature.disable(:branch_rules, project: project)
+ end
+
+ it 'adds a new branch rule', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/397587' do
+ project.visit!
+
+ Page::Project::Menu.perform(&:go_to_repository_settings)
+
+ Page::Project::Settings::Repository.perform(&:expand_branch_rules)
+
+ Page::Project::Settings::BranchRules.perform(&:click_add_branch_rule)
+
+ Page::Project::Settings::ProtectedBranches.perform do |settings|
+ settings.select_branch(branch_name)
+ settings.select_allowed_to_push(roles: allowed_to_push_role)
+ settings.select_allowed_to_merge(roles: allowed_to_merge_role)
+ settings.protect_branch
+ end
+
+ Page::Project::Settings::Repository.perform(&:expand_branch_rules)
+
+ Page::Project::Settings::BranchRules.perform do |rules|
+ expect(rules).to have_content(branch_name)
+ rules.navigate_to_branch_rules_details(branch_name)
+ end
+
+ Page::Project::Settings::BranchRulesDetails.perform do |details|
+ aggregate_failures 'branch rules details' do
+ expect(details).to have_allowed_to_push(allowed_to_push_role[:description])
+ expect(details).to have_allowed_to_merge(allowed_to_merge_role[:description])
+ end
+ end
+ 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 b98bb8592d3..afa9be034eb 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
@@ -2,10 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Branch with unusual name', product_group: :source_code, quarantine: {
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/364565',
- type: :bug
- } do
+ describe 'Branch with unusual name', product_group: :source_code do
let(:branch_name) { 'unUsually/named#br--anch' }
let(:project) do
Resource::Project.fabricate_via_api! do |resource|
@@ -33,14 +30,8 @@ module QA
Page::Project::Show.perform do |show|
show.switch_to_branch(branch_name)
- # It takes a few seconds for console errors to appear
- sleep 3
-
- errors = page.driver.browser.logs.get(:browser)
- .select { |e| e.level == "SEVERE" }
- .to_a
-
- raise("Console error(s):\n#{errors.join("\n\n")}") if errors.present?
+ # To prevent false positives: https://gitlab.com/gitlab-org/gitlab/-/issues/383863
+ expect(show).to have_no_content('An error occurred')
show.click_file('test-folder')
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 f4ca7955a0f..479c5816938 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
@@ -20,13 +20,12 @@ module QA
let(:tag_name) { 'v0.0.1' }
let(:tag_message) { 'Version 0.0.1' }
- let(:tag_release_notes) { 'Release It!' }
shared_examples 'successful tag creation' do |user, testcase|
it "can be created by #{user}", testcase: testcase do
Flow::Login.sign_in(as: send(user))
- create_tag_for_project(project, tag_name, tag_message, tag_release_notes)
+ create_tag_for_project(project, tag_name, tag_message)
Page::Project::Tag::Show.perform do |show|
expect(show).to have_tag_name(tag_name)
@@ -40,7 +39,7 @@ module QA
it "cannot be created by an unauthorized #{user}", testcase: testcase do
Flow::Login.sign_in(as: send(user))
- create_tag_for_project(project, tag_name, tag_message, tag_release_notes)
+ create_tag_for_project(project, tag_name, tag_message)
Page::Project::Tag::New.perform do |new_tag|
expect(new_tag).to have_content('You are not allowed to create this tag as it is protected.')
@@ -73,7 +72,7 @@ module QA
it_behaves_like 'successful tag creation', :maintainer_user, 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347928'
end
- def create_tag_for_project(project, name, message, release_notes)
+ def create_tag_for_project(project, name, message)
project.visit!
Page::Project::Menu.perform(&:go_to_repository_tags)
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb
index 1a614e538ea..01ff6133e70 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/copy_snippet_file_contents_spec.rb
@@ -1,11 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :reliable, product_group: :editor, quarantine: {
- only: { subdomain: 'pre' },
- type: :investigating,
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/378697'
- } do
+ RSpec.describe 'Create', :reliable, product_group: :editor do
describe 'Multiple file snippet' do
let(:first_file_content) { 'First file content' }
let(:second_file_content) { 'Second file content' }
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 e5e3941e0cd..59b008d01e7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
module QA
- RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ RSpec.describe 'Create', product_group: :editor do
describe 'Add a directory in Web IDE' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -30,23 +29,18 @@ module QA
}
])
end
-
project.visit!
-
- Page::Project::Show.perform(&:open_web_ide!)
end
- it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347733' do
- Page::Project::WebIDE::Edit.perform do |ide|
- # Support::Waiter.wait_until(sleep_interval: 2, max_duration: 60, reload_page: page,
- # retry_on_exception: true) do
- # expect(ide).to have_element(:commit_mode_tab)
- # end
- ide.wait_until_ide_loads
- ide.add_directory(directory_name)
+ it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386760' do
+ Page::Project::Show.perform(&:open_web_ide!)
+ Page::Project::WebIDE::VSCode.perform do |ide|
+ ide.wait_for_ide_to_load
+ ide.create_new_folder(directory_name)
+ ide.within_vscode_editor do
+ expect(page).to have_content('A file or folder first_directory already exists at this location.')
+ end
end
-
- expect(page).to have_content('The name "first_directory" is already taken in this directory.')
end
end
@@ -57,18 +51,15 @@ module QA
Page::Project::Show.perform(&:open_web_ide!)
end
- it 'shows in the tree view but cannot be committed', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347732' do
- Page::Project::WebIDE::Edit.perform do |ide|
- ide.wait_until_ide_loads
- ide.add_directory(directory_name)
-
- expect(ide).to have_file(directory_name)
- expect(ide).to have_folder_icon(directory_name)
- expect(ide).not_to have_file_addition_icon(directory_name)
-
- ide.switch_to_commit_tab
-
- expect(ide).not_to have_file_to_commit(directory_name)
+ it 'shows successfully but not able to be committed',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386761' do
+ Page::Project::WebIDE::VSCode.perform do |ide|
+ ide.wait_for_ide_to_load
+ ide.create_new_folder(directory_name)
+ ide.commit_and_push(directory_name)
+ ide.within_vscode_editor do
+ expect(page).to have_content('No changes found. Not able to commit.')
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_new/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_new/add_new_directory_in_web_ide_spec.rb
deleted file mode 100644
index 7b40c8a62c1..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_new/add_new_directory_in_web_ide_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create', feature_flag: { name: 'vscode_web_ide', scope: :global }, product_group: :editor do
- describe 'Add a directory in Web IDE' do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'add-directory-project'
- project.initialize_with_readme = true
- end
- end
-
- before do
- Runtime::Feature.enable(:vscode_web_ide)
- Flow::Login.sign_in
- project.visit!
- end
-
- after do
- Runtime::Feature.disable(:vscode_web_ide)
- end
-
- context 'when a directory with the same name already exists' do
- let(:directory_name) { 'first_directory' }
-
- 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"
- }
- ])
- end
- project.visit!
- end
-
- it 'throws an error', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386760' do
- Page::Project::Show.perform(&:open_web_ide!)
- Page::Project::WebIDE::VSCode.perform do |ide|
- ide.wait_for_ide_to_load
- ide.create_new_folder(directory_name)
- ide.within_vscode_editor do
- expect(page).to have_content('A file or folder first_directory already exists at this location.')
- end
- end
- end
- end
-
- context 'when user adds a new empty directory' do
- let(:directory_name) { 'new_empty_directory' }
-
- before do
- Page::Project::Show.perform(&:open_web_ide!)
- end
-
- it 'shows successfully but not able to be committed',
-testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386761' do
- Page::Project::WebIDE::VSCode.perform do |ide|
- ide.wait_for_ide_to_load
- ide.create_new_folder(directory_name)
- ide.commit_and_push(directory_name)
- ide.within_vscode_editor do
- expect(page).to have_content('No changes found. Not able to commit.')
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb
index cf1e4700863..d046a6fb0c5 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/add_file_template_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'Web IDE file templates' do
include Runtime::Fixtures
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb
index 58afdfe7cd1..047490bd31e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/create_first_file_in_web_ide_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'First file using Web IDE' do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb
index 9c40a3abe52..aeb7a20a15b 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/link_to_line_in_web_ide_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'Link to line in Web IDE' do
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:project) do
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/open_web_ide_from_diff_tab_spec.rb
index bbfc3ba8ccd..92e4ed11ea7 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_old/open_web_ide_from_diff_tab_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'Open Web IDE from Diff Tab' do
files = [
{
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb
index 05c58b66b09..34e445d6c1c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/review_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/review_merge_request_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'Review a merge request in Web IDE' do
let(:new_file) { 'awesome_new_file.txt' }
let(:original_text) { 'Text' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
index 8082c54a6ee..e3ffeba6902 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' }, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'Git Server Hooks' do
let(:file_path) { File.join(Runtime::Path.fixtures_path, 'web_ide', 'README.md') }
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
index abc7c37a1d4..d83e2517cff 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/upload_new_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
-# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled
+# TODO: remove this test when coverage is replaced or deemed irrelevant
module QA
RSpec.describe 'Create', :skip_live_env, product_group: :editor do
+ before do
+ skip("Skipped but kept as reference. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115741#note_1330720944")
+ end
+
describe 'Upload a file in Web IDE' do
let(:file_path) { File.join(Runtime::Path.fixtures_path, 'web_ide', file_name) }
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb
index 072c957f4dc..b08a36b0d43 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_parent_child_pipelines_spec.rb
@@ -1,10 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', :runner, product_group: :pipeline_security, quarantine: {
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/396855',
- type: :flaky
- } do
+ RSpec.describe 'Verify', :runner, product_group: :pipeline_security do
describe "Unlocking job artifacts across parent-child pipelines" do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" }
@@ -22,15 +19,6 @@ module QA
end
end
- let(:parent_test_job_name) { 'test-job-parent' }
- let(:child_test_job_name) { 'test-job-child' }
-
- let(:previous_successful_pipeline) do
- Resource::Pipeline.fabricate_via_api! do |pipeline|
- pipeline.project = project
- end
- end
-
before do
Flow::Login.sign_in
project.visit!
@@ -40,47 +28,40 @@ module QA
let(:strategy) { nil }
before do
- add_parent_child_ci_files
- Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
- previous_successful_pipeline
+ add_parent_child_ci_files(
+ parent_job_name: 'parent_1', parent_script: 'echo parent',
+ child_job_name: 'child_1', child_script: 'echo child'
+ )
Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
end
context 'when latest pipeline family is successful' do
before do
- update_parent_child_ci_files
+ update_parent_child_ci_files(
+ parent_job_name: 'parent_2', parent_script: 'echo parent',
+ child_job_name: 'child_2', child_script: 'echo child'
+ )
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
end
it 'unlocks job artifacts from previous successful pipeline family',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/395516' do
- project.visit!
-
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_2').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_2').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
- previous_successful_pipeline.visit!
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
@@ -89,43 +70,31 @@ module QA
context 'when latest parent pipeline failed' do
before do
- update_failed_parent_ci_file
+ update_parent_child_ci_files(
+ parent_job_name: 'parent_2', parent_script: 'exit 1',
+ child_job_name: 'child_2', child_script: 'echo child'
+ )
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'failed')
end
it 'does not unlock job artifacts from previous successful pipeline family',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/396243' do
- project.visit!
-
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_failed
- # FIXME: this should be unlocked,
- # to be fixed by https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110575
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
@@ -134,41 +103,31 @@ module QA
context 'when latest child pipeline failed' do
before do
- update_failed_child_ci_file
+ update_parent_child_ci_files(
+ parent_job_name: 'parent_2', parent_script: 'echo parent',
+ child_job_name: 'child_2', child_script: 'exit 1'
+ )
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
end
it 'unlocks job artifacts from previous successful pipeline family because the latest parent is successful',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/396244' do
- project.visit!
-
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_failed
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
- previous_successful_pipeline.visit!
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
@@ -180,47 +139,40 @@ module QA
let(:strategy) { 'depend' }
before do
- add_parent_child_ci_files
- Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
- previous_successful_pipeline
+ add_parent_child_ci_files(
+ parent_job_name: 'parent_1', parent_script: 'echo parent',
+ child_job_name: 'child_1', child_script: 'echo child'
+ )
Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
end
context 'when latest pipeline family is successful' do
before do
- update_parent_child_ci_files
+ update_parent_child_ci_files(
+ parent_job_name: 'parent_2', parent_script: 'echo parent',
+ child_job_name: 'child_2', child_script: 'echo child'
+ )
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
end
it 'unlocks job artifacts from previous successful pipeline family',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/396245' do
- project.visit!
-
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_2').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_2').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
- previous_successful_pipeline.visit!
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
@@ -229,43 +181,31 @@ module QA
context 'when latest parent pipeline failed' do
before do
- update_failed_parent_ci_file
+ update_parent_child_ci_files(
+ parent_job_name: 'parent_2', parent_script: 'exit 1',
+ child_job_name: 'child_2', child_script: 'echo child'
+ )
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'failed')
end
it 'does not unlock job artifacts from previous successful pipeline family',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/396246' do
- project.visit!
-
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_2').visit!
Page::Project::Job::Show.perform do |job|
- # FIXME: this should be unlocked,
- # to be fixed by https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110575
- expect(job).to be_failed
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
@@ -274,45 +214,31 @@ module QA
context 'when latest child pipeline failed' do
before do
- update_failed_child_ci_file
+ update_parent_child_ci_files(
+ parent_job_name: 'parent_2', parent_script: 'echo parent',
+ child_job_name: 'child_2', child_script: 'exit 1'
+ )
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'failed')
end
it 'does not unlock job artifacts from previous successful pipeline family',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/396248' do
- project.visit!
-
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful
- # FIXME: this should be unlocked,
- # to be fixed by https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110575
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to be_failed
- # FIXME: this should be unlocked,
- # to be fixed by https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110575
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Flow::Pipeline.visit_pipeline_job_page(job_name: parent_test_job_name)
+ find_job('parent_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- previous_successful_pipeline.visit!
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.expand_child_pipeline
- pipeline.click_job(child_test_job_name)
- end
+ find_job('child_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
@@ -322,78 +248,33 @@ module QA
private
- def update_parent_child_ci_files
+ def update_parent_child_ci_files(parent_job_name:, parent_script:, child_job_name:, child_script:)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Update parent and child pipelines CI files.'
commit.update_files(
[
- parent_ci_file,
- child_ci_file
- ]
- )
- end
- end
-
- def update_failed_parent_ci_file
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Fail parent pipeline.'
- commit.update_files(
- [
- parent_failed_ci_file
+ parent_ci_file(parent_job_name, parent_script),
+ child_ci_file(child_job_name, child_script)
]
)
end
end
- def update_failed_child_ci_file
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Fail child pipeline.'
- commit.update_files(
- [
- child_failed_ci_file
- ]
- )
- end
- end
-
- def add_parent_child_ci_files
+ def add_parent_child_ci_files(parent_job_name:, parent_script:, child_job_name:, child_script:)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add parent and child pipelines CI files.'
commit.add_files(
[
- parent_ci_file,
- child_ci_file
+ parent_ci_file(parent_job_name, parent_script),
+ child_ci_file(child_job_name, child_script)
]
)
end
end
- def parent_ci_file
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
- trigger-child:
- stage: test
- trigger:
- include: ".child-ci.yml"
- strategy: #{strategy}
-
- #{parent_test_job_name}:
- stage: test
- tags: ["#{executor}"]
- script: echo "parent test"
- artifacts:
- paths: ['.gitlab-ci.yml']
- when: always
- YAML
- }
- end
-
- def parent_failed_ci_file
+ def parent_ci_file(job_name, script)
{
file_path: '.gitlab-ci.yml',
content: <<~YAML
@@ -403,10 +284,10 @@ module QA
include: ".child-ci.yml"
strategy: #{strategy}
- #{parent_test_job_name}:
+ #{job_name}:
stage: test
tags: ["#{executor}"]
- script: echo "parent test" && exit 1
+ script: #{script}
artifacts:
paths: ['.gitlab-ci.yml']
when: always
@@ -414,14 +295,14 @@ module QA
}
end
- def child_ci_file
+ def child_ci_file(job_name, script)
{
file_path: '.child-ci.yml',
content: <<~YAML
- #{child_test_job_name}:
+ #{job_name}:
stage: test
tags: ["#{executor}"]
- script: echo "child test"
+ script: #{script}
artifacts:
paths: ['.child-ci.yml']
when: always
@@ -429,19 +310,11 @@ module QA
}
end
- def child_failed_ci_file
- {
- file_path: '.child-ci.yml',
- content: <<~YAML
- #{child_test_job_name}:
- stage: test
- tags: ["#{executor}"]
- script: echo "child test" && exit 1
- artifacts:
- paths: ['.child-ci.yml']
- when: always
- YAML
- }
+ def find_job(job_name)
+ Resource::Job.fabricate_via_api! do |job|
+ job.project = project
+ job.id = project.job_by_name(job_name)[:id]
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb
index a954bd16386..f1a433984d8 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb
@@ -19,41 +19,34 @@ module QA
end
end
- let(:test_job_name) { 'test-job' }
-
before do
Flow::Login.sign_in
+ project.visit!
end
context 'when latest pipeline is successful' do
+ before do
+ add_ci_file(job_name: 'job_1', script: 'echo test')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
+ end
+
it 'unlocks job artifacts from previous successful pipeline',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/394807' do
- add_ci_file
- project.visit!
-
- previous_successful_pipeline = Resource::Pipeline.fabricate! do |pipeline|
- pipeline.project = project
- end
-
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: test_job_name)
-
+ find_job('job_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- update_ci_script('echo bye')
- project.visit!
+ update_ci_file(job_name: 'job_2', script: 'echo test')
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: test_job_name)
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
+ find_job('job_2').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_pipeline_job_page(pipeline: previous_successful_pipeline, job_name: test_job_name)
-
+ find_job('job_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
@@ -61,57 +54,69 @@ module QA
end
context 'when latest pipeline failed' do
- it 'unlocks job artifacts from failed pipelines, keeps job artifacts from latest successful pipeline',
+ before do
+ add_ci_file(job_name: 'successful_job_1', script: 'echo test')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
+ end
+
+ it 'keeps job artifacts from latest failed pipelines and from latest successful pipeline',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/394808',
quarantine: {
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/266958',
type: :bug
} do
- add_ci_file
- project.visit!
+ update_ci_file(job_name: 'failed_job_1', script: 'exit 1')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'failed')
- successful_pipeline = Resource::Pipeline.fabricate! do |pipeline|
- pipeline.project = project
- end
-
- Flow::Pipeline.visit_latest_pipeline(status: 'passed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: test_job_name)
+ update_ci_file(job_name: 'failed_job_2', script: 'exit 2')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'failed')
+ find_job('failed_job_2').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
- update_ci_script('echo test && exit 1')
-
- failed_pipeline_1 = Resource::Pipeline.fabricate! do |pipeline|
- pipeline.project = project
+ find_job('failed_job_1').visit!
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to have_unlocked_artifact
end
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: test_job_name)
-
+ find_job('successful_job_1').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to have_unlocked_artifact
+ expect(job).to have_locked_artifact
end
+ end
+ end
- update_ci_script('echo bye && exit 1')
- project.visit!
+ context 'when latest pipeline is blocked' do
+ before do
+ add_ci_file(job_name: 'successful_job_1', script: 'echo test')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'passed')
+ end
+
+ it 'keeps job artifacts from the latest blocked pipeline and from latest successful pipeline',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/395511',
+ quarantine: {
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387087',
+ type: :bug
+ } do
+ update_ci_with_manual_job(job_name: 'successful_job_with_manual_1', script: 'echo test')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'blocked')
- Flow::Pipeline.visit_latest_pipeline(status: 'failed')
- Flow::Pipeline.visit_pipeline_job_page(job_name: test_job_name)
+ update_ci_with_manual_job(job_name: 'successful_job_with_manual_2', script: 'echo test')
+ Flow::Pipeline.wait_for_latest_pipeline(status: 'blocked')
+ find_job('successful_job_with_manual_2').visit!
Page::Project::Job::Show.perform do |job|
- expect(job).to have_unlocked_artifact
+ expect(job).to have_locked_artifact
end
- Flow::Pipeline.visit_pipeline_job_page(pipeline: failed_pipeline_1, job_name: test_job_name)
-
+ find_job('successful_job_with_manual_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_unlocked_artifact
end
- Flow::Pipeline.visit_pipeline_job_page(pipeline: successful_pipeline, job_name: test_job_name)
-
+ find_job('successful_job_1').visit!
Page::Project::Job::Show.perform do |job|
expect(job).to have_locked_artifact
end
@@ -120,42 +125,41 @@ module QA
private
- def add_ci_file
- script = 'echo test'
- ci_file = ci_file_with_job_artifact(script)
+ def add_ci_file(job_name:, script:)
+ ci_file = ci_file_with_job_artifact(job_name, script)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
- commit.commit_message = "Set script #{script}"
+ commit.commit_message = "Set job #{job_name} script #{script}"
commit.add_files([ci_file])
end
end
- def update_ci_script(script)
- ci_file = ci_file_with_job_artifact(script)
+ def update_ci_file(job_name:, script:)
+ ci_file = ci_file_with_job_artifact(job_name, script)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
- commit.commit_message = "Set script #{script}"
+ commit.commit_message = "Set job #{job_name} script #{script}"
commit.update_files([ci_file])
end
end
- def add_failing_ci_file
- ci_file = ci_file_with_job_artifact('echo test && exit 1')
+ def update_ci_with_manual_job(job_name:, script:)
+ ci_file = ci_file_with_manual_job(job_name, script)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
- commit.commit_message = 'Add failing CI file.'
- commit.add_files([ci_file])
+ commit.commit_message = "Set job #{job_name} script #{script}"
+ commit.update_files([ci_file])
end
end
- def ci_file_with_job_artifact(script)
+ def ci_file_with_job_artifact(job_name, script)
{
file_path: '.gitlab-ci.yml',
content: <<~YAML
- #{test_job_name}:
+ #{job_name}:
stage: test
tags: ["#{executor}"]
script: #{script}
@@ -165,6 +169,36 @@ module QA
YAML
}
end
+
+ def ci_file_with_manual_job(job_name, script)
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ #{job_name}:
+ stage: test
+ tags: ["#{executor}"]
+ script: #{script}
+ artifacts:
+ paths: ['.gitlab-ci.yml']
+
+ manual-job:
+ stage: test
+ tags: ["#{executor}"]
+ rules:
+ - when: manual
+ script: "echo 'this job is manual'"
+ artifacts:
+ paths: ['.gitlab-ci.yml']
+ YAML
+ }
+ end
+
+ def find_job(job_name)
+ Resource::Job.fabricate_via_api! do |job|
+ job.project = project
+ job.id = project.job_by_name(job_name)[:id]
+ end
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
deleted file mode 100644
index 8474e5c1b37..00000000000
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Verify' do
- describe 'Add or Remove CI variable via UI', :smoke, product_group: :pipeline_security do
- let(:project) do
- Resource::Project.fabricate_via_api_unless_fips! do |project|
- project.name = 'project-with-ci-variables'
- project.description = 'project with CI variables'
- end
- end
-
- before do
- Flow::Login.sign_in
- project.visit!
- add_ci_variable
- end
-
- it 'user adds a CI variable', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348027' do
- Page::Project::Settings::CiVariables.perform do |ci_variable|
- expect(ci_variable).to have_text('VARIABLE_KEY')
- expect(ci_variable).not_to have_text('some_CI_variable')
-
- ci_variable.click_reveal_ci_variable_value_button
-
- expect(ci_variable).to have_text('some_CI_variable')
- end
- end
-
- it 'user removes a CI variable', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348026' do
- Page::Project::Settings::CiVariables.perform do |ci_variable|
- ci_variable.click_edit_ci_variable
- ci_variable.click_ci_variable_delete_button
-
- expect(ci_variable).to have_text('There are no variables yet', wait: 60)
- end
- end
-
- private
-
- def add_ci_variable
- Resource::CiVariable.fabricate_via_browser_ui! do |ci_variable|
- ci_variable.project = project
- ci_variable.key = 'VARIABLE_KEY'
- ci_variable.value = 'some_CI_variable'
- ci_variable.masked = false
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb
index 4c1319da0cb..4515353dfc5 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/custom_variable_spec.rb
@@ -49,7 +49,7 @@ module QA
Flow::Login.sign_in
project.visit!
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb
index b79f8b5f1f4..b62ae85436f 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb
@@ -52,7 +52,7 @@ module QA
project.visit!
# Navigate to Run Pipeline page
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
deleted file mode 100644
index 0aedbd307bf..00000000000
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Verify', :runner, product_group: :pipeline_execution do
- describe 'Pipeline creation and processing' do
- let(:executor) { "qa-runner-#{Time.now.to_i}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-pipeline'
- end
- end
-
- let!(:runner) do
- Resource::ProjectRunner.fabricate! do |runner|
- runner.project = project
- runner.name = executor
- runner.tags = [executor]
- end
- end
-
- after do
- [runner, project].each(&:remove_via_api!)
- end
-
- it 'users creates a pipeline which gets processed', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348024' do
- Flow::Login.sign_in
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
- test-success:
- tags:
- - #{executor}
- script: echo 'OK'
-
- test-failure:
- tags:
- - #{executor}
- script:
- - echo 'FAILURE'
- - exit 1
-
- test-tags-mismatch:
- tags:
- - invalid
- script: echo 'NOOP'
-
- test-artifacts:
- tags:
- - #{executor}
- script: mkdir my-artifacts; echo "CONTENTS" > my-artifacts/artifact.txt
- artifacts:
- paths:
- - my-artifacts/
-
- test-coverage-report:
- tags:
- - #{executor}
- script: mkdir coverage; echo "CONTENTS" > coverage/cobertura.xml
- artifacts:
- reports:
- coverage_report:
- coverage_format: cobertura
- path: coverage/cobertura.xml
- YAML
- }
- ]
- )
- end.project.visit!
-
- Flow::Pipeline.visit_latest_pipeline
-
- aggregate_failures do
- {
- 'test-success': 'passed',
- 'test-failure': 'failed',
- 'test-tags-mismatch': 'pending',
- 'test-artifacts': 'passed',
- 'test-coverage-report': 'passed'
- }.each do |job, status|
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job(job)
- end
-
- Page::Project::Job::Show.perform do |show|
- expect(show).to have_status(status), "Expected job status to be #{status} but got #{show.status_badge} instead."
- show.click_element(:pipeline_path, Page::Project::Pipeline::Show)
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
deleted file mode 100644
index 5543e39e38c..00000000000
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/locked_artifacts_spec.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Verify', :runner, product_group: :pipeline_security do
- describe 'Artifacts' do
- context 'when locked' do
- let(:file_name) { 'artifact.txt' }
- let(:directory_name) { 'my_artifacts' }
- let(:executor) { "qa-runner-#{Time.now.to_i}" }
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-with-locked-artifacts'
- end
- end
-
- let!(:runner) do
- Resource::ProjectRunner.fabricate! do |runner|
- runner.project = project
- runner.name = executor
- runner.tags = [executor]
- end
- end
-
- before do
- Flow::Login.sign_in
- end
-
- after do
- runner.remove_via_api!
- end
-
- it 'can be browsed', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348003' do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
- test-artifacts:
- tags:
- - '#{executor}'
- artifacts:
- paths:
- - '#{directory_name}'
- expire_in: 1 sec
- script:
- - |
- mkdir #{directory_name}
- echo "CONTENTS" > #{directory_name}/#{file_name}
- YAML
- }
- ]
- )
- end.project.visit!
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('test-artifacts')
- end
-
- Page::Project::Job::Show.perform do |show|
- expect(show).to have_browse_button
- show.click_browse_button
- end
-
- Page::Project::Artifact::Show.perform do |show|
- show.go_to_directory(directory_name)
- expect(show).to have_content(file_name)
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
index e8ec01577b1..9f43471035f 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
@@ -37,7 +37,7 @@ module QA
before do
Flow::Login.sign_in
project.visit!
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
end
it 'can trigger pipeline', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348011' do
diff --git a/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb
index e7ab515c672..e2bb6c33513 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/testing/endpoint_coverage_spec.rb
@@ -40,8 +40,7 @@ module QA
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/360837'
) do
# create a CI variable via UI
- Page::Project::Show.perform(&:go_to_ci_cd_settings)
-
+ Page::Project::Menu.perform(&:go_to_ci_cd_settings)
Page::Project::Settings::CiCd.perform do |ci_cd|
ci_cd.expand_ci_variables do |vars|
vars.click_add_variable
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
index ec07116550f..d79befc6837 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
@@ -2,8 +2,8 @@
module QA
RSpec.describe 'Package', :orchestrated, :skip_live_env, product_group: :container_registry, quarantine: {
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/390090',
- type: :investigating
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/399556',
+ type: :flaky
} do
describe 'Self-managed Container Registry' do
include Support::Helpers::MaskToken
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index 1e7d0eab365..0a9f30f0529 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Configure',
- only: { subdomain: %i[staging staging-canary] }, product_group: :configure do
+ only: { pipeline: %i[staging staging-canary canary production] }, product_group: :configure do
describe 'Auto DevOps with a Kubernetes Agent' do
let!(:app_project) do
Resource::Project.fabricate_via_api! do |project|
@@ -45,7 +45,7 @@ module QA
app_project.visit!
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+ Page::Project::Menu.perform(&:go_to_pipelines)
Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button)
Page::Project::Pipeline::New.perform(&:click_run_pipeline_button)
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb
index 70874e46f27..008d8f808b3 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/email_notification_for_alert_spec.rb
@@ -3,8 +3,8 @@
module QA
RSpec.describe 'Monitor', :orchestrated, :smtp, :requires_admin, product_group: :respond do
describe 'Alert' do
- shared_examples 'notification on new alert', :aggregate_failures do
- it 'sends email to user' do
+ shared_examples 'notification on new alert' do
+ it 'sends email to user', :aggregate_failures do
expect { email_subjects }.to eventually_include(alert_email_subject).within(max_duration: 60)
expect(recipient_email_addresses).to include(user.email)
end
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb
index 433d286686b..af088d2978a 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/alert_management/recovery_alert_resolves_correct_alert_spec.rb
@@ -26,7 +26,12 @@ module QA
context(
'when using HTTP endpoint integration',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393589'
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393589',
+ quarantine: {
+ only: { pipeline: :nightly },
+ type: :bug,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/395512'
+ }
) do
include_context 'sends and resolves test alerts'
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident.rb b/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb
index fe3cd5a432b..aadca29de0c 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/incident_management/recovery_alert_closes_correct_incident_spec.rb
@@ -27,7 +27,12 @@ module QA
context(
'when using HTTP endpoint integration',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393842'
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/393842',
+ quarantine: {
+ only: { pipeline: :nightly },
+ type: :bug,
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/403596'
+ }
) do
include_context 'sends and resolves test alerts'
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/group_member_access_request_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb
index 3a84646977f..1206898431a 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/group_member_access_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/group/group_member_access_request_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :requires_admin, product_group: :organization do
+ RSpec.describe 'Data Stores', :requires_admin, product_group: :tenant_scale do
describe 'Group member access request' do
let!(:admin_api_client) { Runtime::API::Client.as_admin }
@@ -40,7 +40,7 @@ module QA
end
it 'generates a todo item for the group owner',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370132' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370132' do
Page::Dashboard::Todos.perform do |todos|
expect(todos).to have_latest_todo_with_author(
author: user.name,
@@ -64,7 +64,7 @@ module QA
end
it 'adds user to the group',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386792' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386792' do
found_member = group.reload!.find_member(user.username)
expect(found_member).not_to be_nil
@@ -81,7 +81,7 @@ module QA
end
it 'does not add user to the group',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386793' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/386793' do
found_member = group.reload!.find_member(user.username)
expect(found_member).to be_nil
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb
index b2ccacfd142..2f14e2c10da 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_group_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'Subgroup transfer', product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Subgroup transfer', product_group: :tenant_scale do
let(:source_group) do
Resource::Group.fabricate_via_api! do |group|
group.path = "source-group-for-transfer_#{SecureRandom.hex(8)}"
@@ -28,7 +28,7 @@ module QA
end
it 'transfers a subgroup to another group',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347692' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347692' do
Page::Group::Menu.perform(&:click_group_general_settings_item)
Page::Group::Settings::General.perform do |general|
general.transfer_group(sub_group_for_transfer, target_group)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb
index ef05f4cfecf..02e1598d6e7 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/group/transfer_project_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'Project transfer between groups', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Project transfer between groups', :reliable, product_group: :tenant_scale do
let(:source_group) do
Resource::Group.fabricate_via_api! do |group|
group.path = "source-group-#{SecureRandom.hex(8)}"
@@ -36,8 +36,8 @@ module QA
end
it 'user transfers a project between groups',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347878' do
- Page::File::Show.perform(&:go_to_general_settings)
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347878' do
+ Page::Project::Menu.perform(&:go_to_general_settings)
Page::Project::Settings::Main.perform(&:expand_advanced_settings)
@@ -45,7 +45,7 @@ module QA
advanced.transfer_project!(project.name, target_group.full_path)
end
- Page::Project::Settings::Main.perform(&:click_project)
+ Page::Project::Menu.perform(&:click_project)
Page::Project::Show.perform do |project|
expect(project).to have_breadcrumb(target_group.path)
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb
index 50e86b4d555..0beb297ffdb 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/add_project_member_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores', :reliable, product_group: :tenant_scale do
describe 'Add project member' do
it 'user adds project member', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347887' do
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/9_data_stores/project/create_project_badge_spec.rb
index 0a643d1e33b..87492af089e 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_badge_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_badge_spec.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'Create project badge', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Create project badge', :reliable, product_group: :tenant_scale do
let(:badge_name) { "project-badge-#{SecureRandom.hex(8)}" }
let(:expected_badge_link_url) { "#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}" }
- let(:expected_badge_image_url) { "#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}/badges/main/pipeline.svg" }
+ let(:expected_badge_image_url) do
+ "#{Runtime::Scenario.gitlab_address}/#{project.path_with_namespace}/badges/main/pipeline.svg"
+ end
+
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'badge-test-project'
@@ -18,7 +21,8 @@ module QA
project.visit!
end
- it 'creates project badge successfully', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/350065' do
+ it 'creates project badge successfully',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/350065' do
Resource::ProjectBadge.fabricate! do |badge|
badge.name = badge_name
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_spec.rb
index c9e90cce84c..2d288ced0ca 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/create_project_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :smoke, product_group: :organization do
+ RSpec.describe 'Data Stores', :smoke, product_group: :tenant_scale 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/9_data_stores/project/dashboard_images_spec.rb
index e609dfb9197..f2136773f59 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/dashboard_images_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', product_group: :organization do
+ RSpec.describe 'Data Stores', product_group: :tenant_scale do
shared_examples 'loads all images' do |admin|
let(:api_client) { Runtime::API::Client.as_admin }
@@ -21,7 +21,7 @@ module QA
Page::Dashboard::Welcome.perform do |welcome|
Support::Waiter.wait_until(sleep_interval: 2, max_duration: 60, reload_page: page,
- retry_on_exception: true) do
+ retry_on_exception: true) do
expect(welcome).to have_welcome_title("Welcome to GitLab")
end
# This would be better if it were a visual validation test
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/9_data_stores/project/invite_group_to_project_spec.rb
index 4479f2ebfab..c7501d437eb 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/invite_group_to_project_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'Invite group', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Invite group', :reliable, product_group: :tenant_scale do
shared_examples 'invites group to project' do
it 'verifies group is added and members can access project with correct access level' do
Page::Project::Menu.perform(&:click_members)
@@ -28,7 +28,9 @@ module QA
end
end
- let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
+ let(:user) do
+ Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
+ end
before do
Flow::Login.sign_in
@@ -36,7 +38,8 @@ module QA
project.visit!
end
- context 'to personal namespace project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do
+ context 'with a personal namespace project',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do
let(:group) do
Resource::Group.fabricate_via_api! do |group|
group.path = "group-for-personal-project-#{SecureRandom.hex(8)}"
@@ -52,10 +55,15 @@ module QA
end
end
+ after do
+ project.remove_via_api!
+ group.remove_via_api!
+ end
+
it_behaves_like 'invites group to project'
end
- context 'to group project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349340' do
+ context 'with a group project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349340' do
let(:group) do
Resource::Group.fabricate_via_api! do |group|
group.path = "group-for-group-project-#{SecureRandom.hex(8)}"
@@ -70,6 +78,11 @@ module QA
end
end
+ after do
+ project.remove_via_api!
+ group.remove_via_api!
+ end
+
it_behaves_like 'invites group to project'
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
index 59774ed7c49..2793b0440a4 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/project_owner_permissions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/project_owner_permissions_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'Project owner permissions', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Project owner permissions', :reliable, product_group: :tenant_scale 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/9_data_stores/project/view_project_activity_spec.rb
index 95305b7a4aa..4945ef533a4 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/project/view_project_activity_spec.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'Project activity', :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'Project activity', :reliable, product_group: :tenant_scale do
it 'user creates an event in the activity page upon Git push',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
Flow::Login.sign_in
project = Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
index ac08ecec786..c78151b94b7 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/follow_user_activity_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'User', :requires_admin, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'User', :requires_admin, product_group: :tenant_scale do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let(:followed_user_api_client) { Runtime::API::Client.new(:gitlab, user: followed_user) }
@@ -68,7 +68,15 @@ module QA
followed_user_api_client.personal_access_token
end
- it 'can be followed and their activity seen', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347678' do
+ after do
+ project&.api_client = admin_api_client
+ project&.remove_via_api!
+ followed_user&.remove_via_api!
+ following_user&.remove_via_api!
+ end
+
+ it 'can be followed and their activity seen',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347678' do
Flow::Login.sign_in(as: following_user)
page.visit Runtime::Scenario.gitlab_address + "/#{followed_user.username}"
Page::User::Show.perform(&:click_follow_user_link)
@@ -93,13 +101,6 @@ module QA
end
end
end
-
- after do
- project&.api_client = admin_api_client
- project&.remove_via_api!
- followed_user&.remove_via_api!
- following_user&.remove_via_api!
- end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
index 7caa6677787..7e88f3a9ac3 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/parent_group_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/parent_group_access_termination_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'User', :requires_admin, :reliable, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'User', :requires_admin, :reliable, product_group: :tenant_scale do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user) do
@@ -41,7 +41,7 @@ module QA
end
it 'is not allowed to edit the project files',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347866' do
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347866' do
Flow::Login.sign_in(as: user)
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
index c57900efe35..78baba403fd 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/user_inherited_access_spec.rb
+++ b/qa/qa/specs/features/browser_ui/9_data_stores/user/user_inherited_access_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage' do
- describe 'User', :requires_admin, product_group: :organization do
+ RSpec.describe 'Data Stores' do
+ describe 'User', :requires_admin, product_group: :tenant_scale do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:parent_group) do
@@ -41,6 +41,10 @@ module QA
parent_group.add_member(parent_group_user)
end
+ after do
+ parent_group_user.remove_via_api!
+ end
+
it(
'is allowed to edit the sub-group project files',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/363467'
@@ -58,10 +62,6 @@ module QA
expect(file_form).to have_element(:commit_button)
end
end
-
- after do
- parent_group_user.remove_via_api!
- end
end
context 'when added to sub-group' do
@@ -87,6 +87,10 @@ module QA
sub_group.add_member(sub_group_user)
end
+ after do
+ sub_group_user.remove_via_api!
+ end
+
it(
'is not allowed to edit the parent group project files',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/363466'
@@ -102,10 +106,6 @@ module QA
expect(page).to have_text("You can’t edit files directly in this project.")
end
-
- after do
- sub_group_user.remove_via_api!
- end
end
end
end
diff --git a/qa/qa/specs/features/shared_contexts/import/gitlab_group_migration_common.rb b/qa/qa/specs/features/shared_contexts/import/gitlab_group_migration_common.rb
index 4bd81ccdf36..bfd0825cf91 100644
--- a/qa/qa/specs/features/shared_contexts/import/gitlab_group_migration_common.rb
+++ b/qa/qa/specs/features/shared_contexts/import/gitlab_group_migration_common.rb
@@ -77,7 +77,7 @@ module QA
imported_group.import_details.sum([]) { |details| details[:failures] }
end
- let(:cleanup!) {}
+ let(:cleanup!) {} # rubocop:disable Lint/EmptyBlock
def expect_group_import_finished_successfully
imported_group # trigger import
diff --git a/qa/qa/specs/features/shared_contexts/sends_and_resolves_test_alerts.rb b/qa/qa/specs/features/shared_contexts/sends_and_resolves_test_alerts.rb
index a72140f41e0..9623bcbb7b5 100644
--- a/qa/qa/specs/features/shared_contexts/sends_and_resolves_test_alerts.rb
+++ b/qa/qa/specs/features/shared_contexts/sends_and_resolves_test_alerts.rb
@@ -35,6 +35,8 @@ module QA
private
def mark_as_resolved(payload, http)
+ sleep 3 # To ensure create and end time are different
+
if http
payload[:end_time] = Time.now
else
diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb
index 1bf189ed6ac..aa274a4e101 100644
--- a/qa/qa/specs/spec_helper.rb
+++ b/qa/qa/specs/spec_helper.rb
@@ -33,7 +33,7 @@ RSpec.configure do |config|
QA::Runtime::Logger.info("Starting test: #{Rainbow(example.full_description).bright}")
QA::Runtime::Example.current = example
- visit(QA::Runtime::Scenario.gitlab_address) if QA::Runtime::Env.remote_mobile_device_name
+ visit(QA::Runtime::Scenario.gitlab_address) if QA::Runtime::Env.mobile_layout?
# Reset fabrication counters tracked in resource base
Thread.current[:api_fabrication] = 0
diff --git a/qa/qa/support/matchers/have_matcher.rb b/qa/qa/support/matchers/have_matcher.rb
index d843949e6b2..a9b365f7e81 100644
--- a/qa/qa/support/matchers/have_matcher.rb
+++ b/qa/qa/support/matchers/have_matcher.rb
@@ -28,6 +28,7 @@ module QA
system_note
alert_with_title
incident
+ framework
].each do |predicate|
RSpec::Matchers.define "have_#{predicate}" do |*args, **kwargs|
match do |page_object|
diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb
index 2e97325aff0..ad8d63ec856 100644
--- a/qa/qa/support/page/logging.rb
+++ b/qa/qa/support/page/logging.rb
@@ -92,8 +92,8 @@ module QA
super
end
- def click_via_capybara(method, locator)
- log("clicking via capybara using '#{method}(#{locator})'", :info)
+ def act_via_capybara(method, locator, **kwargs)
+ log("acting via capybara using '#{method}(#{locator})' with args #{kwargs}", :info)
super
end
diff --git a/qa/qa/support/wait_for_requests.rb b/qa/qa/support/wait_for_requests.rb
index d863ed0491d..2856602629a 100644
--- a/qa/qa/support/wait_for_requests.rb
+++ b/qa/qa/support/wait_for_requests.rb
@@ -16,7 +16,7 @@ module QA
end
def finished_all_ajax_requests?
- requests = %w[window.pendingRequests window.pendingRailsUJSRequests 0]
+ requests = %w[window.pendingRequests window.pendingApolloRequests window.pendingRailsUJSRequests 0]
if Runtime::Env.can_intercept?
requests.unshift('(window.Interceptor && window.Interceptor.activeFetchRequests)')
@@ -26,6 +26,10 @@ module QA
Capybara.page.evaluate_script(script).zero? # rubocop:disable Style/NumericPredicate
end
+ def spinner_exists?
+ Capybara.page.has_css?('.gl-spinner', wait: 2)
+ end
+
def finished_loading?(wait: DEFAULT_MAX_WAIT_TIME)
# The number of selectors should be able to be reduced after
# migration to the new spinner is complete.
diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb
index 2aa8845605e..7f4b8f78618 100644
--- a/qa/qa/tools/test_resources_handler.rb
+++ b/qa/qa/tools/test_resources_handler.rb
@@ -31,6 +31,8 @@ module QA
QA::Resource::CiVariable
QA::Resource::Repository::Commit
QA::Resource::Design
+ QA::Resource::InstanceOauthApplication
+ QA::EE::Resource::ComplianceFramework
QA::EE::Resource::GroupIteration
QA::EE::Resource::Settings::Elasticsearch
QA::EE::Resource::VulnerabilityItem
diff --git a/qa/qa/vendor/github/page/base.rb b/qa/qa/vendor/github/page/base.rb
new file mode 100644
index 00000000000..3b96180afe9
--- /dev/null
+++ b/qa/qa/vendor/github/page/base.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module QA
+ module Vendor
+ module Github
+ module Page
+ class Base
+ include Capybara::DSL
+ include Scenario::Actable
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/vendor/github/page/login.rb b/qa/qa/vendor/github/page/login.rb
new file mode 100644
index 00000000000..17a7471e251
--- /dev/null
+++ b/qa/qa/vendor/github/page/login.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'capybara/dsl'
+require 'benchmark'
+
+module QA
+ module Vendor
+ module Github
+ module Page
+ class Login < Page::Base
+ def login
+ fill_in 'login', with: QA::Runtime::Env.github_username
+ fill_in 'password', with: QA::Runtime::Env.github_password
+ click_on 'Sign in'
+
+ current_otp = OnePassword::CLI.instance.current_otp
+
+ fill_in 'app_otp', with: current_otp
+
+ if has_text?('Two-factor authentication failed', wait: 2)
+ new_otp = OnePassword::CLI.instance.new_otp(otp)
+
+ fill_in 'app_otp', with: new_otp
+ end
+
+ authorize_app
+ end
+
+ def authorize_app
+ click_on 'Authorize' if has_button?('Authorize')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/vendor/one_password/cli.rb b/qa/qa/vendor/one_password/cli.rb
new file mode 100644
index 00000000000..f443ba05492
--- /dev/null
+++ b/qa/qa/vendor/one_password/cli.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'benchmark'
+
+module QA
+ module Vendor
+ module OnePassword
+ class CLI
+ include Singleton
+
+ def initialize
+ @email = QA::Runtime::Env.one_p_email
+ @password = QA::Runtime::Env.one_p_password
+ @secret = QA::Runtime::Env.one_p_secret
+ @github_uuid = QA::Runtime::Env.one_p_github_uuid
+ @address = 'gitlab.1password.com'
+ end
+
+ def new_otp(old_otp = "")
+ # Fetches a new OTP that is not equal to the old OTP
+ new_otp = ""
+ time = Benchmark.realtime do
+ # An otp is valid for 30 seconds so 64 attempts with 0.5 interval are enough to ensure a new OTP is obtained
+ Support::Retrier.retry_until(max_attempts: 64, sleep_interval: 0.5) do
+ new_otp = current_otp
+ new_otp != old_otp
+ end
+ end
+
+ QA::Runtime::Logger.info("Fetched new OTP in: #{time} seconds")
+
+ new_otp
+ end
+
+ def current_otp
+ result = nil
+
+ time = Benchmark.realtime do
+ result = `op item get #{@github_uuid} --otp --session #{session_token}`.chop
+ end
+
+ QA::Runtime::Logger.info("Fetched current OTP in: #{time} seconds")
+
+ result
+ end
+
+ private
+
+ # OP session tokens are valid for 30 minutes. We are caching the session token here and this is fine currently
+ # as we just have one test that is not expected to go over 30 minutes.
+ # But note that if we add more tests that use this class, we might need to add a mechanism to invalidate
+ # the cache after 30 minutes or if the session_token is rejected by op CLI.
+ def session_token
+ @session_token ||= `echo '#{@password}' | op account add --address #{@address} --email #{@email} --secret-key #{@secret} --signin --raw` # rubocop:disable Layout/LineLength
+ end
+ end
+ end
+ end
+end
diff --git a/qa/tasks/ci.rake b/qa/tasks/ci.rake
index aaf691de1b5..e5f4acb158b 100644
--- a/qa/tasks/ci.rake
+++ b/qa/tasks/ci.rake
@@ -32,7 +32,7 @@ namespace :ci do
if run_all_label_present
logger.info(" merge request has pipeline:run-all-e2e label, full test suite will be executed")
- append_to_file(env_file, "QA_RUN_ALL_TESTS=true\n")
+ append_to_file(env_file, "QA_RUN_ALL_E2E_LABEL=true\n")
elsif qa_changes.framework_changes? # run all tests when framework changes detected
logger.info(" merge request contains qa framework changes, full test suite will be executed")
append_to_file(env_file, "QA_FRAMEWORK_CHANGES=true\n")
diff --git a/qa/tasks/webdrivers.rake b/qa/tasks/webdrivers.rake
index f4fa3fab555..cd2a36ddf6b 100644
--- a/qa/tasks/webdrivers.rake
+++ b/qa/tasks/webdrivers.rake
@@ -1,4 +1,3 @@
# frozen_string_literal: true
-require 'webdrivers'
load 'webdrivers/Rakefile'