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-07-19 17:16:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-19 17:16:28 +0300
commite4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch)
tree2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /qa
parentffda4e7bcac36987f936b4ba515995a6698698f0 (diff)
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'qa')
-rw-r--r--qa/Dockerfile3
-rw-r--r--qa/Gemfile9
-rw-r--r--qa/Gemfile.lock52
-rw-r--r--qa/gdk/Dockerfile.gdk10
-rw-r--r--qa/qa.rb3
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/build.gradle.erb51
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb27
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb27
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb8
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_install_package.yaml.erb23
-rw-r--r--qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb8
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/gitlab_ci.yaml.erb8
-rw-r--r--qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/settings.xml.erb23
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb8
-rw-r--r--qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb23
-rw-r--r--qa/qa/fixtures/package_managers/pypi/pypi_upload_install_package.yaml.erb2
-rw-r--r--qa/qa/flow/alert_settings.rb1
-rw-r--r--qa/qa/git/repository.rb2
-rw-r--r--qa/qa/page/base.rb11
-rw-r--r--qa/qa/page/component/confirm_modal.rb15
-rw-r--r--qa/qa/page/component/design_management.rb2
-rw-r--r--qa/qa/page/component/dropdown.rb7
-rw-r--r--qa/qa/page/component/issuable/sidebar.rb4
-rw-r--r--qa/qa/page/component/members/invite_members_modal.rb12
-rw-r--r--qa/qa/page/component/members/members_table.rb3
-rw-r--r--qa/qa/page/component/note.rb5
-rw-r--r--qa/qa/page/component/rich_text_popover.rb31
-rw-r--r--qa/qa/page/file/form.rb2
-rw-r--r--qa/qa/page/group/bulk_import.rb9
-rw-r--r--qa/qa/page/group/sub_menus/common.rb2
-rw-r--r--qa/qa/page/issuable/new.rb9
-rw-r--r--qa/qa/page/main/login.rb25
-rw-r--r--qa/qa/page/main/menu.rb37
-rw-r--r--qa/qa/page/merge_request/show.rb12
-rw-r--r--qa/qa/page/project/branches/show.rb22
-rw-r--r--qa/qa/page/project/issue/show.rb1
-rw-r--r--qa/qa/page/project/pipeline/show.rb24
-rw-r--r--qa/qa/page/project/settings/alerts.rb8
-rw-r--r--qa/qa/page/project/snippet/new.rb2
-rw-r--r--qa/qa/page/project/web_ide/edit.rb4
-rw-r--r--qa/qa/page/user/show.rb5
-rw-r--r--qa/qa/resource/base.rb3
-rw-r--r--qa/qa/resource/design.rb2
-rw-r--r--qa/qa/resource/events/project.rb8
-rw-r--r--qa/qa/resource/import_project.rb2
-rw-r--r--qa/qa/resource/issuable.rb2
-rw-r--r--qa/qa/resource/issue.rb7
-rw-r--r--qa/qa/resource/merge_request.rb7
-rw-r--r--qa/qa/resource/personal_access_token_cache.rb6
-rw-r--r--qa/qa/resource/project_imported_from_github.rb9
-rw-r--r--qa/qa/resource/repository/branch.rb52
-rw-r--r--qa/qa/runtime/application_settings.rb9
-rw-r--r--qa/qa/runtime/env.rb24
-rw-r--r--qa/qa/runtime/fixtures.rb2
-rw-r--r--qa/qa/runtime/gpg.rb2
-rw-r--r--qa/qa/runtime/path.rb16
-rw-r--r--qa/qa/scenario/test/instance/airgapped.rb2
-rw-r--r--qa/qa/scenario/test/instance/blocking.rb14
-rw-r--r--qa/qa/scenario/test/instance/non_blocking.rb15
-rw-r--r--qa/qa/scenario/test/integration/oauth.rb13
-rw-r--r--qa/qa/service/docker_run/base.rb36
-rw-r--r--qa/qa/service/docker_run/gitlab_runner.rb7
-rw-r--r--qa/qa/service/docker_run/ldap.rb2
-rw-r--r--qa/qa/service/docker_run/smocker.rb6
-rw-r--r--qa/qa/service/docker_run/video.rb50
-rw-r--r--qa/qa/service/praefect_manager.rb182
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb114
-rw-r--r--qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb96
-rw-r--r--qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb5
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb4
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb6
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb8
-rw-r--r--qa/qa/specs/features/api/1_manage/rate_limits_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb77
-rw-r--r--qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb24
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_facebook_spec.rb18
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/design_management/add_design_content_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_file_upload_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb99
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_job_artifacts/unlocking_job_artifacts_across_pipelines_spec.rb22
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb118
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb10
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb115
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb15
-rw-r--r--qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb2
-rw-r--r--qa/qa/specs/features/shared_contexts/import/gitlab_group_migration_common.rb2
-rw-r--r--qa/qa/support/formatters/allure_metadata_formatter.rb1
-rw-r--r--qa/qa/support/formatters/test_metrics_formatter.rb8
-rw-r--r--qa/qa/support/helpers/mask_token.rb2
-rw-r--r--qa/qa/support/influxdb_tools.rb27
-rw-r--r--qa/qa/support/matchers/have_matcher.rb1
-rw-r--r--qa/qa/support/parallel_pipeline_jobs.rb2
-rw-r--r--qa/qa/support/wait_for_requests.rb6
-rw-r--r--qa/qa/tools/ci/qa_changes.rb4
-rw-r--r--qa/qa/tools/test_resources_handler.rb1
-rw-r--r--qa/qa/vendor/facebook/page/login.rb23
-rw-r--r--qa/qa/vendor/github/page/base.rb14
-rw-r--r--qa/qa/vendor/github/page/login.rb11
-rw-r--r--qa/qa/vendor/page/base.rb14
-rw-r--r--qa/qa/vendor/saml_idp/page/base.rb14
-rw-r--r--qa/qa/vendor/saml_idp/page/login.rb10
-rw-r--r--qa/qa/vendor/smocker/smocker_api.rb2
-rw-r--r--qa/spec/runtime/feature_spec.rb2
-rw-r--r--qa/spec/service/docker_run/video_spec.rb28
-rw-r--r--qa/spec/support/formatters/allure_metadata_formatter_spec.rb10
123 files changed, 932 insertions, 1084 deletions
diff --git a/qa/Dockerfile b/qa/Dockerfile
index bd9cd166701..213ec3450cb 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -40,6 +40,8 @@ WORKDIR /home/gitlab/qa
# Install qa dependencies or fetch from cache if unchanged
#
COPY ./qa/Gemfile* /home/gitlab/qa/
+COPY ./vendor/gems/ /home/gitlab/vendor/gems/
+COPY ./gems/ /home/gitlab/gems/
RUN bundle config set --local without development \
&& bundle install --retry=3
@@ -47,7 +49,6 @@ COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/co
COPY ./config/feature_flags /home/gitlab/config/feature_flags
COPY ./config/bundler_setup.rb /home/gitlab/config/
COPY ./lib/gitlab_edition.rb /home/gitlab/lib/
-COPY ./lib/gitlab/utils.rb /home/gitlab/lib/gitlab/
COPY ./INSTALLATION_TYPE ./VERSION /home/gitlab/
COPY ./qa /home/gitlab/qa
diff --git a/qa/Gemfile b/qa/Gemfile
index a06914ca7de..e9616f29731 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,9 +2,10 @@
source 'https://rubygems.org'
-gem 'gitlab-qa', '~> 11', '>= 11.2.0', require: 'gitlab/qa'
-gem 'gitlab_quality-test_tooling', '~> 0.8.1', require: false
-gem 'activesupport', '~> 6.1.7.2' # This should stay in sync with the root's Gemfile
+gem 'gitlab-qa', '~> 12', '>= 12.1.0', require: 'gitlab/qa'
+gem 'gitlab_quality-test_tooling', '~> 0.8.3', require: false
+gem 'gitlab-utils', path: '../gems/gitlab-utils'
+gem 'activesupport', '~> 7.0.5.1' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.20.0'
gem 'capybara', '~> 3.39.2'
gem 'capybara-screenshot', '~> 1.0.26'
@@ -39,7 +40,7 @@ gem 'chemlab', '~> 0.10'
gem 'chemlab-library-www-gitlab-com', '~> 0.1', '>= 0.1.1'
# dependencies for jenkins client
-gem 'nokogiri', '~> 1.15', '>= 1.15.2'
+gem 'nokogiri', '~> 1.15', '>= 1.15.3'
gem 'deprecation_toolkit', '~> 2.0.3', require: false
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index e4e89e7e2e1..521f101ee4d 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -1,12 +1,27 @@
+PATH
+ remote: ../gems/gitlab-utils
+ specs:
+ gitlab-utils (0.1.0)
+ actionview (>= 6.1.7.2)
+ activesupport (>= 6.1.7.2)
+ addressable (~> 2.8)
+ nokogiri (~> 1.15.2)
+ rake (~> 13.0)
+
GEM
remote: https://rubygems.org/
specs:
- activesupport (6.1.7.2)
+ actionview (7.0.5.1)
+ activesupport (= 7.0.5.1)
+ builder (~> 3.1)
+ erubi (~> 1.4)
+ rails-dom-testing (~> 2.0)
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
+ activesupport (7.0.5.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
- zeitwerk (~> 2.3)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
airborne (0.3.7)
@@ -55,6 +70,7 @@ GEM
confiner (0.4.0)
gitlab (>= 4.17)
zeitwerk (>= 2.5, < 3)
+ crass (1.0.6)
debug_inspector (1.1.0)
declarative (0.0.20)
deprecation_toolkit (2.0.3)
@@ -62,6 +78,7 @@ GEM
diff-lcs (1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
+ erubi (1.12.0)
excon (0.92.4)
faker (3.2.0)
i18n (>= 1.8.11, < 2)
@@ -102,8 +119,8 @@ GEM
gitlab (4.19.0)
httparty (~> 0.20)
terminal-table (>= 1.5.1)
- gitlab-qa (11.2.0)
- activesupport (~> 6.1)
+ gitlab-qa (12.1.0)
+ activesupport (>= 6.1, < 7.1)
gitlab (~> 4.19)
http (~> 5.0)
nokogiri (~> 1.10)
@@ -111,7 +128,7 @@ GEM
rainbow (>= 3, < 4)
table_print (= 1.5.7)
zeitwerk (>= 2, < 3)
- gitlab_quality-test_tooling (0.8.1)
+ gitlab_quality-test_tooling (0.8.3)
activesupport (>= 6.1, < 7.1)
gitlab (~> 4.19)
http (~> 5.0)
@@ -176,6 +193,9 @@ GEM
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
+ loofah (2.21.3)
+ crass (~> 1.0.2)
+ nokogiri (>= 1.12.0)
macaddr (1.7.2)
systemu (~> 2.6.5)
matrix (0.4.2)
@@ -186,11 +206,11 @@ GEM
mime-types-data (3.2023.0218.1)
mini_mime (1.1.0)
mini_portile2 (2.8.2)
- minitest (5.18.0)
+ minitest (5.18.1)
multi_json (1.15.0)
multi_xml (0.6.0)
netrc (0.11.0)
- nokogiri (1.15.2)
+ nokogiri (1.15.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
octokit (6.1.1)
@@ -214,10 +234,15 @@ GEM
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
public_suffix (5.0.1)
- racc (1.6.2)
+ racc (1.7.1)
rack (2.2.3.1)
rack-test (1.1.0)
rack (>= 1.0, < 3)
+ rails-dom-testing (2.0.3)
+ activesupport (>= 4.2.0)
+ nokogiri (>= 1.6)
+ rails-html-sanitizer (1.5.0)
+ loofah (~> 2.19, >= 2.19.1)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.1.1)
@@ -310,7 +335,7 @@ PLATFORMS
ruby
DEPENDENCIES
- activesupport (~> 6.1.7.2)
+ activesupport (~> 7.0.5.1)
airborne (~> 0.3.7)
allure-rspec (~> 2.20.0)
capybara (~> 3.39.2)
@@ -323,11 +348,12 @@ DEPENDENCIES
faraday-retry (~> 2.2)
fog-core (= 2.1.0)
fog-google (~> 1.19)
- gitlab-qa (~> 11, >= 11.2.0)
- gitlab_quality-test_tooling (~> 0.8.1)
+ gitlab-qa (~> 12, >= 12.1.0)
+ gitlab-utils!
+ gitlab_quality-test_tooling (~> 0.8.3)
influxdb-client (~> 2.9)
knapsack (~> 4.0)
- nokogiri (~> 1.15, >= 1.15.2)
+ nokogiri (~> 1.15, >= 1.15.3)
octokit (~> 6.1.1)
parallel (~> 1.23)
parallel_tests (~> 4.2, >= 4.2.1)
@@ -348,4 +374,4 @@ DEPENDENCIES
zeitwerk (~> 2.6, >= 2.6.8)
BUNDLED WITH
- 2.4.14
+ 2.4.15
diff --git a/qa/gdk/Dockerfile.gdk b/qa/gdk/Dockerfile.gdk
index cf9cea69056..51e058a7088 100644
--- a/qa/gdk/Dockerfile.gdk
+++ b/qa/gdk/Dockerfile.gdk
@@ -88,17 +88,11 @@ RUN set -eux; \
rm -rf ${GEM_HOME}/cache \
&& go clean -cache
-# Build metrics-exporter
-#
-COPY --chown=gdk:gdk GITLAB_METRICS_EXPORTER_VERSION ./gitlab/
-RUN set -eux; \
- make gitlab-metrics-exporter-setup; \
- go clean -cache
-
# Install gitlab gem dependencies
#
COPY --chown=gdk:gdk Gemfile Gemfile.lock ./gitlab/
-COPY --chown=gdk:gdk vendor/gems ./gitlab/vendor/gems
+COPY --chown=gdk:gdk vendor/gems/ ./gitlab/vendor/gems/
+COPY --chown=gdk:gdk gems/ ./gitlab/gems/
RUN make .gitlab-bundle && rm -rf ${GEM_HOME}/cache
# Install gitlab npm dependencies
diff --git a/qa/qa.rb b/qa/qa.rb
index f6fba30c079..0e3d343b861 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -2,8 +2,9 @@
Encoding.default_external = 'UTF-8'
+require 'gitlab/utils/all'
+
require_relative '../lib/gitlab_edition'
-require_relative '../lib/gitlab/utils'
require_relative '../config/initializers/0_inject_enterprise_edition_module'
require_relative 'lib/gitlab'
diff --git a/qa/qa/fixtures/package_managers/maven/gradle/build.gradle.erb b/qa/qa/fixtures/package_managers/maven/gradle/build.gradle.erb
new file mode 100644
index 00000000000..77e5398bf13
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/gradle/build.gradle.erb
@@ -0,0 +1,51 @@
+plugins {
+ id 'java'
+ id 'maven-publish'
+ id 'application'
+}
+
+repositories {
+ maven {
+ url "<%= gitlab_address_with_port %>/api/v4/projects/<%= project.id %>/packages/maven"
+ name "GitLab"
+ credentials(HttpHeaderCredentials) {
+ name = '<%= maven_header_name %>'
+ value = project.property('Token')
+ }
+ authentication {
+ header(HttpHeaderAuthentication)
+ }
+ }
+}
+
+dependencies {
+ implementation group: '<%= group_id %>', name: '<%= artifact_id %>', version: '<%= package_version %>'
+ testImplementation 'junit:junit:4.12'
+}
+
+publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ groupId '<%= group_id %>'
+ artifactId '<%= artifact_id %>'
+ version '<%= package_version %>'
+ from components.java
+ }
+ }
+ repositories {
+ maven {
+ url "<%= gitlab_address_with_port %>/api/v4/projects/<%= project.id %>/packages/maven"
+ credentials(HttpHeaderCredentials) {
+ name = '<%= maven_header_name %>'
+ value = project.property('Token')
+ }
+ authentication {
+ header(HttpHeaderAuthentication)
+ }
+ }
+ }
+}
+
+application {
+ mainClassName = 'gradle_maven_app.App'
+}
diff --git a/qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb b/qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb
deleted file mode 100644
index 31543d30e88..00000000000
--- a/qa/qa/fixtures/package_managers/maven/gradle/build_install.gradle.erb
+++ /dev/null
@@ -1,27 +0,0 @@
-plugins {
- id 'java'
- id 'application'
-}
-
-repositories {
- maven {
- url "<%= gitlab_address_with_port %>/api/v4/projects/<%= package_project.id %>/packages/maven"
- name "GitLab"
- credentials(HttpHeaderCredentials) {
- name = '<%= maven_header_name %>'
- value = <%= token %>
- }
- authentication {
- header(HttpHeaderAuthentication)
- }
- }
-}
-
-dependencies {
- implementation group: '<%= group_id %>', name: '<%= artifact_id %>', version: '<%= package_version %>'
- testImplementation 'junit:junit:4.12'
-}
-
-application {
- mainClassName = 'gradle_maven_app.App'
-} \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb b/qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb
deleted file mode 100644
index c14e63e11df..00000000000
--- a/qa/qa/fixtures/package_managers/maven/gradle/build_upload.gradle.erb
+++ /dev/null
@@ -1,27 +0,0 @@
-plugins {
- id 'java'
- id 'maven-publish'
-}
-
-publishing {
- publications {
- library(MavenPublication) {
- groupId '<%= group_id %>'
- artifactId '<%= artifact_id %>'
- version '<%= package_version %>'
- from components.java
- }
- }
- repositories {
- maven {
- url "<%= gitlab_address_with_port %>/api/v4/projects/<%= package_project.id %>/packages/maven"
- credentials(HttpHeaderCredentials) {
- name = "Private-Token"
- value = "<%= personal_access_token %>"
- }
- authentication {
- header(HttpHeaderAuthentication)
- }
- }
- }
-} \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb
deleted file mode 100644
index 49873f124cc..00000000000
--- a/qa/qa/fixtures/package_managers/maven/gradle/gradle_install_package.yaml.erb
+++ /dev/null
@@ -1,8 +0,0 @@
- build:
- image: gradle:6.5-jdk11
- script:
- - 'gradle build'
- only:
- - "<%= client_project.default_branch %>"
- tags:
- - "runner-for-<%= client_project.group.name %>" \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_install_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_install_package.yaml.erb
new file mode 100644
index 00000000000..35f4dba6130
--- /dev/null
+++ b/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_install_package.yaml.erb
@@ -0,0 +1,23 @@
+stages:
+ - publish
+ - install
+
+publish:
+ stage: publish
+ image: gradle:6.5-jdk11
+ script:
+ - 'gradle -PToken=<%= token %> publish'
+ only:
+ - "<%= project.default_branch %>"
+ tags:
+ - "runner-for-<%= project.name %>"
+
+install:
+ stage: install
+ image: gradle:6.5-jdk11
+ script:
+ - 'gradle -PToken=<%= token %> build'
+ only:
+ - "<%= project.default_branch %>"
+ tags:
+ - "runner-for-<%= project.name %>"
diff --git a/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb b/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb
deleted file mode 100644
index 3f3c7dce03c..00000000000
--- a/qa/qa/fixtures/package_managers/maven/gradle/gradle_upload_package.yaml.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-deploy:
- image: gradle:6.5-jdk11
- script:
- - 'gradle publish'
- only:
- - "<%= package_project.default_branch %>"
- tags:
- - "runner-for-<%= package_project.group.name %>" \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/gitlab_ci.yaml.erb b/qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/gitlab_ci.yaml.erb
deleted file mode 100644
index 394c6689eef..00000000000
--- a/qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/gitlab_ci.yaml.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-install:
- image: maven:3.6-jdk-11
- script:
- - "mvn install -U -s settings.xml"
- only:
- - "<%= imported_project.default_branch %>"
- tags:
- - "runner-for-<%= imported_project.group.name %>" \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/settings.xml.erb b/qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/settings.xml.erb
deleted file mode 100644
index 4bcd63b3c6d..00000000000
--- a/qa/qa/fixtures/package_managers/maven/group/consumer/request_forwarding/settings.xml.erb
+++ /dev/null
@@ -1,23 +0,0 @@
-<settings>
- <servers>
- <server>
- <id>central-proxy</id>
- <configuration>
- <httpHeaders>
- <property>
- <name>Private-Token</name>
- <value><%= personal_access_token %></value>
- </property>
- </httpHeaders>
- </configuration>
- </server>
- </servers>
- <mirrors>
- <mirror>
- <id>central-proxy</id>
- <name>GitLab proxy of central repo</name>
- <url><%= gitlab_address_with_port %>/api/v4/groups/<%= imported_project.group.id %>/-/packages/maven</url>
- <mirrorOf>central</mirrorOf>
- </mirror>
- </mirrors>
-</settings> \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb b/qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb
deleted file mode 100644
index a41bdc4d650..00000000000
--- a/qa/qa/fixtures/package_managers/maven/project/request_forwarding/gitlab_ci.yaml.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-install:
- image: maven:3.6-jdk-11
- script:
- - 'mvn install -U -s settings.xml'
- only:
- - "<%= imported_project.default_branch %>"
- tags:
- - "runner-for-<%= imported_project.name %>" \ No newline at end of file
diff --git a/qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb b/qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb
deleted file mode 100644
index caf1fc9b761..00000000000
--- a/qa/qa/fixtures/package_managers/maven/project/request_forwarding/settings.xml.erb
+++ /dev/null
@@ -1,23 +0,0 @@
-<settings>
- <servers>
- <server>
- <id>central-proxy</id>
- <configuration>
- <httpHeaders>
- <property>
- <name>Private-Token</name>
- <value><%= personal_access_token %></value>
- </property>
- </httpHeaders>
- </configuration>
- </server>
- </servers>
- <mirrors>
- <mirror>
- <id>central-proxy</id>
- <name>GitLab proxy of central repo</name>
- <url><%= gitlab_address_with_port %>/api/v4/projects/<%= imported_project.id %>/packages/maven</url>
- <mirrorOf>central</mirrorOf>
- </mirror>
- </mirrors>
-</settings>
diff --git a/qa/qa/fixtures/package_managers/pypi/pypi_upload_install_package.yaml.erb b/qa/qa/fixtures/package_managers/pypi/pypi_upload_install_package.yaml.erb
index 87c01fb5477..3cd1b1e630f 100644
--- a/qa/qa/fixtures/package_managers/pypi/pypi_upload_install_package.yaml.erb
+++ b/qa/qa/fixtures/package_managers/pypi/pypi_upload_install_package.yaml.erb
@@ -14,6 +14,6 @@ run:
install:
stage: install
script:
- - "pip install <%= package.name %> --no-deps --index-url <%= uri.scheme %>://<%= personal_access_token %>:<%= personal_access_token %>@<%= gitlab_host_with_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple --trusted-host <%= gitlab_host_with_port %>"
+ - "pip install <%= package.name %> --no-deps --index-url <%= uri.scheme %>://${PERSONAL_ACCESS_TOKEN}:${PERSONAL_ACCESS_TOKEN}@<%= gitlab_host_with_port %>/api/v4/projects/${CI_PROJECT_ID}/packages/pypi/simple --trusted-host <%= gitlab_host_with_port %>"
tags:
- runner-for-<%= project.name %>
diff --git a/qa/qa/flow/alert_settings.rb b/qa/qa/flow/alert_settings.rb
index f5ee4f94065..7bda1585b39 100644
--- a/qa/qa/flow/alert_settings.rb
+++ b/qa/qa/flow/alert_settings.rb
@@ -27,7 +27,6 @@ module QA
alert.add_new_integration
alert.select_prometheus
alert.activate_integration
- alert.fill_in_prometheus_url
alert.save_and_create_alert
end
end
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index 35c5262e767..0e8a1c68bc5 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -144,7 +144,7 @@ module QA
end
def init_repository
- run_git("git init")
+ run_git("git init --initial-branch=#{default_branch}")
end
def pull(repository = nil, branch = nil)
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 6c01fa9f344..92b4fd39759 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -4,6 +4,11 @@ require 'capybara/dsl'
module QA
module Page
+ # Page base class
+ #
+ # @!method self.perform
+ # Perform action on the page
+ # @yieldparam [self] instance of page object
class Base
# Generic matcher for common css selectors like:
# - class name '.someclass'
@@ -518,6 +523,12 @@ module QA
"Could not find the expected element as #{element_when_flag_enabled} or #{element_when_flag_disabled}." \
"The relevant feature flag is #{feature_flag}"
end
+
+ def wait_for_gitlab_to_respond
+ wait_until(sleep_interval: 5, message: '502 - GitLab is taking too much time to respond') do
+ Capybara.page.has_no_text?('GitLab is taking too much time to respond')
+ end
+ end
end
end
end
diff --git a/qa/qa/page/component/confirm_modal.rb b/qa/qa/page/component/confirm_modal.rb
index 4d1cf30c392..f72ca4f068e 100644
--- a/qa/qa/page/component/confirm_modal.rb
+++ b/qa/qa/page/component/confirm_modal.rb
@@ -11,6 +11,7 @@ module QA
base.view 'app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue' do
element :confirm_ok_button
+ element :confirmation_modal
end
base.view 'app/assets/javascripts/vue_shared/components/confirm_danger/confirm_danger_modal.vue' do
@@ -37,6 +38,20 @@ module QA
def click_confirmation_ok_button
click_element(:confirm_ok_button)
end
+
+ # Click the confirmation button if the confirmation modal is present
+ # Can be used when the modal may not always appear in a test. For example, if the modal is behind a feature flag
+ #
+ # @return [void]
+ def click_confirmation_ok_button_if_present
+ # In the case of changing access levels[1], the modal appears while there's a request in process, so we need
+ # to skip the loading check otherwise it will time out.
+ #
+ # [1]: https://gitlab.com/gitlab-org/gitlab/-/blob/4a99af809b86047ce3c8985e6582748bbd23fc84/qa/qa/page/component/members/members_table.rb#L54
+ return unless has_element?(:confirmation_modal, skip_finished_loading_check: true)
+
+ click_element(:confirm_ok_button, skip_finished_loading_check: true)
+ end
end
end
end
diff --git a/qa/qa/page/component/design_management.rb b/qa/qa/page/component/design_management.rb
index 71c24b6cac8..4caa5169c5f 100644
--- a/qa/qa/page/component/design_management.rb
+++ b/qa/qa/page/component/design_management.rb
@@ -78,7 +78,7 @@ module QA
end
def update_design(filename)
- filepath = ::File.join(Runtime::Path.fixtures_path, 'designs', 'update', filename)
+ filepath = Runtime::Path.fixture('designs', 'update', filename)
add_design(filepath)
end
diff --git a/qa/qa/page/component/dropdown.rb b/qa/qa/page/component/dropdown.rb
index 767cd40daa2..5f60a789900 100644
--- a/qa/qa/page/component/dropdown.rb
+++ b/qa/qa/page/component/dropdown.rb
@@ -33,12 +33,13 @@ module QA
def clear_current_selection_if_present
expand_select_list unless dropdown_open?
+ Support::WaitForRequests.wait_for_requests
- if has_css?('button[data-testid="listbox-reset-button"]')
+ if has_css?('button[data-testid="listbox-reset-button"]', wait: 0)
find('button[data-testid="listbox-reset-button"]').click
- elsif dropdown_open?
- expand_select_list
end
+
+ expand_select_list if dropdown_open?
end
def search_item(item_text)
diff --git a/qa/qa/page/component/issuable/sidebar.rb b/qa/qa/page/component/issuable/sidebar.rb
index 06a3c6a8845..15155fd9f44 100644
--- a/qa/qa/page/component/issuable/sidebar.rb
+++ b/qa/qa/page/component/issuable/sidebar.rb
@@ -31,7 +31,7 @@ module QA
end
base.view 'app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents.vue' do
- element :labels_dropdown_content
+ element :labels_select_dropdown_contents
end
base.view 'app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_value.vue' do
@@ -137,7 +137,7 @@ module QA
click_element(:edit_button)
labels.each do |label|
- within_element(:labels_dropdown_content) do
+ within_element(:labels_select_dropdown_contents) do
fill_element(:dropdown_input_field, label)
click_button(text: label)
end
diff --git a/qa/qa/page/component/members/invite_members_modal.rb b/qa/qa/page/component/members/invite_members_modal.rb
index 0220bb1e4fc..ae51213b3e2 100644
--- a/qa/qa/page/component/members/invite_members_modal.rb
+++ b/qa/qa/page/component/members/invite_members_modal.rb
@@ -6,6 +6,7 @@ module QA
module Members
module InviteMembersModal
extend QA::Page::PageConcern
+ include QA::Page::Component::Dropdown
def self.included(base)
super
@@ -16,11 +17,6 @@ module QA
element :invite_members_modal_content
end
- base.view 'app/assets/javascripts/invite_members/components/group_select.vue' do
- element :group_select_dropdown_search_field
- element :group_select_dropdown_item
- end
-
base.view 'app/assets/javascripts/invite_members/components/members_token_select.vue' do
element :members_token_select_input
end
@@ -61,11 +57,9 @@ module QA
within_element(:invite_members_modal_content) do
click_button 'Select a group'
- Support::Waiter.wait_until { has_element?(:group_select_dropdown_item) }
-
- fill_element :group_select_dropdown_search_field, group_name
Support::WaitForRequests.wait_for_requests
- click_button group_name
+
+ search_and_select(group_name)
set_access_level(access_level)
end
diff --git a/qa/qa/page/component/members/members_table.rb b/qa/qa/page/component/members/members_table.rb
index 46010a0f9ab..15b0f230341 100644
--- a/qa/qa/page/component/members/members_table.rb
+++ b/qa/qa/page/component/members/members_table.rb
@@ -14,6 +14,7 @@ module QA
include MembersFilter
include RemoveMemberModal
include RemoveGroupModal
+ include ConfirmModal
end
base.view 'app/assets/javascripts/members/components/table/members_table.vue' do
@@ -53,6 +54,8 @@ module QA
click_element :access_level_dropdown
click_element :access_level_link, text: access_level
end
+
+ click_confirmation_ok_button_if_present
end
def remove_member(username)
diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb
index 84cc481945f..638c46f228f 100644
--- a/qa/qa/page/component/note.rb
+++ b/qa/qa/page/component/note.rb
@@ -73,11 +73,13 @@ module QA
end
def collapse_replies
+ close_rich_text_promo_popover_if_present
click_element :collapse_replies_button
end
# Attachment option should be an absolute path
def comment(text, attachment: nil, filter: :all_activities)
+ close_rich_text_promo_popover_if_present
method("select_#{filter}_filter").call
fill_element :comment_field, "#{text}\n"
@@ -148,7 +150,8 @@ module QA
def start_discussion(text)
fill_element :comment_field, text
- within_element(:comment_button) { click_button(class: 'dropdown-toggle-split') }
+ close_rich_text_promo_popover_if_present
+ within_element(:comment_button) { click_button(class: 'gl-new-dropdown-toggle') }
click_element :discussion_menu_item
click_element :comment_button
diff --git a/qa/qa/page/component/rich_text_popover.rb b/qa/qa/page/component/rich_text_popover.rb
new file mode 100644
index 00000000000..6a187dcedc5
--- /dev/null
+++ b/qa/qa/page/component/rich_text_popover.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Component
+ module RichTextPopover
+ extend QA::Page::PageConcern
+
+ def self.included(base)
+ super
+
+ base.view 'app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue' do
+ element :rich_text_promo_popover
+ end
+
+ base.view 'app/views/shared/_broadcast_message.html.haml' do
+ element :close_button
+ end
+ end
+
+ def close_rich_text_promo_popover_if_present
+ return unless has_element?(:rich_text_promo_popover, wait: 0)
+
+ within_element(:rich_text_promo_popover) do
+ click_element(:close_button)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/file/form.rb b/qa/qa/page/file/form.rb
index d0113d66dec..06b75f42e4d 100644
--- a/qa/qa/page/file/form.rb
+++ b/qa/qa/page/file/form.rb
@@ -46,7 +46,7 @@ module QA
when 'LICENSE'
click_element :license_dropdown
else
- raise %Q(Unsupported template_type "#{template_type}". Please confirm that it is a valid option.)
+ raise %(Unsupported template_type "#{template_type}". Please confirm that it is a valid option.)
end
filter_and_select template
end
diff --git a/qa/qa/page/group/bulk_import.rb b/qa/qa/page/group/bulk_import.rb
index 90bc7a66dcc..f57b76b11a9 100644
--- a/qa/qa/page/group/bulk_import.rb
+++ b/qa/qa/page/group/bulk_import.rb
@@ -8,6 +8,7 @@ module QA
element :import_table
element :import_item
element :import_status_indicator
+ element :filter_groups
end
view "app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue" do
@@ -22,6 +23,12 @@ module QA
element :import_group_button
end
+ def filter_group(source_group_name)
+ find('input[data-testid="filter-groups"]').set(source_group_name).send_keys(:return)
+
+ finished_loading?
+ end
+
# Import source group in to target group
#
# @param [String] source_group_name
@@ -30,6 +37,8 @@ module QA
def import_group(source_group_name, target_group_name)
finished_loading?
+ filter_group(source_group_name)
+
within_element(:import_item, source_group: source_group_name) do
click_element(:target_namespace_selector_dropdown)
click_element(:target_group_dropdown_item, group_name: target_group_name)
diff --git a/qa/qa/page/group/sub_menus/common.rb b/qa/qa/page/group/sub_menus/common.rb
index 3cbca3db359..6369306da3f 100644
--- a/qa/qa/page/group/sub_menus/common.rb
+++ b/qa/qa/page/group/sub_menus/common.rb
@@ -13,7 +13,7 @@ module QA
base.class_eval do
view 'app/views/shared/nav/_sidebar.html.haml' do
- element :group_sidebar, 'qa_selector: sidebar_qa_selector(sidebar.container)' # rubocop:disable QA/ElementWithPattern
+ element :group_sidebar, 'testid: sidebar_qa_selector(sidebar.container)' # rubocop:disable QA/ElementWithPattern
end
end
end
diff --git a/qa/qa/page/issuable/new.rb b/qa/qa/page/issuable/new.rb
index b74dc705888..0a8be750752 100644
--- a/qa/qa/page/issuable/new.rb
+++ b/qa/qa/page/issuable/new.rb
@@ -4,6 +4,8 @@ module QA
module Page
module Issuable
class New < Page::Base
+ include Page::Component::RichTextPopover
+
view 'app/views/shared/issuable/form/_title.html.haml' do
element :issuable_form_title_field
end
@@ -20,6 +22,10 @@ module QA
element :issuable_label_dropdown
end
+ view 'app/assets/javascripts/sidebar/components/labels/labels_select_widget/dropdown_contents.vue' do
+ element :labels_select_dropdown_contents
+ end
+
view 'app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml' do
element :assign_to_me_link
end
@@ -44,6 +50,7 @@ module QA
end
def choose_template(template_name)
+ close_rich_text_promo_popover_if_present
click_element :template_dropdown
within_element(:template_dropdown) do
click_on template_name
@@ -53,7 +60,7 @@ module QA
def select_label(label)
click_element :issuable_label_dropdown
- click_link label.title
+ click_on(label.title, match: :prefer_exact)
click_element :issuable_label_dropdown # So that the dropdown goes away(click away action)
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 3a836210dea..8812c792554 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -43,6 +43,7 @@ module QA
element :github_login_button
element :oidc_login_button
element :gitlab_oauth_login_button
+ element :facebook_login_button
end
view 'app/views/layouts/devise.html.haml' do
@@ -102,6 +103,12 @@ module QA
click_element :sign_in_button
end
+ if Runtime::Env.super_sidebar_enabled?
+ Page::Main::Menu.perform(&:enable_new_navigation)
+ else
+ Page::Main::Menu.perform(&:disable_new_navigation)
+ end
+
Page::Main::Menu.perform(&:signed_in?)
end
@@ -128,8 +135,8 @@ module QA
'/users/sign_in'
end
- def has_sign_in_tab?
- has_element?(:sign_in_tab)
+ def has_sign_in_tab?(wait: Capybara.default_max_wait_time)
+ has_element?(:sign_in_tab, wait: wait)
end
def has_ldap_tab?
@@ -186,6 +193,11 @@ module QA
click_element :github_login_button
end
+ def sign_in_with_facebook
+ set_initial_password_if_present
+ click_element :facebook_login_button
+ end
+
def sign_in_with_saml
set_initial_password_if_present
click_element :saml_login_button
@@ -203,7 +215,6 @@ module QA
def sign_out_and_sign_in_as(user:)
Menu.perform(&:sign_out_if_signed_in)
- has_sign_in_tab?
sign_in_using_credentials(user: user)
end
@@ -225,7 +236,7 @@ module QA
def sign_in_using_gitlab_credentials(user:, skip_page_validation: false)
wait_if_retry_later
- switch_to_sign_in_tab if has_sign_in_tab?
+ switch_to_sign_in_tab if has_sign_in_tab?(wait: 0)
switch_to_standard_tab if has_standard_tab?
fill_in_credential(user)
@@ -258,7 +269,11 @@ module QA
wait_for_gitlab_to_respond
- Page::Main::Menu.perform(&:enable_new_navigation) if Runtime::Env.super_sidebar_enabled?
+ if Runtime::Env.super_sidebar_enabled?
+ Page::Main::Menu.perform(&:enable_new_navigation)
+ else
+ Page::Main::Menu.perform(&:disable_new_navigation)
+ end
wait_for_gitlab_to_respond
diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb
index 7e0337035e3..29c4360f814 100644
--- a/qa/qa/page/main/menu.rb
+++ b/qa/qa/page/main/menu.rb
@@ -20,7 +20,7 @@ module QA
end
view 'app/assets/javascripts/super_sidebar/components/user_menu.vue' do
- element :user_menu, required: !Runtime::Env.phone_layout?
+ element :user_dropdown, required: !Runtime::Env.phone_layout?
element :user_avatar_content, required: !Runtime::Env.phone_layout?
element :sign_out_link
element :edit_profile_link
@@ -31,8 +31,11 @@ module QA
end
view 'app/assets/javascripts/super_sidebar/components/user_bar.vue' do
- element :global_search_button
- element :stop_impersonation_link
+ element :super_sidebar_search_button
+ element :stop_impersonation_btn
+ element :issues_shortcut_button, required: !Runtime::Env.phone_layout?
+ element :merge_requests_shortcut_button, required: !Runtime::Env.phone_layout?
+ element :todos_shortcut_button, required: !Runtime::Env.phone_layout?
end
view 'app/assets/javascripts/super_sidebar/components/global_search/components/global_search.vue' do
@@ -43,8 +46,8 @@ module QA
element :navbar, required: true
element :canary_badge_link
element :user_avatar_content, required: !Runtime::Env.phone_layout?
- element :user_menu, required: !Runtime::Env.phone_layout?
- element :stop_impersonation_link
+ element :user_dropdown, required: !Runtime::Env.phone_layout?
+ element :stop_impersonation_btn
element :issues_shortcut_button, required: !Runtime::Env.phone_layout?
element :merge_requests_shortcut_button, required: !Runtime::Env.phone_layout?
element :todos_shortcut_button, required: !Runtime::Env.phone_layout?
@@ -62,7 +65,7 @@ module QA
end
view 'app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue' do
- element :menu_subview_container
+ element :menu_subview
end
view 'lib/gitlab/nav/top_nav_menu_item.rb' do
@@ -240,7 +243,7 @@ module QA
end
def search_for(term)
- click_element(Runtime::Env.super_sidebar_enabled? ? :global_search_button : :search_box)
+ click_element(Runtime::Env.super_sidebar_enabled? ? :super_sidebar_search_button : :search_box)
fill_element(:global_search_input, "#{term}\n")
end
@@ -262,7 +265,7 @@ module QA
end
def click_stop_impersonation_link
- click_element(:stop_impersonation_link)
+ click_element(:stop_impersonation_btn)
end
# To verify whether the user has been directed to a canary web node
@@ -278,11 +281,23 @@ module QA
def enable_new_navigation
Runtime::Logger.info("Enabling super sidebar!")
return Runtime::Logger.info("User is not signed in, skipping") unless has_element?(:navbar, wait: 2)
+
return Runtime::Logger.info("Super sidebar is already enabled") if has_css?('[data-testid="super-sidebar"]')
within_user_menu { click_element(:new_navigation_toggle) }
end
+ def disable_new_navigation
+ Runtime::Logger.info("Disabling super sidebar!")
+ return Runtime::Logger.info("User is not signed in, skipping") unless has_element?(:navbar, wait: 2)
+
+ unless has_css?('[data-testid="super-sidebar"]')
+ return Runtime::Logger.info("Super sidebar is already disabled")
+ end
+
+ within_user_menu { click_element(:new_navigation_toggle) }
+ end
+
private
def within_top_menu(&block)
@@ -293,20 +308,20 @@ module QA
within_top_menu do
click_element :user_avatar_content unless has_element?(:user_profile_link, wait: 1)
- within_element(:user_menu, &block)
+ within_element(:user_dropdown, &block)
end
end
def within_groups_menu(&block)
go_to_menu_dropdown_option(:groups_dropdown)
- within_element(:menu_subview_container, &block)
+ within_element(:menu_subview, &block)
end
def within_projects_menu(&block)
go_to_menu_dropdown_option(:projects_dropdown)
- within_element(:menu_subview_container, &block)
+ within_element(:menu_subview, &block)
end
def click_admin_area
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index e0ec5d50bc5..71c2aa2d0b3 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -6,6 +6,7 @@ module QA
class Show < Page::Base
include Page::Component::Note
include Page::Component::Issuable::Sidebar
+ include Page::Component::RichTextPopover
view 'app/assets/javascripts/batch_comments/components/preview_dropdown.vue' do
element :review_preview_dropdown
@@ -285,6 +286,7 @@ module QA
end
def merge!
+ close_rich_text_promo_popover_if_present
try_to_merge!
finished_loading?
@@ -331,13 +333,15 @@ module QA
#
# @param [Boolean] transient_test true if the current test is a transient test (default: false)
def wait_until_ready_to_merge(transient_test: false)
- wait_until do
- has_element?(:merge_button)
+ wait_until(message: "Waiting for ready to merge", sleep_interval: 1) do
+ # changes in mr are rendered async, because of that mr can sometimes show no changes and there will be no
+ # merge button, in such case we must retry loop otherwise find_element will raise ElementNotFound error
+ next false unless has_element?(:merge_button, wait: 1)
break true unless find_element(:merge_button).disabled?
# If the widget shows "Merge blocked: new changes were just added" we can refresh the page and check again
- next false if has_element?(:head_mismatch_content)
+ next false if has_element?(:head_mismatch_content, wait: 1)
# Stop waiting if we're in a transient test. By this point we're in an unexpected state and should let the
# test fail so we can investigate. If we're not in a transient test we keep trying until we reach timeout.
@@ -364,6 +368,7 @@ module QA
end
def merge_immediately!
+ close_rich_text_promo_popover_if_present
retry_until(reload: true, sleep_interval: 1, max_attempts: 12) do
if has_element?(:merge_moment_dropdown)
click_element(:merge_moment_dropdown, skip_finished_loading_check: true)
@@ -377,6 +382,7 @@ module QA
end
def try_to_merge!
+ close_rich_text_promo_popover_if_present
# Revisit after merge page re-architect is done https://gitlab.com/gitlab-org/gitlab/-/issues/300042
# To remove page refresh logic if possible
wait_until_ready_to_merge
diff --git a/qa/qa/page/project/branches/show.rb b/qa/qa/page/project/branches/show.rb
index af328f876f7..bbe0f91abf6 100644
--- a/qa/qa/page/project/branches/show.rb
+++ b/qa/qa/page/project/branches/show.rb
@@ -14,7 +14,6 @@ module QA
end
view 'app/views/projects/branches/_branch.html.haml' do
- element :badge_content
element :branch_container
element :branch_link
end
@@ -23,13 +22,6 @@ module QA
element :all_branches_container
end
- view 'app/assets/javascripts/branches/components/delete_merged_branches.vue' do
- element :delete_merged_branches_dropdown_button
- element :delete_merged_branches_button
- element :delete_merged_branches_input
- element :delete_merged_branches_confirmation_button
- end
-
def delete_branch(branch_name)
within_element(:branch_container, name: branch_name) do
click_element(:delete_branch_button)
@@ -47,20 +39,6 @@ module QA
end
end
end
-
- def has_branch_with_badge?(branch_name, badge)
- within_element(:branch_container, name: branch_name) do
- has_element?(:badge_content, text: badge)
- end
- end
-
- def delete_merged_branches(branches_length)
- click_element(:delete_merged_branches_dropdown_button)
- click_element(:delete_merged_branches_button)
- fill_element(:delete_merged_branches_input, branches_length)
- click_element(:delete_merged_branches_confirmation_button)
- finished_loading?
- end
end
end
end
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
index c2f334c930a..c95375dbbb9 100644
--- a/qa/qa/page/project/issue/show.rb
+++ b/qa/qa/page/project/issue/show.rb
@@ -9,6 +9,7 @@ module QA
include Page::Component::DesignManagement
include Page::Component::Issuable::Sidebar
include Page::Component::Issuable::Common
+ include Page::Component::RichTextPopover
# 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?
diff --git a/qa/qa/page/project/pipeline/show.rb b/qa/qa/page/project/pipeline/show.rb
index 41c61aaecc8..c955b4d933d 100644
--- a/qa/qa/page/project/pipeline/show.rb
+++ b/qa/qa/page/project/pipeline/show.rb
@@ -7,19 +7,8 @@ module QA
class Show < QA::Page::Base
include Component::CiBadgeLink
- # TODO: remove element with FF pipeline_details_header_vue removal
- view 'app/assets/javascripts/vue_shared/components/header_ci_component.vue' do
- element :pipeline_header
- end
-
- # TODO: make this a requirement at page render - `required: true`
- # together with FF pipeline_details_header_vue removal
view 'app/assets/javascripts/pipelines/components/pipeline_details_header.vue' do
- element :pipeline_details_header
- end
-
- view 'app/views/projects/pipelines/_info.html.haml' do
- element :merge_request_badge_tag
+ element :pipeline_details_header, required: true
end
view 'app/assets/javascripts/pipelines/components/graph/graph_component.vue' do
@@ -63,20 +52,11 @@ module QA
end
def running?(wait: 0)
- # TODO: remove condition check together with FF pipeline_details_header_vue removal
- # issue: https://gitlab.com/gitlab-org/gitlab/-/issues/411442
-
- element = has_element?(:pipeline_details_header) ? :pipeline_details_header : :pipeline_header
-
- within_element(element) do
+ within_element(:pipeline_details_header) do
page.has_content?('running', wait: wait)
end
end
- def has_merge_request_badge_tag?
- has_element?(:merge_request_badge_tag)
- end
-
def has_build?(name, status: :success, wait: nil)
if status
within_element(:job_item_container, text: name) do
diff --git a/qa/qa/page/project/settings/alerts.rb b/qa/qa/page/project/settings/alerts.rb
index 3ff4ef20bde..2646e271bd2 100644
--- a/qa/qa/page/project/settings/alerts.rb
+++ b/qa/qa/page/project/settings/alerts.rb
@@ -25,7 +25,6 @@ module QA
element :save_and_create_alert_button
element :test_payload_field
element :send_test_alert_button
- element :prometheus_url_field
end
def go_to_alert_settings
@@ -73,19 +72,12 @@ module QA
def select_prometheus
click_element(:integration_type_dropdown)
find("option[value='PROMETHEUS']").click
-
- # Click outside of the list to close it
- click_element(:prometheus_url_field)
end
def enter_integration_name(name)
fill_element(:integration_name_field, name)
end
- def fill_in_prometheus_url(url = Runtime::Scenario.gitlab_address)
- fill_element(:prometheus_url_field, url)
- end
-
def activate_integration
within_element(:active_toggle_container) do
find('.gl-toggle').click
diff --git a/qa/qa/page/project/snippet/new.rb b/qa/qa/page/project/snippet/new.rb
index 47200ba5fda..4a13e597e15 100644
--- a/qa/qa/page/project/snippet/new.rb
+++ b/qa/qa/page/project/snippet/new.rb
@@ -20,7 +20,7 @@ module QA
# webdriver to miss the hit so we wait for the svg to load before
# clicking the button.
within_element(:svg_content) do
- has_element?(:js_lazy_loaded)
+ has_element?(:js_lazy_loaded_content)
end
click_element(:create_first_snippet_link)
end
diff --git a/qa/qa/page/project/web_ide/edit.rb b/qa/qa/page/project/web_ide/edit.rb
index 8432edff046..19802f846d8 100644
--- a/qa/qa/page/project/web_ide/edit.rb
+++ b/qa/qa/page/project/web_ide/edit.rb
@@ -178,7 +178,7 @@ module QA
within_element(:template_list_content) do
click_on file_name
rescue Capybara::ElementNotFound
- raise ElementNotFound, %Q(Couldn't find file template named "#{file_name}". Please confirm that it is a valid option.)
+ raise ElementNotFound, %(Couldn't find file template named "#{file_name}". Please confirm that it is a valid option.)
end
# Wait for the modal to fade out too
@@ -192,7 +192,7 @@ module QA
begin
click_on template
rescue Capybara::ElementNotFound
- raise ElementNotFound, %Q(Couldn't find template "#{template}" for #{file_name}. Please confirm that it exists in the list of templates.)
+ raise ElementNotFound, %(Couldn't find template "#{template}" for #{file_name}. Please confirm that it exists in the list of templates.)
end
end
end
diff --git a/qa/qa/page/user/show.rb b/qa/qa/page/user/show.rb
index f14ddea3e8b..1cfaca2fc57 100644
--- a/qa/qa/page/user/show.rb
+++ b/qa/qa/page/user/show.rb
@@ -5,10 +5,13 @@ module QA
module User
class Show < Page::Base
view 'app/views/users/show.html.haml' do
- element :follow_user_link
element :following_tab
end
+ view 'app/views/users/_follow_user.html.haml' do
+ element :follow_user_link
+ end
+
view 'app/views/shared/users/_user.html.haml' do
element :user_link
end
diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb
index e12a8f97d95..459670add36 100644
--- a/qa/qa/resource/base.rb
+++ b/qa/qa/resource/base.rb
@@ -17,7 +17,8 @@ module QA
class << self
# Initialize new instance of class without fabrication
#
- # @param [Proc] prepare_block
+ # @yieldparam [self] instance of page object
+ # @return [self]
def init(&prepare_block)
new.tap(&prepare_block)
end
diff --git a/qa/qa/resource/design.rb b/qa/qa/resource/design.rb
index 127e7ae61e3..68d8e43ad3d 100644
--- a/qa/qa/resource/design.rb
+++ b/qa/qa/resource/design.rb
@@ -111,7 +111,7 @@ module QA
private
def filepath
- ::File.join(Runtime::Path.fixtures_path, 'designs', filename)
+ Runtime::Path.fixture('designs', filename)
end
end
end
diff --git a/qa/qa/resource/events/project.rb b/qa/qa/resource/events/project.rb
index c1bd921c3cf..693fdd6168f 100644
--- a/qa/qa/resource/events/project.rb
+++ b/qa/qa/resource/events/project.rb
@@ -7,21 +7,21 @@ module QA
include Events::Base
def push_events(commit_message)
- QA::Runtime::Logger.info(%Q[#{self.class.name} - wait for and fetch push events"])
+ QA::Runtime::Logger.info(%[#{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.info(%Q[#{self.class.name} - wait_for_merge with title "#{title}"])
+ QA::Runtime::Logger.info(%[#{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.info(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"])
+ QA::Runtime::Logger.info(%[#{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
@@ -32,7 +32,7 @@ module QA
end
def wait_for_push_new_branch(branch_name = self.default_branch)
- QA::Runtime::Logger.info(%Q[#{self.class.name} - wait_for_push_new_branch with branch_name "#{branch_name}"])
+ QA::Runtime::Logger.info(%[#{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/import_project.rb b/qa/qa/resource/import_project.rb
index a490905cbd6..1709a9eb989 100644
--- a/qa/qa/resource/import_project.rb
+++ b/qa/qa/resource/import_project.rb
@@ -7,7 +7,7 @@ module QA
def initialize
@name = "ImportedProject-#{SecureRandom.hex(8)}"
- @file_path = ::File.join(Runtime::Path.fixtures_path, 'export.tar.gz')
+ @file_path = Runtime::Path.fixture('export.tar.gz')
end
def fabricate!
diff --git a/qa/qa/resource/issuable.rb b/qa/qa/resource/issuable.rb
index 5aee27b46d4..508f412711a 100644
--- a/qa/qa/resource/issuable.rb
+++ b/qa/qa/resource/issuable.rb
@@ -5,7 +5,7 @@ module QA
class Issuable < Base
using Rainbow
- # Commentes (notes) path
+ # Comments (notes) path
#
# @return [String]
def api_comments_path
diff --git a/qa/qa/resource/issue.rb b/qa/qa/resource/issue.rb
index a5d5795b0de..a39e04c61a3 100644
--- a/qa/qa/resource/issue.rb
+++ b/qa/qa/resource/issue.rb
@@ -69,6 +69,13 @@ module QA
"#{api_get_path}/related_merge_requests"
end
+ # Close issue
+ #
+ # @return [void]
+ def close
+ api_put_to(api_put_path, state_event: "close")
+ end
+
def set_issue_assignees(assignee_ids:)
put_body = { assignee_ids: assignee_ids }
response = put Runtime::API::Request.new(api_client, api_put_path).url, put_body
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index 0d1a0bb2cd4..93e8c4f3be6 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -45,7 +45,7 @@ module QA
resource.project = project
resource.api_client = api_client
resource.commit_message = 'This is a test commit'
- resource.add_files([{ 'file_path': "file-#{SecureRandom.hex(8)}.txt", 'content': 'MR init' }])
+ resource.add_files([{ file_path: "file-#{SecureRandom.hex(8)}.txt", content: 'MR init' }])
resource.branch = target_branch
resource.start_branch = project.default_branch if target_branch != project.default_branch
@@ -60,7 +60,7 @@ module QA
resource.branch = source_branch
resource.start_branch = target_branch
- files = [{ 'file_path': file_name, 'content': file_content }]
+ files = [{ file_path: file_name, content: file_content }]
update_existing_file ? resource.update_files(files) : resource.add_files(files)
end
end
@@ -139,7 +139,8 @@ module QA
source_branch: source_branch,
target_branch: target_branch,
title: title,
- reviewer_ids: reviewer_ids
+ reviewer_ids: reviewer_ids,
+ labels: labels.join(",")
}
end
diff --git a/qa/qa/resource/personal_access_token_cache.rb b/qa/qa/resource/personal_access_token_cache.rb
index 0874618201a..078df8e6779 100644
--- a/qa/qa/resource/personal_access_token_cache.rb
+++ b/qa/qa/resource/personal_access_token_cache.rb
@@ -9,9 +9,9 @@ module QA
token = @personal_access_tokens[username]
log_message = if token
- %Q[Retrieved cached token for username: #{username}, last six chars of token:#{token[-6..]}]
+ %[Retrieved cached token for username: #{username}, last six chars of token:#{token[-6..]}]
else
- %Q[No cached token found for username: #{username}]
+ %[No cached token found for username: #{username}]
end
QA::Runtime::Logger.info(log_message)
@@ -20,7 +20,7 @@ module QA
end
def self.set_token_for_username(username, token)
- QA::Runtime::Logger.info(%Q[Caching token for username: #{username}, last six chars of token:#{token[-6..]}])
+ QA::Runtime::Logger.info(%[Caching token for username: #{username}, last six chars of token:#{token[-6..]}])
@personal_access_tokens[username] = token
end
end
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index ed8074b1440..855e1edf3ef 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -3,7 +3,11 @@
module QA
module Resource
class ProjectImportedFromGithub < Resource::Project
- attr_accessor :issue_events_import, :full_notes_import, :attachments_import, :allow_partial_import
+ attr_accessor :issue_events_import,
+ :full_notes_import,
+ :attachments_import,
+ :allow_partial_import,
+ :additional_access_tokens
attribute :github_repo_id do
github_client.repository(github_repository_path).id
@@ -58,13 +62,14 @@ module QA
new_name: name,
target_namespace: @personal_namespace || group.full_path,
personal_access_token: github_personal_access_token,
+ additional_access_tokens: additional_access_tokens,
ci_cd_only: false,
optional_stages: {
single_endpoint_issue_events_import: issue_events_import,
single_endpoint_notes_import: full_notes_import,
attachments_import: attachments_import
}
- }
+ }.compact
end
def transform_api_resource(api_resource)
diff --git a/qa/qa/resource/repository/branch.rb b/qa/qa/resource/repository/branch.rb
new file mode 100644
index 00000000000..9e6132b8387
--- /dev/null
+++ b/qa/qa/resource/repository/branch.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ module Repository
+ class Branch < Base
+ attr_accessor :name, :ref
+
+ attribute :project do
+ Project.fabricate_via_api! do |resource|
+ resource.name = 'branch-project'
+ resource.initialize_with_readme = true
+ end
+ end
+
+ def initialize
+ @name = 'test'
+ @ref = Runtime::Env.default_branch
+ end
+
+ def fabricate!
+ raise NotImplementedError
+ end
+
+ def fabricate_via_api!
+ resource_web_url(api_get)
+ rescue ResourceNotFoundError
+ super
+ end
+
+ def api_get_path
+ "/projects/#{project.id}/repository/branches/#{name}"
+ end
+
+ def api_delete_path
+ api_get_path
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/repository/branches"
+ end
+
+ def api_post_body
+ {
+ branch: name,
+ ref: ref
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/runtime/application_settings.rb b/qa/qa/runtime/application_settings.rb
index 4cbce0972b6..0c88716a01c 100644
--- a/qa/qa/runtime/application_settings.rb
+++ b/qa/qa/runtime/application_settings.rb
@@ -26,6 +26,15 @@ module QA
raise("Couldn't set application settings #{application_settings.inspect}, code: '#{r.code}', body: #{body}")
end
+ # Get a single application setting
+ #
+ # @param setting [Symbol] the name of the setting to get
+ # @param api_client [Runtime::API::Client] the API client representing the admin user who will get the setting
+ # @return [String]
+ def get_application_setting(setting, api_client: admin_api_client)
+ get_application_settings(api_client: api_client).fetch(setting)
+ end
+
def get_application_settings(api_client: admin_api_client)
parse_body(get(Runtime::API::Request.new(api_client, APPLICATION_SETTINGS_PATH).url))
end
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 54f9db65afb..517cb00df41 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -253,6 +253,10 @@ module QA
enabled?(ENV['USE_SELENOID'], default: false)
end
+ def save_all_videos?
+ enabled?(ENV['QA_SAVE_ALL_VIDEOS'], default: false)
+ end
+
def require_video_variables!
docs_link = 'https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/running_against_remote_grid.md#testing-with-selenoid'
use_selenoid? || (raise ArgumentError, "USE_SELENOID is required! See docs: #{docs_link}")
@@ -282,6 +286,14 @@ module QA
ENV['QA_GITHUB_PASSWORD']
end
+ def facebook_username
+ ENV['QA_FACEBOOK_USERNAME']
+ end
+
+ def facebook_password
+ ENV['QA_FACEBOOK_PASSWORD']
+ end
+
def forker?
!!(forker_username && forker_password)
end
@@ -444,6 +456,10 @@ module QA
ENV['QA_GITHUB_ACCESS_TOKEN'].to_s.strip
end
+ def github_additional_access_tokens
+ ENV['QA_ADDITIONAL_GITHUB_ACCESS_TOKENS']
+ end
+
def require_github_access_token!
return unless github_access_token.empty?
@@ -558,6 +574,10 @@ module QA
ENV.fetch('QA_CONTAINER_REGISTRY_HOST', 'registry.gitlab.com')
end
+ def runner_container_image
+ ENV.fetch('QA_RUNNER_CONTAINER_IMAGE', 'gitlab-runner:alpine')
+ end
+
# ENV variables for authenticating against a private container registry
# These need to be set if using the
# Service::DockerRun::Mixins::ThirdPartyDocker module
@@ -622,6 +642,10 @@ module QA
ENV['QA_1P_GITHUB_UUID']
end
+ def gdk_url
+ ENV['GDK_URL']
+ end
+
private
def remote_grid_credentials
diff --git a/qa/qa/runtime/fixtures.rb b/qa/qa/runtime/fixtures.rb
index 201cf7f0fcb..4319f142bba 100644
--- a/qa/qa/runtime/fixtures.rb
+++ b/qa/qa/runtime/fixtures.rb
@@ -35,7 +35,7 @@ module QA
end
def read_fixture(fixture_path, file_name)
- File.read(File.join(Runtime::Path.fixtures_path, fixture_path, file_name))
+ File.read(Runtime::Path.fixture(fixture_path, file_name))
end
private
diff --git a/qa/qa/runtime/gpg.rb b/qa/qa/runtime/gpg.rb
index 3314b14cd68..fb2a63ba2e3 100644
--- a/qa/qa/runtime/gpg.rb
+++ b/qa/qa/runtime/gpg.rb
@@ -14,7 +14,7 @@ module QA
def key
return @key if defined?(@key)
- shell("gpg --import #{File.join(Path.fixtures_path, 'gpg', 'admin.asc')}")
+ shell("gpg --import #{Path.fixture('gpg', 'admin.asc')}")
@key = shell("gpg --armor --export #{key_id}")
end
end
diff --git a/qa/qa/runtime/path.rb b/qa/qa/runtime/path.rb
index fd451f2df19..ae1b26ca84a 100644
--- a/qa/qa/runtime/path.rb
+++ b/qa/qa/runtime/path.rb
@@ -3,14 +3,18 @@
module QA
module Runtime
module Path
- extend self
+ class << self
+ def qa_root
+ ::File.expand_path('../../', __dir__)
+ end
- def qa_root
- ::File.expand_path('../../', __dir__)
- end
+ def fixtures_path
+ ::File.expand_path('../fixtures', __dir__)
+ end
- def fixtures_path
- ::File.expand_path('../fixtures', __dir__)
+ def fixture(*args)
+ ::File.join(fixtures_path, *args)
+ end
end
end
end
diff --git a/qa/qa/scenario/test/instance/airgapped.rb b/qa/qa/scenario/test/instance/airgapped.rb
index 556741ec040..1d4d57b342e 100644
--- a/qa/qa/scenario/test/instance/airgapped.rb
+++ b/qa/qa/scenario/test/instance/airgapped.rb
@@ -8,7 +8,7 @@ module QA
include Bootable
include SharedAttributes
def perform(address, *rspec_options)
- Runtime::Scenario.define(:runner_network, 'airgapped')
+ Runtime::Scenario.define(:network, 'airgapped')
super
end
diff --git a/qa/qa/scenario/test/instance/blocking.rb b/qa/qa/scenario/test/instance/blocking.rb
new file mode 100644
index 00000000000..26bd71e04e8
--- /dev/null
+++ b/qa/qa/scenario/test/instance/blocking.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Instance
+ class Blocking < All
+ tags :reliable,
+ *Specs::Runner::DEFAULT_SKIPPED_TAGS.map { |tag| :"~#{tag}" }
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/scenario/test/instance/non_blocking.rb b/qa/qa/scenario/test/instance/non_blocking.rb
new file mode 100644
index 00000000000..602fa60b646
--- /dev/null
+++ b/qa/qa/scenario/test/instance/non_blocking.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Instance
+ class NonBlocking < All
+ tags :"~reliable",
+ :"~smoke",
+ *Specs::Runner::DEFAULT_SKIPPED_TAGS.map { |tag| :"~#{tag}" }
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/scenario/test/integration/oauth.rb b/qa/qa/scenario/test/integration/oauth.rb
new file mode 100644
index 00000000000..912156fbc29
--- /dev/null
+++ b/qa/qa/scenario/test/integration/oauth.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Integration
+ class OAuth < Test::Instance::All
+ tags :oauth
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/service/docker_run/base.rb b/qa/qa/service/docker_run/base.rb
index 1a25aeb4c19..d6b50db7fa9 100644
--- a/qa/qa/service/docker_run/base.rb
+++ b/qa/qa/service/docker_run/base.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'socket'
+
module QA
module Service
module DockerRun
@@ -11,8 +13,7 @@ module QA
end
def initialize
- @network = Runtime::Scenario.attributes[:network] || 'test'
- @runner_network = Runtime::Scenario.attributes[:runner_network] || @network
+ @network = gdk_network || Runtime::Scenario.attributes[:network] || 'test'
end
# Authenticate against a container registry
@@ -42,10 +43,6 @@ module QA
network_exists?(@network) ? @network : 'bridge'
end
- def runner_network
- network_exists?(@runner_network) ? @runner_network : network
- end
-
def inspect_network(name)
shell("docker network inspect #{name}", fail_on_exception: false, return_exit_status: true)
end
@@ -90,6 +87,33 @@ module QA
def health
shell("docker inspect --format='{{json .State.Health.Status}}' #{@name}").delete('"')
end
+
+ # The network to use when testing against GDK in docker
+ #
+ # @return [String]
+ def gdk_network
+ return unless Runtime::Env.gdk_url
+
+ 'host'
+ end
+
+ # The IP address of the docker host when testing against GDK in docker
+ #
+ # @return [String]
+ def gdk_host_ip
+ return unless Runtime::Env.gdk_url
+
+ Addrinfo.tcp(URI(Runtime::Env.gdk_url).host, nil).ip_address
+ end
+
+ # Returns the IP address of the docker host
+ #
+ # @return [String]
+ def host_ip
+ docker_host = shell("docker context inspect --format='{{json .Endpoints.docker.Host}}'").delete('"')
+ ip = Addrinfo.tcp(URI(docker_host).host, nil).ip_address
+ ip == '0.0.0.0' ? '127.0.0.1' : ip
+ 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 078a3048cad..b0bb999e5d6 100644
--- a/qa/qa/service/docker_run/gitlab_runner.rb
+++ b/qa/qa/service/docker_run/gitlab_runner.rb
@@ -16,7 +16,7 @@ module QA
MSG
def initialize(name)
- @image = "#{QA::Runtime::Env.container_registry_host}/gitlab-org/gitlab-runner:alpine"
+ @image = "#{QA::Runtime::Env.container_registry_host}/gitlab-org/#{QA::Runtime::Env.runner_container_image}"
@name = name || "qa-runner-#{SecureRandom.hex(4)}"
@run_untagged = true
@executor = :shell
@@ -40,9 +40,10 @@ module QA
raise("Missing runner token value!") unless token
cmd = <<~CMD.tr("\n", ' ')
- docker run -d --rm --network #{runner_network} --name #{@name}
+ docker run -d --rm --network #{network} --name #{@name}
#{'-v /var/run/docker.sock:/var/run/docker.sock' if @executor == :docker}
--privileged
+ #{"--add-host gdk.test:#{gdk_host_ip}" if gdk_network}
#{@image} #{add_gitlab_tls_cert if @address.include? 'https'}
&& docker exec --detach #{@name} sh -c "#{register_command}"
CMD
@@ -51,7 +52,7 @@ module QA
wait_until_running_and_configured
# Prove airgappedness
- shell("docker exec #{@name} sh -c '#{prove_airgap}'") if runner_network == 'airgapped'
+ shell("docker exec #{@name} sh -c '#{prove_airgap}'") if network == 'airgapped'
end
def tags=(tags)
diff --git a/qa/qa/service/docker_run/ldap.rb b/qa/qa/service/docker_run/ldap.rb
index a6982bddf28..ea0f774b8d9 100644
--- a/qa/qa/service/docker_run/ldap.rb
+++ b/qa/qa/service/docker_run/ldap.rb
@@ -28,7 +28,7 @@ module QA
if volume_exists?(volume_name)
volume_name
else
- ::File.join(Runtime::Path.fixtures_path, 'ldap', volume_name)
+ Runtime::Path.fixture('ldap', volume_name)
end
end
diff --git a/qa/qa/service/docker_run/smocker.rb b/qa/qa/service/docker_run/smocker.rb
index b48f8aa84e3..59f32e29b44 100644
--- a/qa/qa/service/docker_run/smocker.rb
+++ b/qa/qa/service/docker_run/smocker.rb
@@ -38,10 +38,14 @@ module QA
@api = nil
end
+ def self.logs
+ @container&.logs
+ end
+
attr_reader :public_port, :admin_port
def host_name
- return '127.0.0.1' unless QA::Runtime::Env.running_in_ci? || QA::Runtime::Env.qa_hostname
+ return host_ip unless QA::Runtime::Env.running_in_ci? || QA::Runtime::Env.qa_hostname
"#{@name}.#{@network_cache}"
end
diff --git a/qa/qa/service/docker_run/video.rb b/qa/qa/service/docker_run/video.rb
index c75280b1282..601e342b6ba 100644
--- a/qa/qa/service/docker_run/video.rb
+++ b/qa/qa/service/docker_run/video.rb
@@ -29,6 +29,7 @@ module QA
if @recorder_container_name.present? && @browser_container_hostname
configure_rspec
+ configure_rspec_allure if QA::Runtime::Env.generate_allure_report?
QA::Runtime::Logger.info("Test failure video recording setup complete!")
else
@@ -69,17 +70,60 @@ module QA
QA::Runtime::Logger.warn("Video deletion error: #{e}")
end
+ def record?(example)
+ example.metadata[:file_path].include?("/browser_ui/")
+ end
+
+ def save?(example)
+ example.exception || QA::Runtime::Env.save_all_videos?
+ end
+
+ def retrieve_video(example)
+ return unless record?(example) && example.exception
+
+ # We need to wait until the video is finished processing by checking the size
+ QA::Support::Waiter.wait_until(max_duration: 30, sleep_interval: 1) do
+ size =
+ shell("docker exec #{@recorder_container_name} sh -c 'stat -c %s /data/#{@current_recording_name}.mp4'")
+ size.to_i > 1024
+ end
+
+ shell("docker cp #{@recorder_container_name}:/data/#{@current_recording_name}.mp4 tmp/")
+
+ "#{shell('pwd')}/tmp/#{@current_recording_name}.mp4"
+ rescue StandardError => e
+ QA::Runtime::Logger.warn("Video retrieval error: #{e}")
+ end
+
private
def configure_rspec
RSpec.configure do |config|
config.prepend_before do |example|
- QA::Service::DockerRun::Video.start_recording(example)
+ QA::Service::DockerRun::Video.start_recording(example) if QA::Service::DockerRun::Video.record?(example)
+ end
+
+ config.prepend_after do |example|
+ if QA::Service::DockerRun::Video.record?(example)
+ QA::Service::DockerRun::Video.stop_recording
+ QA::Service::DockerRun::Video.delete_video unless QA::Service::DockerRun::Video.save?(example)
+ end
end
+ end
+ end
+ def configure_rspec_allure
+ RSpec.configure do |config|
config.append_after do |example|
- QA::Service::DockerRun::Video.stop_recording
- QA::Service::DockerRun::Video.delete_video unless example.exception
+ video_path = QA::Service::DockerRun::Video.retrieve_video(example)
+ if video_path
+ Allure.add_attachment(
+ name: 'video',
+ source: File.open(video_path),
+ type: 'video/mp4',
+ test_case: true
+ )
+ end
end
end
end
diff --git a/qa/qa/service/praefect_manager.rb b/qa/qa/service/praefect_manager.rb
index 684b18a97a7..56627e51b76 100644
--- a/qa/qa/service/praefect_manager.rb
+++ b/qa/qa/service/praefect_manager.rb
@@ -198,56 +198,6 @@ module QA
destination_storage[:type] == :praefect ? verify_storage_move_to_praefect(repo_path, destination_storage[:name]) : verify_storage_move_to_gitaly(repo_path, destination_storage[:name])
end
- def praefect_dataloss_information(project_id)
- dataloss_info = []
- cmd = "docker exec #{@praefect} praefect -config /var/opt/gitlab/praefect/config.toml dataloss --partially-unavailable=true"
- shell(cmd) { |line| dataloss_info << line.strip }
-
- # Expected will have a record for each repository in the storage, in the following format
- # @hashed/bc/52/bc52dd634277c4a34a2d6210994a9a5e2ab6d33bb4a3a8963410e00ca6c15a02.git:
- # Primary: gitaly1
- # In-Sync Storages:
- # gitaly1, assigned host
- # gitaly3, assigned host
- # Outdated Storages:
- # gitaly2 is behind by 1 change or less, assigned host
- #
- # Alternatively, if all repositories are in sync, a concise message is returned
- # Virtual storage: default
- # All repositories are fully available on all assigned storages!
-
- # extract the relevant project under test info if it is identified
- start_index = dataloss_info.index { |line| line.include?("#{Digest::SHA256.hexdigest(project_id.to_s)}.git") }
- unless start_index.nil?
- dataloss_info = dataloss_info[start_index, 7]
- end
-
- dataloss_info&.each { |info| QA::Runtime::Logger.debug(info) }
- dataloss_info
- end
-
- def wait_for_project_synced_across_all_storages(project_id)
- Support::Retrier.retry_until(max_duration: 60) do
- praefect_dataloss_information(project_id).include?('All repositories are fully available on all assigned storages!')
- end
- end
-
- def accept_dataloss_for_project(project_id, authoritative_storage)
- repository_hash = "#{Digest::SHA256.hexdigest(project_id.to_s)}"
- repository = "@hashed/#{repository_hash[0, 2]}/#{repository_hash[2, 2]}/#{repository_hash}.git"
-
- cmd = %{
- docker exec #{@praefect} \
- praefect \
- -config /var/opt/gitlab/praefect/config.toml \
- accept-dataloss \
- --virtual-storage=default \
- --repository=#{repository} \
- --authoritative-storage=#{authoritative_storage}
- }
- shell(cmd)
- end
-
def wait_for_health_check_all_nodes
gitaly_nodes.each { |node| wait_for_gitaly_health_check(node) }
end
@@ -310,27 +260,6 @@ module QA
Support::Waiter.wait_until(sleep_interval: 1) { replication_queue_incomplete_count == 0 && replicated?(project_id) }
end
- def wait_for_replication_to_node(project_id, node)
- Support::Waiter.wait_until(sleep_interval: 1) do
- result = []
- shell sql_to_docker_exec_cmd(%{
- select * from replication_queue
- where state = 'ready'
- and job ->> 'change' = 'update'
- and job ->> 'target_node_storage' = '#{node}'
- and job ->> 'relative_path' = '#{Digest::SHA256.hexdigest(project_id.to_s)}.git';
- }) do |line|
- result << line.strip
- QA::Runtime::Logger.debug(line.strip)
- end
- # The result should look like this when all items are replicated
- # id | state | created_at | updated_at | attempt | lock_id | job | meta
- # ----+-------+------------+------------+---------+---------+-----+------
- # (0 rows)
- result[2] == '(0 rows)'
- end
- end
-
def replication_pending?
result = []
shell sql_to_docker_exec_cmd(
@@ -357,58 +286,6 @@ module QA
result.size >= 5
end
- def list_untracked_repositories
- untracked_repositories = []
- shell "docker exec #{@praefect} bash -c 'gitlab-ctl praefect list-untracked-repositories'" do |line|
- # Results look like this
- # The following repositories were found on disk, but missing from the tracking database:
- # {"relative_path":"@hashed/aa/bb.git","storage":"gitaly1","virtual_storage":"default"}
- # {"relative_path":"@hashed/bb/cc.git","storage":"gitaly3","virtual_storage":"default"}
-
- QA::Runtime::Logger.debug(line.chomp)
- untracked_repositories.append(JSON.parse(line))
- rescue JSON::ParserError
- # Ignore lines that can't be parsed as JSON
- end
-
- QA::Runtime::Logger.debug("list_untracked_repositories --- #{untracked_repositories}")
- untracked_repositories
- end
-
- def track_repository_in_praefect(relative_path, storage, virtual_storage)
- cmd = "gitlab-ctl praefect track-repository --repository-relative-path #{relative_path} --authoritative-storage #{storage} --virtual-storage-name #{virtual_storage}"
- shell "docker exec #{@praefect} bash -c '#{cmd}'"
- end
-
- def remove_tracked_praefect_repository(relative_path, virtual_storage)
- cmd = "gitlab-ctl praefect remove-repository --repository-relative-path #{relative_path} --virtual-storage-name #{virtual_storage} --apply"
- shell "docker exec #{@praefect} bash -c '#{cmd}'"
- end
-
- # set_replication_factor assigns or unassigns random storage nodes as necessary to reach the desired replication factor for a repository
- def set_replication_factor(relative_path, virtual_storage, factor)
- cmd = "/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -repository #{relative_path} -virtual-storage #{virtual_storage} -replication-factor #{factor}"
- shell "docker exec #{@praefect} bash -c '#{cmd}'"
- end
-
- # get_replication_storages retrieves a list of currently assigned storages for a repository
- def get_replication_storages(relative_path, virtual_storage)
- storage_repositories = []
- query = "SELECT storage FROM repository_assignments WHERE relative_path='#{relative_path}' AND virtual_storage='#{virtual_storage}';"
- shell(sql_to_docker_exec_cmd(query)) { |line| storage_repositories << line.strip }
- # Returned data from query will be in format
- # storage
- # --------
- # gitaly1
- # gitaly3
- # gitaly2
- # (3 rows)
- #
-
- # remove 2 header rows and last 2 rows from query response (including blank line)
- storage_repositories[2..-3]
- end
-
def modify_repo_access_time(node, repo_path, update_time)
repo = "/var/opt/gitlab/git-data/repositories/#{repo_path}"
shell(%{
@@ -416,65 +293,6 @@ module QA
})
end
- def add_repo_to_disk(node, repo_path)
- cmd = "GIT_DIR=. git init --initial-branch=main /var/opt/gitlab/git-data/repositories/#{repo_path}"
- shell "docker exec --user git #{node} bash -c '#{cmd}'"
- modify_repo_access_time(node, repo_path, "24 hours ago")
- end
-
- def remove_repo_from_disk(repo_path)
- cmd = "rm -rf /var/opt/gitlab/git-data/repositories/#{repo_path}"
- shell "docker exec #{@primary_node} bash -c '#{cmd}'"
- shell "docker exec #{@secondary_node} bash -c '#{cmd}'"
- shell "docker exec #{@tertiary_node} bash -c '#{cmd}'"
- end
-
- def remove_repository_from_praefect_database(relative_path)
- shell sql_to_docker_exec_cmd("delete from repositories where relative_path = '#{relative_path}';")
- shell sql_to_docker_exec_cmd("delete from storage_repositories where relative_path = '#{relative_path}';")
- end
-
- def praefect_database_tracks_repo?(relative_path)
- storage_repositories = []
- shell sql_to_docker_exec_cmd("SELECT count(*) FROM storage_repositories where relative_path='#{relative_path}';") do |line|
- storage_repositories << line
- end
- QA::Runtime::Logger.debug("storage_repositories count is ---#{storage_repositories}")
-
- repositories = []
- shell sql_to_docker_exec_cmd("SELECT count(*) FROM repositories where relative_path='#{relative_path}';") do |line|
- repositories << line
- end
- QA::Runtime::Logger.debug("repositories count is ---#{repositories}")
-
- (storage_repositories[2].to_i >= 1) && (repositories[2].to_i >= 1)
- end
-
- def repository_replicated_to_disk?(node, relative_path)
- Support::Waiter.wait_until(max_duration: 300, sleep_interval: 1, raise_on_failure: false) do
- result = []
- shell sql_to_docker_exec_cmd("SELECT count(*) FROM storage_repositories where relative_path='#{relative_path}';") do |line|
- result << line
- end
- QA::Runtime::Logger.debug("result is ---#{result}")
- result[2].to_i == 3
- end
-
- repository_exists_on_node_disk?(node, relative_path)
- end
-
- def repository_exists_on_node_disk?(node, relative_path)
- # If the dir does not exist it has a non zero exit code leading to a error being raised
- # Instead we echo a test line if the dir does not exist, which has a zero exit code, with no output
- bash_command = "test -d /var/opt/gitlab/git-data/repositories/#{relative_path} || echo -n 'DIR_DOES_NOT_EXIST'"
- result = []
- shell "docker exec #{node} bash -c '#{bash_command}'" do |line|
- result << line
- end
- QA::Runtime::Logger.debug("result is ---#{result}")
- result.exclude?("DIR_DOES_NOT_EXIST")
- end
-
private
def dataloss_command
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb
deleted file mode 100644
index 7b9164c1fc9..00000000000
--- a/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Systems' do
- describe 'Praefect dataloss commands', :orchestrated, :gitaly_cluster, product_group: :gitaly do
- let(:praefect_manager) { Service::PraefectManager.new }
-
- let(:project) do
- Resource::Project.fabricate! do |project|
- project.name = 'gitaly_cluster-dataloss-project'
- project.initialize_with_readme = true
- end
- end
-
- before do
- praefect_manager.start_all_nodes
- end
-
- it 'confirms that changes are synced across all storages',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352691' do
- expect { praefect_manager.praefect_dataloss_information(project.id) }
- .to(eventually_include('All repositories are fully available on all assigned storages!')
- .within(max_duration: 60))
- end
-
- it 'identifies how many changes are not in sync across storages',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352692' do
- # Ensure our test repository is replicated and in a consistent state prior to test
- praefect_manager.wait_for_project_synced_across_all_storages(project.id)
-
- # testing for gitaly2 'out of sync'
- praefect_manager.stop_node(praefect_manager.secondary_node)
-
- number_of_changes = 3
- 1.upto(number_of_changes) do |i|
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.branch = "newbranch-#{SecureRandom.hex(8)}"
- commit.start_branch = project.default_branch
- commit.commit_message = 'Add new file'
- commit.add_files(
- [{
- file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'new file'
- }]
- )
- end
- end
-
- # testing for gitaly3 'in sync' but marked unhealthy
- praefect_manager.stop_node(praefect_manager.tertiary_node)
-
- project_data_loss = praefect_manager.praefect_dataloss_information(project.id)
- aggregate_failures "validate dataloss identified" do
- expect(project_data_loss).to include('gitaly1, assigned host')
- expect(project_data_loss)
- .to include("gitaly2 is behind by #{number_of_changes} changes or less, assigned host, unhealthy")
- expect(project_data_loss).to include('gitaly3, assigned host, unhealthy')
- end
- end
-
- it 'allows admin resolve scenario where data cannot be recovered',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352708' do
- # Ensure everything is in sync before begining test
- praefect_manager.wait_for_project_synced_across_all_storages(project.id)
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'accept-dataloss-1'
- commit.add_files(
- [{
- file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly1,gitaly2,gitaly3'
- }]
- )
- end
-
- praefect_manager.wait_for_replication_to_node(project.id, praefect_manager.primary_node)
- praefect_manager.stop_node(praefect_manager.primary_node)
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'accept-dataloss-2'
- commit.add_files(
- [{
- file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly2,gitaly3'
- }]
- )
- end
-
- praefect_manager.wait_for_replication_to_node(project.id, praefect_manager.secondary_node)
- praefect_manager.stop_node(praefect_manager.secondary_node)
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'accept-dataloss-3'
- commit.add_files([
- { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly3' }
- ])
- end
-
- # Confirms that they want to accept dataloss, using gitaly2 as authoritative storage to use as a base
- praefect_manager.accept_dataloss_for_project(project.id, praefect_manager.secondary_node)
-
- # Restart nodes, and allow replication to apply dataloss changes
- praefect_manager.start_all_nodes
- praefect_manager.wait_for_project_synced_across_all_storages(project.id)
-
- # Validate that gitaly2 was accepted as the authorative storage
- aggregate_failures "validate correct set of commits available" do
- expect(project.commits.map { |commit| commit[:message].chomp }).to include('accept-dataloss-1')
- expect(project.commits.map { |commit| commit[:message].chomp }).to include('accept-dataloss-2')
- expect(project.commits.map { |commit| commit[:message].chomp }).not_to include('accept-dataloss-3')
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb
deleted file mode 100644
index 4f916300ee3..00000000000
--- a/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Systems' do
- describe 'Praefect repository commands', :orchestrated, :gitaly_cluster, product_group: :gitaly do
- let(:praefect_manager) { Service::PraefectManager.new }
-
- let(:repo1) do
- { "relative_path" => "@hashed/repo1.git", "storage" => "gitaly1", "virtual_storage" => "default" }
- end
-
- let(:repo2) do
- { "relative_path" => "@hashed/path/to/repo2.git", "storage" => "gitaly3", "virtual_storage" => "default" }
- end
-
- before do
- praefect_manager.start_all_nodes
- praefect_manager.add_repo_to_disk(praefect_manager.primary_node, repo1["relative_path"])
- praefect_manager.add_repo_to_disk(praefect_manager.tertiary_node, repo2["relative_path"])
- end
-
- after do
- praefect_manager.remove_repo_from_disk(repo1["relative_path"])
- praefect_manager.remove_repo_from_disk(repo2["relative_path"])
- praefect_manager.remove_repository_from_praefect_database(repo1["relative_path"])
- praefect_manager.remove_repository_from_praefect_database(repo2["relative_path"])
- end
-
- it 'allows admin to manage difference between praefect database and disk state',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347606' do
- # Some repos are on disk that praefect is not aware of
- untracked_repositories = praefect_manager.list_untracked_repositories
- expect(untracked_repositories).to include(repo1)
- expect(untracked_repositories).to include(repo2)
-
- # admin manually adds the first repo to the praefect database
- praefect_manager
- .track_repository_in_praefect(repo1["relative_path"], repo1["storage"], repo1["virtual_storage"])
- untracked_repositories = praefect_manager.list_untracked_repositories
- expect(untracked_repositories).not_to include(repo1)
- expect(untracked_repositories).to include(repo2)
- expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.primary_node, repo1["relative_path"]))
- .to be true
- expect(praefect_manager.praefect_database_tracks_repo?(repo1["relative_path"])).to be true
-
- # admin manually adds the second repo to the praefect database
- praefect_manager
- .track_repository_in_praefect(repo2["relative_path"], repo2["storage"], repo2["virtual_storage"])
- untracked_repositories = praefect_manager.list_untracked_repositories
- expect(untracked_repositories).not_to include(repo2)
- expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.tertiary_node, repo2["relative_path"]))
- .to be true
- expect(praefect_manager.praefect_database_tracks_repo?(repo2["relative_path"])).to be true
-
- # admin ensures replication to other nodes occurs
- expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.secondary_node, repo1["relative_path"]))
- .to be true
- expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.tertiary_node, repo1["relative_path"]))
- .to be true
- expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.primary_node, repo2["relative_path"]))
- .to be true
- expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.secondary_node, repo2["relative_path"]))
- .to be true
-
- # admin chooses to remove the first repo completely from praefect and disk
- praefect_manager.remove_tracked_praefect_repository(repo1["relative_path"], repo1["virtual_storage"])
- expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.primary_node, repo1["relative_path"]))
- .to be false
- expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager
- .secondary_node, repo1["relative_path"])).to be false
- expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.tertiary_node, repo1["relative_path"]))
- .to be false
- expect(praefect_manager.praefect_database_tracks_repo?(repo1["relative_path"])).to be false
-
- untracked_repositories = praefect_manager.list_untracked_repositories
- expect(untracked_repositories).not_to include(repo1)
- end
-
- it 'allows admin to control the number of replicas of data',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347566' do
- praefect_manager
- .track_repository_in_praefect(repo1['relative_path'], repo1['storage'], repo1['virtual_storage'])
-
- praefect_manager.set_replication_factor(repo1['relative_path'], repo1['virtual_storage'], 2)
- replication_storages = praefect_manager
- .get_replication_storages(repo1['relative_path'], repo1['virtual_storage'])
- expect(replication_storages).to have_attributes(size: 2)
-
- praefect_manager.set_replication_factor(repo1['relative_path'], repo1['virtual_storage'], 3)
- replication_storages = praefect_manager
- .get_replication_storages(repo1['relative_path'], repo1['virtual_storage'])
- expect(replication_storages).to eq(%w[gitaly1 gitaly2 gitaly3])
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb
index b81cb70eb18..e9a9f838436 100644
--- a/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb
@@ -196,6 +196,7 @@ module QA
project.add_name_uuid = false
project.name = 'imported-project'
project.github_personal_access_token = Runtime::Env.github_access_token
+ project.additional_access_tokens = Runtime::Env.github_additional_access_tokens
project.github_repository_path = github_repo
project.personal_namespace = user.username
project.api_client = Runtime::API::Client.new(user: user)
@@ -204,6 +205,10 @@ module QA
end
end
+ before do
+ QA::Support::Helpers::ImportSource.enable('github')
+ end
+
after do |example|
next unless defined?(@import_time)
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
index ac8399b391d..99f8fb5107e 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
@@ -65,6 +65,10 @@ module QA
let(:mrs) { fetch_mrs(imported_project, api_client) }
let(:issues) { fetch_issues(imported_project, api_client) }
+ before do
+ QA::Support::Helpers::ImportSource.enable(%w[gitlab_project])
+ end
+
# rubocop:disable RSpec/InstanceVariable
after do |example|
next unless defined?(@import_time)
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
index 7d785630a57..307d0493b2a 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb
@@ -70,7 +70,11 @@ module QA
context 'with merge request' do
it(
'successfully imports merge request',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348478'
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348478',
+ quarantine: {
+ type: :bug,
+ issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/414859"
+ }
) do
expect_project_import_finished_successfully
expect(imported_mrs.count).to eq(1)
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 0c94d6e64d5..7cbccf9be44 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
@@ -24,7 +24,7 @@ module QA
group.api_client = admin_api_client
group.sandbox = source_sandbox
group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
- group.avatar = File.new(File.join(Runtime::Path.fixtures_path, 'designs', 'tanuki.jpg'), 'r')
+ group.avatar = File.new(Runtime::Path.fixture('designs', 'tanuki.jpg'), 'r')
end
end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
index 2443887c3d4..fcf15b66c11 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_release_spec.rb
@@ -34,10 +34,10 @@ module QA
commit_path: release[:commit_path].split("/-/").last,
tag_path: release[:tag_path].split("/-/").last,
assets: release[:assets].merge({
- sources: release.dig(:assets, :sources).map do |source|
- source.merge({ url: source[:url].split("/-/").last })
- end
- }),
+ sources: release.dig(:assets, :sources).map do |source|
+ source.merge({ url: source[:url].split("/-/").last })
+ end
+ }),
milestones: release[:milestones].map do |milestone|
milestone.except(:id, :project_id).merge({ web_url: milestone[:web_url].split("/-/").last })
end,
diff --git a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
index 86fc154c1cf..d3b702a658c 100644
--- a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :requires_admin, :skip_live_env, except: { job: 'review-qa-*' } do
+ RSpec.describe 'Manage', :requires_admin, :skip_live_env, except: { job: %w[review-qa-* gdk-qa-*] } do
describe 'rate limits', :reliable, product_group: :import_and_integrate do
let(:rate_limited_user) { Resource::User.fabricate_via_api! }
let(:api_client) { Runtime::API::Client.new(:gitlab, user: rate_limited_user) }
diff --git a/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb
new file mode 100644
index 00000000000..f69a8a4dfa5
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/repository/add_list_delete_branches_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'project-qa-test'
+ project.description = 'project for qa test'
+ end
+ end
+
+ describe 'Create, Retrieve and Delete branches via API', :requires_admin, product_group: :source_code do
+ created_branch = 'create-branch'
+ deleted_branch = 'delete-branch'
+ filename = 'file.txt'
+ default_branch_commit_message = "Add #{filename}"
+
+ before do
+ Git::Repository.perform do |repository|
+ repository.uri = project.repository_http_location.uri
+ repository.use_default_credentials
+ repository.try_add_credentials_to_netrc
+
+ repository.act do
+ init_repository
+ configure_identity('GitLab QA', 'root@gitlab.com')
+
+ commit_file(filename, 'Test file content', default_branch_commit_message)
+ push_changes
+
+ checkout(deleted_branch, new_branch: true)
+ push_changes(deleted_branch)
+ end
+ end
+ project.wait_for_push default_branch_commit_message
+ end
+
+ it(
+ 'creates, retrieves and deletes branches',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347740'
+ ) do
+ # Create branch
+ Resource::Repository::Branch.fabricate_via_api! do |branch|
+ branch.name = created_branch
+ branch.project = project
+ end
+
+ # Retrieve branch
+ delete_branch = Resource::Repository::Branch.fabricate_via_api! do |branch|
+ branch.name = deleted_branch
+ branch.project = project
+ end
+
+ # Delete branch
+ delete_branch.remove_via_api!
+
+ # Clone repository, verify branches and commits
+ Git::Repository.perform do |repository|
+ repository.uri = project.repository_http_location.uri
+ repository.use_default_credentials
+ repository.try_add_credentials_to_netrc
+
+ repository.clone
+
+ branches = repository.remote_branches
+ expect(branches).to include(created_branch)
+ expect(branches).not_to include(deleted_branch)
+
+ expect(repository.commits.first).to include(default_branch_commit_message)
+
+ repository.checkout(created_branch)
+ expect(repository.commits.first).to include(default_branch_commit_message)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb b/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
index d5073863dff..23d8585d07a 100644
--- a/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
+++ b/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
@@ -19,17 +19,17 @@ module QA
end
end
- let!(:project_access_token) do
- QA::Resource::ProjectAccessToken.fabricate_via_api! do |pat|
- pat.project = project
+ let!(:runner) do
+ Resource::ProjectRunner.fabricate! do |runner|
+ runner.project = project
+ runner.name = "runner-for-#{project.name}"
+ runner.tags = ["runner-for-#{project.name}"]
end
end
- let(:registry) do
- Resource::RegistryRepository.init do |repository|
- repository.name = project.path_with_namespace
- repository.project = project
- repository.tag_name = 'master'
+ let!(:project_access_token) do
+ QA::Resource::ProjectAccessToken.fabricate_via_api! do |pat|
+ pat.project = project
end
end
@@ -61,6 +61,8 @@ module QA
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
- docker pull $IMAGE_TAG
+ tags:
+ - "runner-for-#{project.name}"
test:
image: dwdraju/alpine-curl-jq:latest
@@ -74,9 +76,15 @@ module QA
- if [ $status_code -ne 200 ]; then exit 1; fi;
- 'status_code=$(curl --head --output /dev/null --write-out "%{http_code}\n" --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories/$id/tags/master")'
- if [ $status_code -ne 404 ]; then exit 1; fi;
+ tags:
+ - "runner-for-#{project.name}"
YAML
end
+ after do
+ runner.remove_via_api!
+ end
+
it 'pushes, pulls image to the registry and deletes tag',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348001' do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2, message: "Commit push") do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
index 54fb2aca990..84664cb8b94 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
@@ -46,7 +46,7 @@ module QA
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931',
quarantine: {
type: :bug,
- only: { condition: -> { QA::Runtime::Env.super_sidebar_enabled? } },
+ only: { condition: -> { !QA::Runtime::Env.super_sidebar_enabled? } },
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/409336'
}
) do
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_facebook_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_facebook_spec.rb
new file mode 100644
index 00000000000..ee4c3b167db
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/oauth_login_with_facebook_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 'logs in with Facebook credentials',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/417115' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+
+ Page::Main::Login.perform(&:sign_in_with_facebook)
+
+ Vendor::Facebook::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/design_management/add_design_content_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/design_management/add_design_content_spec.rb
index 130006fe424..63d30da9ec3 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/design_management/add_design_content_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/design_management/add_design_content_spec.rb
@@ -5,7 +5,7 @@ module QA
describe 'Design Management' do
let(:issue) { Resource::Issue.fabricate_via_api! }
let(:design_filename) { 'banana_sample.gif' }
- let(:design) { File.join(Runtime::Path.fixtures_path, 'designs', design_filename) }
+ let(:design) { Runtime::Path.fixture('designs', design_filename) }
let(:annotation) { "This design is great!" }
before do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
index 4e9d74a5117..1a53fda4cdb 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
@@ -38,7 +38,7 @@ module QA
def mailhog_json
Support::Retrier.retry_until(sleep_interval: 1) do
- Runtime::Logger.debug(%Q[retrieving "#{QA::Runtime::MailHog.api_messages_url}"])
+ Runtime::Logger.debug(%[retrieving "#{QA::Runtime::MailHog.api_messages_url}"])
mailhog_response = get QA::Runtime::MailHog.api_messages_url
@@ -47,8 +47,8 @@ module QA
subjects = mailhog_data.dig('items')
.map { |item| mailhog_item_subject(item) }
- Runtime::Logger.debug(%Q[Total number of emails: #{total}])
- Runtime::Logger.debug(%Q[Subjects:\n#{subjects.join("\n")}])
+ Runtime::Logger.debug(%[Total number of emails: #{total}])
+ Runtime::Logger.debug(%[Subjects:\n#{subjects.join("\n")}])
# Expect at least two invitation messages: group and project
mailhog_data if mailhog_project_message_count(subjects) >= 1
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 821f885c4c8..33cd3879298 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
@@ -59,9 +59,7 @@ module QA
context 'when using attachments in comments', :object_storage do
let(:png_file_name) { 'testfile.png' }
- let(:file_to_attach) do
- File.join(Runtime::Path.fixtures_path, 'designs', png_file_name)
- end
+ let(:file_to_attach) { Runtime::Path.fixture('designs', png_file_name) }
before do
Resource::Issue.fabricate_via_api_unless_fips! { |issue| issue.project = project }.visit!
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
index 5febb6579df..ce6e9c6a1fb 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/create_group_milestone_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :reliable, product_group: :project_management do
+ RSpec.describe 'Plan', :reliable, :db_migrate, product_group: :project_management do
describe 'Group milestone' do
include Support::Dates
diff --git a/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb
index 7368ca34683..919b4b2c46e 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/pages/new_static_page_spec.rb
@@ -30,9 +30,6 @@ module QA
end
before do
- # Pages Menu Experiment currently progress https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98044
- # Update spec along with Feature Flag Removal.
- Runtime::Feature.disable(:show_pages_in_deployments_menu)
Flow::Login.sign_in
Resource::ProjectRunner.fabricate_via_api! do |runner|
runner.project = project
@@ -41,10 +38,6 @@ module QA
pipeline.visit!
end
- after do
- Runtime::Feature.enable(:show_pages_in_deployments_menu)
- end
-
it 'creates a Pages website',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347669' do
Page::Project::Pipeline::Show.perform do |show|
@@ -57,7 +50,7 @@ module QA
end
Page::Project::Menu.perform(&:go_to_pages_settings)
- Page::Project::Settings::Pages.perform(&:go_to_access_page)
+ Page::Project::Deployments::Pages.perform(&:go_to_access_page)
Support::Waiter.wait_until(
sleep_interval: 2,
diff --git a/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_file_upload_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_file_upload_spec.rb
index a044bfa2054..bb411efc029 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_file_upload_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/project_wiki/project_based_file_upload_spec.rb
@@ -31,7 +31,7 @@ module QA
edit.set_title(page_title)
edit.use_new_editor
edit.add_heading('Heading 1', heading_text)
- edit.upload_image(File.join(Runtime::Path.fixtures_path, 'designs', image_file_name))
+ edit.upload_image(Runtime::Path.fixture('designs', image_file_name))
end
Page::Project::Wiki::Edit.perform(&:click_submit)
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
index 1e08fc49066..fcce6bb291c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
@@ -46,7 +46,7 @@ module QA
label = Resource::ProjectLabel.fabricate_via_api! do |label|
label.project = project
- label.title = 'label'
+ label.title = 'foo::label'
end
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
index 7b89b021d89..297f91be0bb 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/batch_suggestion_spec.rb
@@ -15,7 +15,7 @@ module QA
merge_request.title = 'Needs some suggestions'
merge_request.description = '... so please add them.'
merge_request.file_content = File.read(
- File.join(Runtime::Path.fixtures_path, 'metrics_dashboards', 'templating.yml')
+ Runtime::Path.fixture('metrics_dashboards', 'templating.yml')
)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
index 499d4c00384..ce32f4aadca 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/suggestions/custom_commit_suggestion_spec.rb
@@ -17,7 +17,7 @@ module QA
merge_request.title = 'Needs some suggestions'
merge_request.description = '... so please add them.'
merge_request.file_content = File.read(
- File.join(Runtime::Path.fixtures_path, 'metrics_dashboards', 'templating.yml')
+ Runtime::Path.fixture('metrics_dashboards', 'templating.yml')
)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
deleted file mode 100644
index 631b4ae099d..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create' do
- describe 'Create, list, and delete branches via web', :requires_admin, product_group: :source_code do
- master_branch = nil
- second_branch = 'second-branch'
- third_branch = 'third-branch'
- file_1_master = 'file.txt'
- file_2_master = 'other-file.txt'
- file_second_branch = 'file-2.txt'
- file_third_branch = 'file-3.txt'
- first_commit_message_of_master_branch = "Add #{file_1_master}"
- second_commit_message_of_master_branch = "Add #{file_2_master}"
- commit_message_of_second_branch = "Add #{file_second_branch}"
- commit_message_of_third_branch = "Add #{file_third_branch}"
-
- before do
- Flow::Login.sign_in
-
- project = Resource::Project.fabricate_via_api! do |proj|
- proj.name = 'project-qa-test'
- proj.description = 'project for qa test'
- proj.initialize_with_readme = true
- end
-
- master_branch = project.default_branch
-
- Git::Repository.perform do |repository|
- repository.uri = project.repository_http_location.uri
- repository.use_default_credentials
- repository.try_add_credentials_to_netrc
- repository.default_branch = master_branch
-
- repository.act do
- clone
- configure_identity('GitLab QA', 'root@gitlab.com')
- commit_file(file_1_master, 'Test file content', first_commit_message_of_master_branch)
- push_changes
- checkout(second_branch, new_branch: true)
- commit_file(file_second_branch, 'File 2 content', commit_message_of_second_branch)
- push_changes(second_branch)
- checkout(master_branch)
- # This second commit on master is needed for the master branch to be ahead
- # of the second branch, and when the second branch is merged to master it will
- # show the 'merged' badge on it.
- # Refer to the below issue note:
- # https://gitlab.com/gitlab-org/gitlab-foss/issues/55524#note_126100848
- commit_file(file_2_master, 'Other test file content', second_commit_message_of_master_branch)
- push_changes
- merge(second_branch)
- push_changes
- checkout(third_branch, new_branch: true)
- commit_file(file_third_branch, 'File 3 content', commit_message_of_third_branch)
- push_changes(third_branch)
- end
- end
- project.wait_for_push commit_message_of_third_branch
- project.visit!
- end
-
- it(
- 'lists branches correctly after CRUD operations',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347740',
- quarantine: {
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/414026',
- type: :stale
- }
- ) do
- Page::Project::Menu.perform(&:go_to_repository_branches)
-
- expect(page).to have_content(master_branch)
- expect(page).to have_content(second_branch)
- expect(page).to have_content(third_branch)
- expect(page).to have_content("Merge branch 'second-branch'")
- expect(page).to have_content(commit_message_of_second_branch)
- expect(page).to have_content(commit_message_of_third_branch)
-
- Page::Project::Branches::Show.perform do |branches_page|
- expect(branches_page).to have_branch_with_badge(second_branch, 'merged')
-
- branches_page.delete_branch(third_branch)
-
- expect(branches_page).to have_no_branch(third_branch)
-
- branches_page.delete_merged_branches('delete')
-
- expect(branches_page).to have_content(
- 'Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes.'
- )
-
- branches_page.refresh
-
- expect(branches_page).to have_no_branch(second_branch, reload: true)
- end
- end
- 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
index 82074919ad4..1d9dccbddf6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_new_branch_rule_spec.rb
@@ -2,11 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Branch Rules Overview', product_group: :source_code,
- quarantine: {
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/403583',
- type: :flaky
- } do
+ describe 'Branch Rules Overview', product_group: :source_code 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 }
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
index 86a9f2c46fb..f00ef65fab4 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/license_detection_spec.rb
@@ -11,7 +11,7 @@ module QA
shared_examples 'project license detection' do
it 'displays the name of the license on the repository' do
- license_path = File.join(Runtime::Path.fixtures_path, 'software_licenses', license_file_name)
+ license_path = Runtime::Path.fixture('software_licenses', license_file_name)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.add_files([{ file_path: 'LICENSE', content: File.read(license_path) }])
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
index 99be95492e6..05925505610 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/server_hooks_custom_error_message_spec.rb
@@ -8,7 +8,7 @@ module QA
end
describe 'Git Server Hooks' do
- let(:file_path) { File.join(Runtime::Path.fixtures_path, 'web_ide', 'README.md') }
+ let(:file_path) { Runtime::Path.fixture('web_ide', 'README.md') }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
index f15f5b3a1d9..c557f2fa8a6 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide_old/upload_new_file_in_web_ide_spec.rb
@@ -8,8 +8,7 @@ module QA
end
describe 'Upload a file in Web IDE' do
- let(:file_path) { File.join(Runtime::Path.fixtures_path, 'web_ide', file_name) }
-
+ let(:file_path) { Runtime::Path.fixture('web_ide', file_name) }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'upload-file-project'
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 f1a433984d8..41ce868f0d6 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
@@ -24,6 +24,10 @@ module QA
project.visit!
end
+ after do
+ runner.remove_via_api!
+ end
+
context 'when latest pipeline is successful' do
before do
add_ci_file(job_name: 'job_1', script: 'echo test')
@@ -127,32 +131,41 @@ module QA
def add_ci_file(job_name:, script:)
ci_file = ci_file_with_job_artifact(job_name, script)
+ original_pipeline_count = pipeline_count
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = "Set job #{job_name} script #{script}"
commit.add_files([ci_file])
end
+
+ wait_for_new_pipeline(original_pipeline_count)
end
def update_ci_file(job_name:, script:)
ci_file = ci_file_with_job_artifact(job_name, script)
+ original_pipeline_count = pipeline_count
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = "Set job #{job_name} script #{script}"
commit.update_files([ci_file])
end
+
+ wait_for_new_pipeline(original_pipeline_count)
end
def update_ci_with_manual_job(job_name:, script:)
ci_file = ci_file_with_manual_job(job_name, script)
+ original_pipeline_count = pipeline_count
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = "Set job #{job_name} script #{script}"
commit.update_files([ci_file])
end
+
+ wait_for_new_pipeline(original_pipeline_count)
end
def ci_file_with_job_artifact(job_name, script)
@@ -199,6 +212,15 @@ module QA
job.id = project.job_by_name(job_name)[:id]
end
end
+
+ def pipeline_count
+ project.pipelines.length
+ end
+
+ def wait_for_new_pipeline(original_pipeline_count)
+ QA::Runtime::Logger.info('Waiting for new pipeline to be created')
+ Support::Waiter.wait_until { pipeline_count > original_pipeline_count }
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb
deleted file mode 100644
index a9f46e394f7..00000000000
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_tabs_spec.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Verify' do
- describe 'Pipeline editor', :reliable, product_group: :pipeline_authoring do
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'pipeline-editor-project'
- end
- end
-
- let!(:commit) 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
- stages:
- - stage1
- - stage2
-
- job1:
- stage: stage1
- script: echo 'Done.'
-
- job2:
- stage: stage2
- script: echo 'Done.'
- YAML
- }
- ]
- )
- end
- end
-
- let(:invalid_content) do
- <<~YAML
-
- job3:
- stage: stage_foo
- script: echo 'Done.'
- YAML
- end
-
- before do
- # Make sure a pipeline is created before visiting pipeline editor page.
- # Otherwise, test might timeout before the page finishing fetching pipeline status.
- Support::Waiter.wait_until { project.pipelines.present? }
-
- Flow::Login.sign_in
- project.visit!
- Page::Project::Menu.perform(&:go_to_pipeline_editor)
- end
-
- context 'when CI has valid syntax' do
- it(
- 'shows valid validations',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/368332'
- ) do
- Page::Project::PipelineEditor::Show.perform do |show|
- aggregate_failures do
- expect(show.ci_syntax_validate_message).to have_content('Pipeline syntax is correct')
-
- show.go_to_visualize_tab
- { stage1: 'job1', stage2: 'job2' }.each_pair do |stage, job|
- expect(show).to have_stage(stage), "Pipeline graph does not have stage #{stage}."
- expect(show).to have_job(job), "Pipeline graph does not have job #{job}."
- end
-
- show.go_to_validate_tab
- show.simulate_pipeline
- expect(show.tab_alert_title).to have_content('Simulation completed successfully')
-
- show.go_to_full_configuration_tab
- expect(show).to have_source_editor
- end
- end
- end
- end
-
- context 'when CI has invalid syntax' do
- it(
- 'shows invalid validations',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/368333'
- ) do
- invalid_msg = 'syntax is invalid'
-
- Page::Project::PipelineEditor::Show.perform do |show|
- show.write_to_editor(invalid_content)
-
- aggregate_failures do
- show.go_to_visualize_tab
- expect(show.tab_alert_message).to have_content(invalid_msg)
-
- show.go_to_validate_tab
- show.simulate_pipeline
- expect(show.tab_alert_title).to have_content('Pipeline simulation completed with errors')
-
- expect(show.ci_syntax_validate_message).to have_content('CI configuration is invalid')
-
- show.go_to_full_configuration_tab
-
- # TODO: remove page reload when
- # https://gitlab.com/gitlab-org/gitlab/-/issues/378536 is resolved
- expect { show.has_source_editor? }
- .to eventually_be_truthy.within(max_attempts: 2, reload_page: show, sleep_interval: 1)
-
- expect(show.ci_syntax_validate_message).to have_content('CI configuration is invalid')
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb
index c693a57605e..1abe1df5964 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb
@@ -112,7 +112,7 @@ module QA
QA::Service::Shellout.shell("docker cp #{runner_name}:/etc/gitlab-runner/config.toml #{tempdir.path}")
File.open(tempdir.path, 'a') do |f|
- f << %Q[ allowed_pull_policies = #{allowed_policies}\n]
+ f << %[ allowed_pull_policies = #{allowed_policies}\n]
end
QA::Service::Shellout.shell("docker cp #{tempdir.path} #{runner_name}:/etc/gitlab-runner/config.toml")
diff --git a/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb
index 312c5a13a61..8dc9fb6db36 100644
--- a/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb
@@ -1,8 +1,13 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', product_group: :package_registry do
- describe 'Terraform Module Registry' do
+ RSpec.describe 'Package', :requires_admin, product_group: :package_registry do
+ describe 'Terraform Module Registry',
+ quarantine: {
+ only: { job: 'airgapped' },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417407',
+ type: :investigating
+ } do
include Runtime::Fixtures
let(:group) { Resource::Group.fabricate_via_api! }
@@ -25,6 +30,7 @@ module QA
end
before do
+ # Remove 'requires_admin' if below method is removed
QA::Support::Helpers::ImportSource.enable('git')
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb
index 4179b65d930..83662e04fab 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/conan_repository_spec.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry, quarantine: {
- only: { job: 'object_storage' },
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/335981',
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry, quarantine: {
+ only: { job: %w[object_storage relative_url airgapped], condition: -> { QA::Support::FIPS.enabled? } },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417584',
type: :bug
} do
describe 'Conan Repository' do
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
index 19d0a4a816f..7bfda7f5956 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
@@ -1,8 +1,13 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'Helm Registry' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'Helm Registry',
+ quarantine: {
+ only: { job: %w[relative_url airgapped] },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417590',
+ type: :investigating
+ } do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
include Support::Helpers::MaskToken
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
index 3553e67eb2c..ce6c54b6ed8 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
@@ -1,8 +1,13 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'Maven group level endpoint' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'Maven group level endpoint',
+ quarantine: {
+ only: { job: %w[relative_url airgapped] },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417600',
+ type: :investigating
+ } do
include Runtime::Fixtures
include Support::Helpers::MaskToken
include_context 'packages registry qa scenario'
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
index 91d8f0dc181..35f80f8d447 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
@@ -1,7 +1,12 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' } do
+ RSpec.describe 'Package', :object_storage,
+ quarantine: {
+ only: { job: %w[relative_url airgapped] },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417600',
+ type: :investigating
+ } do
describe 'Maven project level endpoint', product_group: :package_registry do
include Runtime::Fixtures
include Support::Helpers::MaskToken
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
index 032c77b2519..f24466ed003 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
@@ -1,11 +1,16 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
+ RSpec.describe 'Package', :object_storage,
+ quarantine: {
+ only: { job: 'relative_url', condition: -> { QA::Support::FIPS.enabled? } },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417600',
+ type: :investigating
+ }, product_group: :package_registry do
describe 'Maven Repository with Gradle' do
using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
- include_context 'packages registry qa scenario'
+ include Support::Helpers::MaskToken
let(:group_id) { 'com.gitlab.qa' }
let(:artifact_id) { "maven_gradle-#{SecureRandom.hex(8)}" }
@@ -13,6 +18,52 @@ module QA
let(:package_version) { '1.3.7' }
let(:package_type) { 'maven_gradle' }
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = "#{package_type}_project"
+ project.initialize_with_readme = true
+ project.visibility = :private
+ end
+ end
+
+ let(:runner) do
+ Resource::ProjectRunner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{project.name}"]
+ runner.executor = :docker
+ runner.project = project
+ end
+ end
+
+ let(:gitlab_address_with_port) do
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ end
+
+ let(:project_deploy_token) do
+ Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'package-deploy-token'
+ deploy_token.project = project
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
+ end
+ end
+
+ let(:project_inbound_job_token_disabled) do
+ Resource::CICDSettings.fabricate_via_api! do |settings|
+ settings.project_path = project.full_path
+ settings.inbound_job_token_scope_enabled = false
+ end
+ end
+
+ before do
+ Flow::Login.sign_in_unless_signed_in
+ runner
+ end
+
where(:case_name, :authentication_token_type, :maven_header_name, :testcase) do
'using personal access token' | :personal_access_token | 'Private-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347601'
'using ci job token' | :ci_job_token | 'Job-Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347603'
@@ -23,38 +74,47 @@ module QA
let(:token) do
case authentication_token_type
when :personal_access_token
- "\"#{personal_access_token}\""
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: Runtime::Env.personal_access_token, project: project)
when :ci_job_token
- package_project_inbound_job_token_disabled
- client_project_inbound_job_token_disabled
- 'System.getenv("CI_JOB_TOKEN")'
+ project_inbound_job_token_disabled
+ '${CI_JOB_TOKEN}'
when :project_deploy_token
- "\"#{project_deploy_token.token}\""
+ use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project)
end
end
it 'pushes and pulls a maven package via gradle', testcase: params[:testcase] do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
- gradle_upload_yaml = ERB.new(read_fixture('package_managers/maven/gradle', 'gradle_upload_package.yaml.erb')).result(binding)
- build_upload_gradle = ERB.new(read_fixture('package_managers/maven/gradle', 'build_upload.gradle.erb')).result(binding)
+ gradle_publish_install_yaml = ERB.new(read_fixture('package_managers/maven/gradle', 'gradle_upload_install_package.yaml.erb')).result(binding)
+ build_gradle = ERB.new(read_fixture('package_managers/maven/gradle', 'build.gradle.erb')).result(binding)
- commit.project = package_project
+ commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
commit.add_files(
[
- { file_path: '.gitlab-ci.yml', content: gradle_upload_yaml },
- { file_path: 'build.gradle', content: build_upload_gradle }
+ { file_path: '.gitlab-ci.yml', content: gradle_publish_install_yaml },
+ { file_path: 'build.gradle', content: build_gradle }
])
end
end
- package_project.visit!
+ project.visit!
Flow::Pipeline.visit_latest_pipeline
Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
+ pipeline.click_job('publish')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+
+ job.click_element(:pipeline_path)
+ end
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
end
Page::Project::Job::Show.perform do |job|
@@ -72,33 +132,6 @@ module QA
Page::Project::Packages::Show.perform do |show|
expect(show).to have_package_info(package_name, package_version)
end
-
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- gradle_install_yaml = ERB.new(read_fixture('package_managers/maven/gradle', 'gradle_install_package.yaml.erb')).result(binding)
- build_install_gradle = ERB.new(read_fixture('package_managers/maven/gradle', 'build_install.gradle.erb')).result(binding)
-
- commit.project = client_project
- commit.commit_message = 'Add files'
- commit.add_files(
- [
- { file_path: '.gitlab-ci.yml', content: gradle_install_yaml },
- { file_path: 'build.gradle', content: build_install_gradle }
- ])
- end
- end
-
- client_project.visit!
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('build')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb
index 63549113517..7e2885d3724 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb
@@ -1,8 +1,13 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :object_storage, except: { job: 'relative-url' }, product_group: :package_registry do
- describe 'PyPI Repository' do
+ RSpec.describe 'Package', :object_storage, product_group: :package_registry do
+ describe 'PyPI Repository',
+ quarantine: {
+ only: { job: %w[relative_url airgapped] },
+ issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417592',
+ type: :investigating
+ } do
include Runtime::Fixtures
include Support::Helpers::MaskToken
@@ -30,7 +35,11 @@ module QA
end
let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) }
- let(:personal_access_token) { use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: Runtime::Env.personal_access_token, project: project) }
+
+ let!(:personal_access_token) do
+ use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: Runtime::Env.personal_access_token, project: project)
+ end
+
let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" }
let(:gitlab_host_with_port) do
# Don't specify port if it is a standard one
diff --git a/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb b/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
index 5ae90d20351..55ed9abb0da 100644
--- a/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
+++ b/qa/qa/specs/features/shared_contexts/import/github_import_shared_context.rb
@@ -48,7 +48,7 @@ module QA
)
end
- let(:mocks_path) { File.join(Runtime::Path.fixtures_path, "mocks", "import") }
+ let(:mocks_path) { Runtime::Path.fixture("mocks", "import") }
before do
set_mocks
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 bfd0825cf91..e702da4ad5b 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
@@ -32,7 +32,7 @@ module QA
Resource::Sandbox.fabricate_via_api! do |group|
group.api_client = source_admin_api_client
group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
- group.avatar = File.new(File.join(Runtime::Path.fixtures_path, 'designs', 'tanuki.jpg'), "r")
+ group.avatar = File.new(Runtime::Path.fixture('designs', 'tanuki.jpg'), "r")
end
end
diff --git a/qa/qa/support/formatters/allure_metadata_formatter.rb b/qa/qa/support/formatters/allure_metadata_formatter.rb
index eac74a3b961..3f7ec9f62b9 100644
--- a/qa/qa/support/formatters/allure_metadata_formatter.rb
+++ b/qa/qa/support/formatters/allure_metadata_formatter.rb
@@ -98,7 +98,6 @@ module QA
return unless flaky_specs.key?(example.metadata[:testcase]) && example.execution_result.status != :pending
example.set_flaky
- example.parameter("pass_rate", "#{flaky_specs[example.metadata[:testcase]].round(0)}%")
log(:debug, "Setting spec as flaky because it's pass rate is below 98%")
rescue StandardError => e
log(:error, "Failed to add spec pass rate data for example '#{example.description}', error: #{e}")
diff --git a/qa/qa/support/formatters/test_metrics_formatter.rb b/qa/qa/support/formatters/test_metrics_formatter.rb
index 6e6cdc35af5..cdc0e83dc02 100644
--- a/qa/qa/support/formatters/test_metrics_formatter.rb
+++ b/qa/qa/support/formatters/test_metrics_formatter.rb
@@ -35,7 +35,7 @@ module QA
# @param [Array<RSpec::Core::Example>] examples
# @return [Array<Hash>]
def execution_data(examples = nil)
- @execution_metrics ||= examples.map { |example| test_stats(example) }.compact
+ @execution_metrics ||= examples.filter_map { |example| test_stats(example) }
end
alias_method :parse_execution_data, :execution_data
@@ -171,11 +171,7 @@ module QA
#
# @return [Time]
def time
- @time ||= begin
- return Time.now unless env('CI_PIPELINE_CREATED_AT')
-
- env('CI_PIPELINE_CREATED_AT').to_time
- end
+ @time ||= env('CI_PIPELINE_CREATED_AT')&.to_time || Time.now
end
# Is a merge request execution
diff --git a/qa/qa/support/helpers/mask_token.rb b/qa/qa/support/helpers/mask_token.rb
index 3aea77779ad..928d24ec404 100644
--- a/qa/qa/support/helpers/mask_token.rb
+++ b/qa/qa/support/helpers/mask_token.rb
@@ -9,6 +9,7 @@ module QA
ci_variable.project = project
ci_variable.key = name
ci_variable.value = value
+ ci_variable.masked = true
end
"${#{name}}"
end
@@ -18,6 +19,7 @@ module QA
ci_variable.group = group
ci_variable.key = name
ci_variable.value = value
+ ci_variable.masked = true
end
"${#{name}}"
end
diff --git a/qa/qa/support/influxdb_tools.rb b/qa/qa/support/influxdb_tools.rb
index efdbe1cd129..e8f73540733 100644
--- a/qa/qa/support/influxdb_tools.rb
+++ b/qa/qa/support/influxdb_tools.rb
@@ -48,20 +48,21 @@ module QA
#
# @return [String, nil]
def run_type
- @run_type ||= begin
- return env('QA_RUN_TYPE') if env('QA_RUN_TYPE')
- return unless LIVE_ENVS.include?(ci_project_name)
+ @run_type ||= if env('QA_RUN_TYPE')
+ env('QA_RUN_TYPE')
+ elsif LIVE_ENVS.exclude?(ci_project_name)
+ nil
+ else
+ test_subset = if env('NO_ADMIN') == 'true'
+ 'sanity-no-admin'
+ elsif env('SMOKE_ONLY') == 'true'
+ 'sanity'
+ else
+ 'full'
+ end
- test_subset = if env('NO_ADMIN') == 'true'
- 'sanity-no-admin'
- elsif env('SMOKE_ONLY') == 'true'
- 'sanity'
- else
- 'full'
- end
-
- "#{ci_project_name}-#{test_subset}"
- end
+ "#{ci_project_name}-#{test_subset}"
+ end
end
# Merge request iid
diff --git a/qa/qa/support/matchers/have_matcher.rb b/qa/qa/support/matchers/have_matcher.rb
index a9b365f7e81..c77b585ada8 100644
--- a/qa/qa/support/matchers/have_matcher.rb
+++ b/qa/qa/support/matchers/have_matcher.rb
@@ -8,6 +8,7 @@ module QA
auto_devops_container
element
file_content
+ file_name
assignee
child_pipeline
linked_pipeline
diff --git a/qa/qa/support/parallel_pipeline_jobs.rb b/qa/qa/support/parallel_pipeline_jobs.rb
index a551bf9978b..7984412685d 100644
--- a/qa/qa/support/parallel_pipeline_jobs.rb
+++ b/qa/qa/support/parallel_pipeline_jobs.rb
@@ -7,7 +7,7 @@ module QA
class ParallelPipelineJobs
include API
- PARALLEL_JOB_NAME_PATTERN = %r{^\S+ \d+/\d+$}.freeze
+ PARALLEL_JOB_NAME_PATTERN = %r{^\S+ \d+/\d+$}
def initialize(stage_name:, project_id:, pipeline_id:, access_token:)
@stage_name = stage_name
diff --git a/qa/qa/support/wait_for_requests.rb b/qa/qa/support/wait_for_requests.rb
index ef7875eb838..2856602629a 100644
--- a/qa/qa/support/wait_for_requests.rb
+++ b/qa/qa/support/wait_for_requests.rb
@@ -39,12 +39,6 @@ module QA
Capybara.page.has_no_css?('.gl-spinner', wait: wait)
end
end
-
- def wait_for_gitlab_to_respond
- Waiter.wait_until(sleep_interval: 5, message: '502 - GitLab is taking too much time to respond') do
- Capybara.page.has_no_text?('GitLab is taking too much time to respond')
- end
- end
end
end
end
diff --git a/qa/qa/tools/ci/qa_changes.rb b/qa/qa/tools/ci/qa_changes.rb
index 1ab93b6dfbf..1e3ef9e4816 100644
--- a/qa/qa/tools/ci/qa_changes.rb
+++ b/qa/qa/tools/ci/qa_changes.rb
@@ -9,8 +9,8 @@ module QA
class QaChanges
include Helpers
- QA_PATTERN = %r{^qa/}.freeze
- SPEC_PATTERN = %r{^qa/qa/specs/features/\S+_spec\.rb}.freeze
+ QA_PATTERN = %r{^qa/}
+ SPEC_PATTERN = %r{^qa/qa/specs/features/\S+_spec\.rb}
DEPENDENCY_PATTERN = Regexp.union(
/_VERSION/,
/Gemfile\.lock/,
diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb
index fd76cc3d1a8..5a56f4a62c7 100644
--- a/qa/qa/tools/test_resources_handler.rb
+++ b/qa/qa/tools/test_resources_handler.rb
@@ -38,6 +38,7 @@ module QA
QA::EE::Resource::VulnerabilityItem
QA::EE::Resource::ScanResultPolicyProject
QA::EE::Resource::ScanResultPolicyCommit
+ QA::EE::Resource::InstanceAuditEventExternalDestination
].freeze
PROJECT = 'gitlab-qa-resources'
diff --git a/qa/qa/vendor/facebook/page/login.rb b/qa/qa/vendor/facebook/page/login.rb
new file mode 100644
index 00000000000..99e79d2e5a4
--- /dev/null
+++ b/qa/qa/vendor/facebook/page/login.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module QA
+ module Vendor
+ module Facebook
+ module Page
+ class Login < Vendor::Page::Base
+ def login
+ fill_in 'email', with: QA::Runtime::Env.facebook_username
+ fill_in 'pass', with: QA::Runtime::Env.facebook_password
+ find('#loginbutton').click
+
+ confirm_oauth_access
+ end
+
+ def confirm_oauth_access
+ first('span', text: 'Continue as').click if has_css?('span', text: 'Continue as')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/vendor/github/page/base.rb b/qa/qa/vendor/github/page/base.rb
deleted file mode 100644
index 3b96180afe9..00000000000
--- a/qa/qa/vendor/github/page/base.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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
index 17a7471e251..ce71fc5f11e 100644
--- a/qa/qa/vendor/github/page/login.rb
+++ b/qa/qa/vendor/github/page/login.rb
@@ -1,13 +1,10 @@
# frozen_string_literal: true
-require 'capybara/dsl'
-require 'benchmark'
-
module QA
module Vendor
module Github
module Page
- class Login < Page::Base
+ class Login < Vendor::Page::Base
def login
fill_in 'login', with: QA::Runtime::Env.github_username
fill_in 'password', with: QA::Runtime::Env.github_password
@@ -24,11 +21,17 @@ module QA
end
authorize_app
+
+ confirm_account_recovery_settings
end
def authorize_app
click_on 'Authorize' if has_button?('Authorize')
end
+
+ def confirm_account_recovery_settings
+ click_on 'Confirm' if has_button?('Confirm')
+ end
end
end
end
diff --git a/qa/qa/vendor/page/base.rb b/qa/qa/vendor/page/base.rb
new file mode 100644
index 00000000000..1cfba6bfdda
--- /dev/null
+++ b/qa/qa/vendor/page/base.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'capybara/dsl'
+
+module QA
+ module Vendor
+ module Page
+ class Base
+ include Capybara::DSL
+ include Scenario::Actable
+ end
+ end
+ end
+end
diff --git a/qa/qa/vendor/saml_idp/page/base.rb b/qa/qa/vendor/saml_idp/page/base.rb
deleted file mode 100644
index 39413a64d5a..00000000000
--- a/qa/qa/vendor/saml_idp/page/base.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Vendor
- module SamlIdp
- module Page
- class Base
- include Capybara::DSL
- include Scenario::Actable
- end
- end
- end
- end
-end
diff --git a/qa/qa/vendor/saml_idp/page/login.rb b/qa/qa/vendor/saml_idp/page/login.rb
index dc6925109f7..9b4fbe15366 100644
--- a/qa/qa/vendor/saml_idp/page/login.rb
+++ b/qa/qa/vendor/saml_idp/page/login.rb
@@ -1,18 +1,22 @@
# frozen_string_literal: true
-require 'capybara/dsl'
-
module QA
module Vendor
module SamlIdp
module Page
- class Login < Page::Base
+ class Login < Vendor::Page::Base
def login(username, password)
QA::Runtime::Logger.debug("Logging into SAMLIdp with username: #{username} and password:#{password}")
fill_in 'username', with: username
fill_in 'password', with: password
click_on 'Login'
+
+ if Runtime::Env.super_sidebar_enabled?
+ QA::Page::Main::Menu.perform(&:enable_new_navigation)
+ else
+ QA::Page::Main::Menu.perform(&:disable_new_navigation)
+ end
end
def login_if_required(username, password)
diff --git a/qa/qa/vendor/smocker/smocker_api.rb b/qa/qa/vendor/smocker/smocker_api.rb
index 0434b5dcea4..4bad41f98bd 100644
--- a/qa/qa/vendor/smocker/smocker_api.rb
+++ b/qa/qa/vendor/smocker/smocker_api.rb
@@ -44,7 +44,7 @@ module QA
#
# @param wait [Integer] wait duration for smocker readiness
def wait_for_ready(wait: 10)
- Support::Waiter.wait_until(max_duration: wait, reload_page: false, raise_on_failure: true) do
+ Support::Waiter.wait_until(max_duration: wait, sleep_interval: 1, log: false) do
ready?
end
end
diff --git a/qa/spec/runtime/feature_spec.rb b/qa/spec/runtime/feature_spec.rb
index 72ba915d99b..351856de1bd 100644
--- a/qa/spec/runtime/feature_spec.rb
+++ b/qa/spec/runtime/feature_spec.rb
@@ -59,7 +59,7 @@ RSpec.describe QA::Runtime::Feature do
.and_return(request)
expect(described_class)
.to receive(:get)
- .and_return(Struct.new(:code, :body).new(200, %Q([{ "name": "a_flag", "state": "conditional", "gates": #{gates} }])))
+ .and_return(Struct.new(:code, :body).new(200, %([{ "name": "a_flag", "state": "conditional", "gates": #{gates} }])))
expect(described_class.enabled?(feature_flag, scope => actor)).to be true
end
diff --git a/qa/spec/service/docker_run/video_spec.rb b/qa/spec/service/docker_run/video_spec.rb
index 81be5ccffae..d8d7f680629 100644
--- a/qa/spec/service/docker_run/video_spec.rb
+++ b/qa/spec/service/docker_run/video_spec.rb
@@ -4,7 +4,7 @@ module QA
RSpec.describe Service::DockerRun::Video do
include QA::Support::Helpers::StubEnv
- let(:rspec_config) { instance_double('RSpec::Core::Configuration', append_after: nil, prepend_before: nil) }
+ let(:rspec_config) { instance_double('RSpec::Core::Configuration', prepend_before: nil, prepend_after: nil) }
let(:video_recorder_image) { 'presidenten/selenoid-manual-video-recorder' }
let(:video_recorder_version) { 'latest' }
let(:selenoid_browser_image) { 'selenoid/chrome' }
@@ -12,6 +12,7 @@ module QA
let(:remote_grid) { 'selenoid:4444' }
let(:record_video) { 'true' }
let(:use_selenoid) { 'true' }
+ let(:allure_report) { 'false' }
let(:docs_link) do
'https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/running_against_remote_grid.md#testing-with-selenoid'
end
@@ -55,6 +56,7 @@ module QA
stub_env('QA_REMOTE_GRID', remote_grid)
stub_env('USE_SELENOID', use_selenoid)
stub_env('QA_RECORD_VIDEO', record_video)
+ stub_env('QA_GENERATE_ALLURE_REPORT', allure_report)
allow(RSpec).to receive(:configure).and_yield(rspec_config)
allow(described_class).to receive(:get_container_name)
@@ -173,7 +175,29 @@ module QA
.with(/Test failure video recording setup complete!/)
expect(RSpec).to have_received(:configure)
expect(rspec_config).to have_received(:prepend_before)
- expect(rspec_config).to have_received(:append_after)
+ expect(rspec_config).to have_received(:prepend_after)
+ end
+ end
+
+ context 'with generate_allure_report' do
+ let(:rspec_config) do
+ instance_double('RSpec::Core::Configuration',
+ prepend_before: nil,
+ prepend_after: nil,
+ append_after: nil)
+ end
+
+ let(:allure_report) { 'true' }
+
+ it 'performs configuration with allure report' do
+ aggregate_failures do
+ expect(QA::Runtime::Logger).to have_received(:info)
+ .with(/Test failure video recording setup complete!/)
+ expect(RSpec).to have_received(:configure).twice
+ expect(rspec_config).to have_received(:prepend_before)
+ expect(rspec_config).to have_received(:prepend_after)
+ expect(rspec_config).to have_received(:append_after)
+ end
end
end
end
diff --git a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
index ab3b753c3b0..b80c3f125e9 100644
--- a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
+++ b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
@@ -75,16 +75,6 @@ describe QA::Support::Formatters::AllureMetadataFormatter do
allow(InfluxDB2::Client).to receive(:new) { influx_client }
end
- context 'with non skipped spec' do
- it 'adds flaky test data' do
- formatter.start(nil)
- formatter.example_finished(rspec_example_notification)
-
- expect(rspec_example).to have_received(:set_flaky)
- expect(rspec_example).to have_received(:parameter).with('pass_rate', '50%')
- end
- end
-
context 'with skipped spec' do
let(:status) { :pending }