summaryrefslogtreecommitdiff
path: root/qa/qa/specs
diff options
context:
space:
mode:
Diffstat (limited to 'qa/qa/specs')
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb100
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb71
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb (renamed from qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb)26
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb99
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb (renamed from qa/qa/specs/features/api/3_create/repository/praefect_replication_queue_spec.rb)5
-rw-r--r--qa/qa/specs/features/api/4_verify/pipeline_deletion_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb92
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb46
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb15
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb (renamed from qa/qa/specs/features/browser_ui/3_create/design_management/add_design_add_annotation.rb)19
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/gitaly/high_availability_spec.rb65
-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/view_merge_request_diff_patch_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb1
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb67
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb37
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb67
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb31
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/.gitkeep0
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb104
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb77
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb1
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb1
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb21
33 files changed, 837 insertions, 169 deletions
diff --git a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
new file mode 100644
index 00000000000..064f5280625
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb
@@ -0,0 +1,100 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ context 'Gitaly automatic failover and manual recovery', :orchestrated, :gitaly_cluster, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/238953', type: :flaky } do
+ # Variables shared between contexts. They're used and shared between
+ # contexts so they can't be `let` variables.
+ praefect_manager = Service::PraefectManager.new
+ project = nil
+
+ let(:intial_commit_message) { 'Initial commit' }
+ let(:first_added_commit_message) { 'pushed to primary gitaly node' }
+ let(:second_added_commit_message) { 'commit to failover node' }
+
+ before(:context) do
+ # Reset the cluster in case previous tests left it in a bad state
+ praefect_manager.reset_primary_to_original
+
+ project = Resource::Project.fabricate! do |project|
+ project.name = "gitaly_cluster"
+ project.initialize_with_readme = true
+ end
+ end
+
+ after(:context) do
+ # Leave the cluster in a suitable state for subsequent tests,
+ # if there was a problem during the tests here
+ praefect_manager.reset_primary_to_original
+ end
+
+ it 'automatically fails over' do
+ # Create a new project with a commit and wait for it to replicate
+ Resource::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.commit_message = first_added_commit_message
+ push.new_branch = false
+ push.file_content = "This should exist on both nodes"
+ end
+
+ praefect_manager.wait_for_replication(project.id)
+
+ # Stop the primary node to trigger failover, and then wait
+ # for Gitaly to be ready for writes again
+ praefect_manager.trigger_failover_by_stopping_primary_node
+ praefect_manager.wait_for_new_primary
+ praefect_manager.wait_for_health_check_current_primary_node
+ praefect_manager.wait_for_gitaly_check
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = second_added_commit_message
+ commit.add_files([
+ {
+ file_path: "file-#{SecureRandom.hex(8)}",
+ content: 'This should exist on one node before reconciliation'
+ }
+ ])
+ end
+
+ # Confirm that we have access to the repo after failover,
+ # including the commit we just added
+ expect(project.commits.map { |commit| commit[:message].chomp })
+ .to include(intial_commit_message)
+ .and include(first_added_commit_message)
+ .and include(second_added_commit_message)
+ end
+
+ context 'when recovering from dataloss after failover' do
+ it 'allows reconciliation', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/238187', type: :stale } do
+ # Start the old primary node again
+ praefect_manager.start_primary_node
+ praefect_manager.wait_for_health_check_current_primary_node
+
+ # Confirm dataloss (i.e., inconsistent nodes)
+ expect(praefect_manager.replicated?(project.id)).to be false
+
+ # Reconcile nodes to recover from dataloss
+ praefect_manager.reconcile_nodes
+ praefect_manager.wait_for_replication(project.id)
+
+ # Confirm that all commits are available after reconciliation
+ expect(project.commits.map { |commit| commit[:message].chomp })
+ .to include(intial_commit_message)
+ .and include(first_added_commit_message)
+ .and include(second_added_commit_message)
+
+ # Restore the original primary node
+ praefect_manager.reset_primary_to_original
+
+ # Check that all commits are still available even though the primary
+ # node was offline when one was made
+ expect(project.commits.map { |commit| commit[:message].chomp })
+ .to include(intial_commit_message)
+ .and include(first_added_commit_message)
+ .and include(second_added_commit_message)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb
new file mode 100644
index 00000000000..52674f08e15
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ context 'Gitaly' do
+ describe 'Backend node recovery', :orchestrated, :gitaly_cluster, :skip_live_env do
+ let(:praefect_manager) { Service::PraefectManager.new }
+ let(:project) do
+ Resource::Project.fabricate! do |project|
+ project.name = "gitaly_cluster"
+ project.initialize_with_readme = true
+ end
+ end
+
+ before do
+ # Reset the cluster in case previous tests left it in a bad state
+ praefect_manager.reset_primary_to_original
+ end
+
+ after do
+ # Leave the cluster in a suitable state for subsequent tests
+ praefect_manager.reset_primary_to_original
+ end
+
+ it 'recovers from dataloss', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/238186', type: :investigating } do
+ # Create a new project with a commit and wait for it to replicate
+ praefect_manager.wait_for_replication(project.id)
+
+ # Stop the primary node to trigger failover, and then wait
+ # for Gitaly to be ready for writes again
+ praefect_manager.trigger_failover_by_stopping_primary_node
+ praefect_manager.wait_for_new_primary
+ praefect_manager.wait_for_health_check_current_primary_node
+ praefect_manager.wait_for_gitaly_check
+
+ # Confirm that we have access to the repo after failover
+ Support::Waiter.wait_until(retry_on_exception: true, sleep_interval: 5) do
+ Resource::Repository::Commit.fabricate_via_api! do |commits|
+ commits.project = project
+ commits.sha = 'master'
+ end
+ end
+
+ # Push a commit to the new primary
+ Resource::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.new_branch = false
+ push.commit_message = 'pushed after failover'
+ push.file_name = 'new_file'
+ push.file_content = 'new file'
+ end
+
+ # Start the old primary node again
+ praefect_manager.start_primary_node
+ praefect_manager.wait_for_health_check_current_primary_node
+
+ # Confirm dataloss (i.e., inconsistent nodes)
+ expect(praefect_manager.replicated?(project.id)).to be false
+
+ # Reconcile nodes to recover from dataloss
+ praefect_manager.reconcile_nodes
+ praefect_manager.wait_for_replication(project.id)
+
+ # Confirm that both commits are available after reconciliation
+ expect(project.commits.map { |commit| commit[:message].chomp })
+ .to include("Initial commit").and include("pushed after failover")
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
index 11e7db5b097..432598d1cb3 100644
--- a/qa/qa/specs/features/api/3_create/repository/changing_repository_storage_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb
@@ -2,14 +2,15 @@
module QA
RSpec.describe 'Create' do
- describe 'Changing Gitaly repository storage', :requires_admin do
+ describe 'Changing Gitaly repository storage', :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/236195', type: :investigating } do
+ praefect_manager = Service::PraefectManager.new
+ praefect_manager.gitlab = 'gitlab'
+
shared_examples 'repository storage move' do
it 'confirms a `finished` status after moving project repository storage' do
expect(project).to have_file('README.md')
-
- project.change_repository_storage(destination_storage)
-
- expect(Runtime::API::RepositoryStorageMoves).to have_status(project, 'finished', destination_storage)
+ expect { project.change_repository_storage(destination_storage[:name]) }.not_to raise_error
+ expect { praefect_manager.verify_storage_move(source_storage, destination_storage) }.not_to raise_error
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project
@@ -25,28 +26,35 @@ module QA
end
context 'when moving from one Gitaly storage to another', :orchestrated, :repository_storage do
+ let(:source_storage) { { type: :gitaly, name: 'default' } }
+ let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.additional_repository_storage } }
+
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'repo-storage-move-status'
project.initialize_with_readme = true
+ project.api_client = Runtime::API::Client.as_admin
end
end
- let(:destination_storage) { QA::Runtime::Env.additional_repository_storage }
it_behaves_like 'repository storage move'
end
# Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect
# scenario with other tests that aren't considered orchestrated.
- context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/227127', type: :investigating } do
+ # It also runs on staging using nfs-file07 as non-cluster storage and nfs-file22 as cluster/praefect storage
+ context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect do
+ let(:source_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } }
+ let(:destination_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } }
+
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'repo-storage-move'
project.initialize_with_readme = true
- project.repository_storage = 'gitaly'
+ project.repository_storage = source_storage[:name]
+ project.api_client = Runtime::API::Client.as_admin
end
end
- let(:destination_storage) { QA::Runtime::Env.praefect_repository_storage }
it_behaves_like 'repository storage move'
end
diff --git a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
new file mode 100644
index 00000000000..6292ca821ca
--- /dev/null
+++ b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+require 'parallel'
+
+module QA
+ RSpec.describe 'Create' do
+ context 'Gitaly' do
+ # Issue to track removal of feature flag: https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/602
+ describe 'Distributed reads', :orchestrated, :gitaly_cluster, :skip_live_env, :requires_admin do
+ let(:number_of_reads_per_loop) { 9 }
+ let(:praefect_manager) { Service::PraefectManager.new }
+ let(:project) do
+ Resource::Project.fabricate! do |project|
+ project.name = "gitaly_cluster"
+ project.initialize_with_readme = true
+ end
+ end
+
+ before do
+ Runtime::Feature.enable_and_verify('gitaly_distributed_reads')
+ praefect_manager.wait_for_replication(project.id)
+ end
+
+ after do
+ Runtime::Feature.disable_and_verify('gitaly_distributed_reads')
+ end
+
+ it 'reads from each node' do
+ pre_read_data = praefect_manager.query_read_distribution
+
+ wait_for_reads_to_increase(project, number_of_reads_per_loop, pre_read_data)
+
+ aggregate_failures "each gitaly node" do
+ praefect_manager.query_read_distribution.each_with_index do |data, index|
+ pre_read_count = praefect_manager.value_for_node(pre_read_data, data[:node])
+ QA::Runtime::Logger.debug("Node: #{data[:node]}; before: #{pre_read_count}; now: #{data[:value]}")
+ expect(data[:value]).to be > pre_read_count,
+ "Read counts did not differ for node #{data[:node]}"
+ end
+ end
+ end
+
+ context 'when a node is unhealthy' do
+ before do
+ praefect_manager.stop_secondary_node
+ praefect_manager.wait_for_secondary_node_health_check_failure
+ end
+
+ after do
+ # Leave the cluster in a suitable state for subsequent tests
+ praefect_manager.start_secondary_node
+ praefect_manager.wait_for_health_check_all_nodes
+ praefect_manager.wait_for_reliable_connection
+ end
+
+ it 'does not read from the unhealthy node' do
+ pre_read_data = praefect_manager.query_read_distribution
+
+ read_from_project(project, number_of_reads_per_loop * 10)
+
+ praefect_manager.wait_for_read_count_change(pre_read_data)
+
+ post_read_data = praefect_manager.query_read_distribution
+
+ aggregate_failures "each gitaly node" do
+ expect(praefect_manager.value_for_node(post_read_data, 'gitaly1')).to be > praefect_manager.value_for_node(pre_read_data, 'gitaly1')
+ expect(praefect_manager.value_for_node(post_read_data, 'gitaly2')).to eq praefect_manager.value_for_node(pre_read_data, 'gitaly2')
+ expect(praefect_manager.value_for_node(post_read_data, 'gitaly3')).to be > praefect_manager.value_for_node(pre_read_data, 'gitaly3')
+ end
+ end
+ end
+
+ def read_from_project(project, number_of_reads)
+ QA::Runtime::Logger.info('Reading from the repository')
+ Parallel.each((1..number_of_reads)) do
+ Git::Repository.perform do |repository|
+ repository.uri = project.repository_http_location.uri
+ repository.use_default_credentials
+ repository.clone
+ end
+ end
+ end
+
+ def wait_for_reads_to_increase(project, number_of_reads, pre_read_data)
+ diff_found = pre_read_data
+
+ Support::Waiter.wait_until(sleep_interval: 5, raise_on_failure: false) do
+ read_from_project(project, number_of_reads)
+
+ praefect_manager.query_read_distribution.each_with_index do |data, index|
+ diff_found[index][:diff] = true if data[:value] > praefect_manager.value_for_node(pre_read_data, data[:node])
+ end
+ diff_found.all? { |node| node.key?(:diff) && node[:diff] }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/3_create/repository/praefect_replication_queue_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
index a4040a46b84..78c8639a029 100644
--- a/qa/qa/specs/features/api/3_create/repository/praefect_replication_queue_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb
@@ -4,7 +4,7 @@ require 'parallel'
module QA
RSpec.describe 'Create' do
- context 'Gitaly Cluster replication queue', :orchestrated, :gitaly_ha, :skip_live_env do
+ context 'Gitaly Cluster replication queue', :orchestrated, :gitaly_cluster, :skip_live_env do
let(:praefect_manager) { Service::PraefectManager.new }
let(:project) do
Resource::Project.fabricate! do |project|
@@ -14,7 +14,8 @@ module QA
end
after do
- praefect_manager.reset_cluster
+ praefect_manager.start_praefect
+ praefect_manager.wait_for_reliable_connection
praefect_manager.clear_replication_queue
end
diff --git a/qa/qa/specs/features/api/4_verify/pipeline_deletion_spec.rb b/qa/qa/specs/features/api/4_verify/pipeline_deletion_spec.rb
index a406fa409d5..567815858f3 100644
--- a/qa/qa/specs/features/api/4_verify/pipeline_deletion_spec.rb
+++ b/qa/qa/specs/features/api/4_verify/pipeline_deletion_spec.rb
@@ -48,6 +48,12 @@ module QA
let(:pipeline_data_request) { Runtime::API::Request.new(api_client, "/projects/#{project.id}/pipelines/#{pipeline_id}") }
+ before do
+ Support::Waiter.wait_until(max_duration: 30, sleep_interval: 3) do
+ JSON.parse(get(pipeline_data_request.url))['status'] != 'pending'
+ end
+ end
+
after do
runner.remove_via_api!
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
new file mode 100644
index 00000000000..e83aed18b5f
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+module QA
+ context 'Manage', :requires_admin, :skip_live_env do
+ describe '2FA' do
+ let(:owner_user) do
+ Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_2fa_owner_username_1, Runtime::Env.gitlab_qa_2fa_owner_password_1)
+ end
+
+ let(:developer_user) do
+ Resource::User.fabricate_via_api! do |resource|
+ resource.api_client = admin_api_client
+ end
+ end
+
+ let(:sandbox_group) do
+ Resource::Sandbox.fabricate! do |sandbox_group|
+ sandbox_group.path = "gitlab-qa-2fa-recovery-sandbox-group-#{SecureRandom.hex(4)}"
+ sandbox_group.api_client = owner_api_client
+ end
+ end
+
+ let(:group) do
+ QA::Resource::Group.fabricate_via_api! do |group|
+ group.sandbox = sandbox_group
+ group.api_client = owner_api_client
+ group.require_two_factor_authentication = true
+ end
+ end
+
+ before do
+ group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER)
+ end
+
+ it 'allows using 2FA recovery code once only' do
+ recovery_code = enable_2fa_for_user_and_fetch_recovery_code(developer_user)
+
+ Flow::Login.sign_in(as: developer_user, skip_page_validation: true)
+
+ Page::Main::TwoFactorAuth.perform do |two_fa_auth|
+ two_fa_auth.set_2fa_code(recovery_code)
+ two_fa_auth.click_verify_code_button
+ end
+
+ expect(Page::Main::Menu.perform(&:signed_in?)).to be_truthy
+
+ Page::Main::Menu.perform(&:sign_out)
+
+ Flow::Login.sign_in(as: developer_user, skip_page_validation: true)
+
+ Page::Main::TwoFactorAuth.perform do |two_fa_auth|
+ two_fa_auth.set_2fa_code(recovery_code)
+ two_fa_auth.click_verify_code_button
+ end
+
+ expect(page).to have_text('Invalid two-factor code')
+ end
+
+ after do
+ group.set_require_two_factor_authentication(value: 'false')
+ group.remove_via_api!
+ sandbox_group.remove_via_api!
+ developer_user.remove_via_api!
+ end
+
+ def admin_api_client
+ @admin_api_client ||= Runtime::API::Client.as_admin
+ end
+
+ def owner_api_client
+ @owner_api_client ||= Runtime::API::Client.new(:gitlab, user: owner_user)
+ end
+
+ def enable_2fa_for_user_and_fetch_recovery_code(user)
+ Flow::Login.while_signed_in(as: user) do
+ Page::Profile::TwoFactorAuth.perform do |two_fa_auth|
+ @otp = QA::Support::OTP.new(two_fa_auth.otp_secret_content)
+
+ two_fa_auth.set_pin_code(@otp.fresh_otp)
+ two_fa_auth.click_register_2fa_app_button
+
+ recovery_code = two_fa_auth.recovery_codes.sample
+
+ two_fa_auth.click_proceed_button
+
+ recovery_code
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
index 9dfeec37869..bb01be9d86e 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.shared_examples 'registration and login' do
- it 'user registers and logs in' do
+ it 'allows the user to registers and login' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Resource::User.fabricate_via_browser_ui!
@@ -16,6 +16,50 @@ module QA
RSpec.describe 'Manage', :skip_signup_disabled do
describe 'standard' do
it_behaves_like 'registration and login'
+
+ context 'when user account is deleted', :requires_admin do
+ let(:user) do
+ Resource::User.fabricate_via_api! do |resource|
+ resource.api_client = admin_api_client
+ end
+ end
+
+ before do
+ # Use the UI instead of API to delete the account since
+ # this is the only test that exercise this UI.
+ # Other tests should use the API for this purpose.
+ Flow::Login.sign_in(as: user)
+ Page::Main::Menu.perform(&:click_settings_link)
+ Page::Profile::Menu.perform(&:click_account)
+ Page::Profile::Accounts::Show.perform do |show|
+ show.delete_account(user.password)
+ end
+ end
+
+ it 'allows recreating with same credentials' do
+ expect(Page::Main::Menu.perform(&:signed_in?)).to be_falsy
+
+ Flow::Login.sign_in(as: user, skip_page_validation: true)
+
+ expect(page).to have_text("Invalid Login or password")
+
+ @recreated_user = Resource::User.fabricate_via_browser_ui! do |resource|
+ resource.name = user.name
+ resource.username = user.username
+ resource.email = user.email
+ end
+
+ expect(Page::Main::Menu.perform(&:signed_in?)).to be_truthy
+ end
+
+ after do
+ @recreated_user.remove_via_api!
+ end
+
+ def admin_api_client
+ @admin_api_client ||= Runtime::API::Client.as_admin
+ end
+ end
end
end
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 3717bc8a9ff..a334731386a 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
@@ -26,7 +26,7 @@ module QA
mailhog_items = mailhog_json.dig('items')
- expect(mailhog_items).to include(an_object_satisfying { |o| /project was granted/ === o.dig('Content', 'Headers', 'Subject', 0) })
+ expect(mailhog_items).to include(an_object_satisfying { |o| /project was granted/ === mailhog_item_subject(o) })
end
private
@@ -38,11 +38,22 @@ module QA
mailhog_response = get QA::Runtime::MailHog.api_messages_url
mailhog_data = JSON.parse(mailhog_response.body)
+ total = mailhog_data.dig('total')
+ subjects = mailhog_data.dig('items')
+ .map(&method(:mailhog_item_subject))
+ .join("\n")
+
+ Runtime::Logger.debug(%Q[Total number of emails: #{total}])
+ Runtime::Logger.debug(%Q[Subjects:\n#{subjects}])
# Expect at least two invitation messages: group and project
- mailhog_data if mailhog_data.dig('total') >= 2
+ mailhog_data if total >= 2
end
end
+
+ def mailhog_item_subject(item)
+ item.dig('Content', 'Headers', 'Subject', 0)
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
index e41024e5d14..91fd2579fcd 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
@@ -19,7 +19,7 @@ module QA
end
end
- it 'closes an issue' do
+ it 'closes an issue', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/225303', type: :bug } do
closed_issue.visit!
Page::Project::Issue::Show.perform do |issue_page|
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
index 50df1c3ef01..b0b2a83ae35 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
@@ -3,17 +3,18 @@
module QA
RSpec.describe 'Plan', :smoke, :reliable do
describe 'mention' do
- before do
- Flow::Login.sign_in
-
- @user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
-
- project = Resource::Project.fabricate_via_api! do |project|
+ let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
project.name = 'project-to-test-mention'
project.visibility = 'private'
end
+ end
+
+ before do
+ Flow::Login.sign_in
- project.add_member(@user)
+ project.add_member(user)
Resource::Issue.fabricate_via_api! do |issue|
issue.project = project
@@ -22,7 +23,7 @@ module QA
it 'mentions another user in an issue' do
Page::Project::Issue::Show.perform do |show|
- at_username = "@#{@user.username}"
+ at_username = "@#{user.username}"
show.select_all_activities_filter
show.comment(at_username)
diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_add_annotation.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb
index b50edcfcf08..44c1511fffb 100644
--- a/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_add_annotation.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/design_management/add_design_content_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- context 'Create' do
- describe 'Design management' do
+ RSpec.describe 'Create' do
+ context 'Design Management' do
let(:issue) { Resource::Issue.fabricate_via_api! }
let(:design_filename) { 'banana_sample.gif' }
let(:design) { File.absolute_path(File.join('spec', 'fixtures', design_filename)) }
@@ -12,18 +12,15 @@ module QA
Flow::Login.sign_in
end
- it 'user adds a design and annotation' do
+ it 'user adds a design and annotates it' do
issue.visit!
- Page::Project::Issue::Show.perform do |show|
- show.click_designs_tab
- show.add_design(design)
- show.click_design(design_filename)
- show.add_annotation(annotation)
+ Page::Project::Issue::Show.perform do |issue|
+ issue.add_design(design)
+ issue.click_design(design_filename)
+ issue.add_annotation(annotation)
- expect(show).to have_annotation(annotation)
-
- show.click_discussion_tab
+ expect(issue).to have_annotation(annotation)
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/gitaly/high_availability_spec.rb b/qa/qa/specs/features/browser_ui/3_create/gitaly/high_availability_spec.rb
deleted file mode 100644
index 97a76c1aa01..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/gitaly/high_availability_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create' do
- context 'Gitaly' do
- describe 'High Availability', :orchestrated, :gitaly_ha do
- let(:project) do
- Resource::Project.fabricate! do |project|
- project.name = 'gitaly_high_availability'
- end
- end
- let(:initial_file) { 'pushed_to_primary.txt' }
- let(:final_file) { 'committed_to_primary.txt' }
- let(:praefect_manager) { Service::PraefectManager.new }
-
- before do
- Flow::Login.sign_in
- end
-
- after do
- praefect_manager.reset_cluster
- end
-
- it 'makes sure that automatic failover is happening' do
- Resource::Repository::ProjectPush.fabricate! do |push|
- push.project = project
- push.commit_message = 'pushed to primary gitaly node'
- push.new_branch = true
- push.file_name = initial_file
- push.file_content = "This should exist on both nodes"
- end
-
- praefect_manager.trigger_failover_by_stopping_primary_node
-
- project.visit!
-
- Page::Project::Show.perform do |show|
- show.wait_until do
- show.has_name?(project.name)
- end
- expect(show).to have_file(initial_file)
- end
-
- praefect_manager.enable_writes
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.add_files([
- {
- file_path: final_file,
- content: 'This should exist on both nodes too'
- }
- ])
- end
-
- project.visit!
-
- Page::Project::Show.perform do |show|
- expect(show).to have_file(final_file)
- end
- end
- end
- end
- end
-end
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 a002779d7d9..524cc3fc8a1 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
@@ -16,7 +16,7 @@ module QA
Flow::Login.sign_in
end
- it 'creates a basic merge request' do
+ it 'creates a basic merge request', :smoke do
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
merge_request.project = project
merge_request.title = merge_request_title
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
index 3c2c068dfd1..15c41581e6b 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_diff_patch_spec.rb
@@ -3,31 +3,30 @@
module QA
RSpec.describe 'Create' do
describe 'Download merge request patch and diff' do
- before(:context) do
- @merge_request = Resource::MergeRequest.fabricate_via_api! do |merge_request|
+ let(:merge_request) do
+ Resource::MergeRequest.fabricate_via_api! do |merge_request|
merge_request.title = 'This is a merge request'
merge_request.description = '... for downloading patches and diffs'
end
end
- it 'views the merge request email patches' do
+ before do
Flow::Login.sign_in
+ merge_request.visit!
+ end
- @merge_request.visit!
+ it 'views the merge request email patches' do
Page::MergeRequest::Show.perform(&:view_email_patches)
expect(page.text).to start_with('From')
expect(page).to have_content('Subject: [PATCH] This is a test commit')
- expect(page).to have_content("diff --git a/#{@merge_request.file_name} b/#{@merge_request.file_name}")
+ expect(page).to have_content("diff --git a/#{merge_request.file_name} b/#{merge_request.file_name}")
end
it 'views the merge request plain diff' do
- Flow::Login.sign_in
-
- @merge_request.visit!
Page::MergeRequest::Show.perform(&:view_plain_diff)
- expect(page.text).to start_with("diff --git a/#{@merge_request.file_name} b/#{@merge_request.file_name}")
+ expect(page.text).to start_with("diff --git a/#{merge_request.file_name} b/#{merge_request.file_name}")
expect(page).to have_content('+File Added')
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
index f586c25165c..59e4bb038a7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
@@ -10,6 +10,7 @@ module QA
project.initialize_with_readme = true
end
end
+
let(:fork_project) do
Resource::Fork.fabricate_via_api! do |fork|
fork.user = user
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
index c01558d3702..ceacc73e3c3 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Git push over HTTP', :ldap_no_tls do
+ describe 'Git push over HTTP', :ldap_no_tls, :smoke do
it 'user using a personal access token pushes code to the repository' do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
index b918b2ff268..2baf1e1d8fd 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Git push over HTTP', :ldap_no_tls do
- it 'user pushes code to the repository' do
+ it 'user pushes code to the repository', :smoke do
Flow::Login.sign_in
Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
new file mode 100644
index 00000000000..d0f0cabbbca
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ describe 'SSH key support' do
+ # Note: If you run these tests against GDK make sure you've enabled sshd
+ # See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md
+
+ let(:project) do
+ Resource::Project.fabricate! do |project|
+ project.name = 'ssh-tests'
+ end
+ end
+
+ before(:context) do
+ @key = Resource::SSHKey.fabricate_via_api! do |resource|
+ resource.title = "key for ssh tests #{Time.now.to_f}"
+ end
+ end
+
+ after(:context) do
+ @key.remove_via_api!
+ end
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'pushes code to the repository via SSH', :smoke do
+ Resource::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.ssh_key = @key
+ push.file_name = 'README.md'
+ push.file_content = '# Test Use SSH Key'
+ push.commit_message = 'Add README.md'
+ end.project.visit!
+
+ Page::Project::Show.perform do |project|
+ expect(project).to have_file('README.md')
+ expect(project).to have_readme_content('Test Use SSH Key')
+ end
+ end
+
+ it 'pushes multiple branches and tags together', :smoke do
+ branches = []
+ tags = []
+ Git::Repository.perform do |repository|
+ repository.uri = project.repository_ssh_location.uri
+ repository.use_ssh_key(@key)
+ repository.clone
+ repository.configure_identity('GitLab QA', 'root@gitlab.com')
+ 1.upto(3) do |i|
+ branches << "branch#{i}"
+ tags << "tag#{i}"
+ repository.checkout("branch#{i}", new_branch: true)
+ repository.commit_file("file#{i}", SecureRandom.random_bytes(10000), "Add file#{i}")
+ repository.add_tag("tag#{i}")
+ end
+ repository.push_tags_and_branches(branches)
+ end
+
+ expect(project).to have_branches(branches)
+ expect(project).to have_tags(tags)
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
index d67e4a4ea83..c5a07c69620 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
@@ -24,10 +24,10 @@ module QA
Page::Main::Menu.perform(&:click_settings_link)
Page::Profile::Menu.perform(&:click_ssh_keys)
Page::Profile::SSHKeys.perform do |ssh_keys|
- ssh_keys.remove_key(key_title)
+ ssh_keys.remove_key(key.title)
end
- expect(page).not_to have_content("Title: #{key_title}")
+ expect(page).not_to have_content("Title: #{key.title}")
expect(page).not_to have_content(key.md5_fingerprint)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb
deleted file mode 100644
index e91717b0f5f..00000000000
--- a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Create' do
- describe 'SSH key support' do
- # Note: If you run this test against GDK make sure you've enabled sshd
- # See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md
-
- let(:key_title) { "key for ssh tests #{Time.now.to_f}" }
-
- it 'user adds an ssh key and pushes code to the repository' do
- Flow::Login.sign_in
-
- key = Resource::SSHKey.fabricate_via_api! do |resource|
- resource.title = key_title
- end
-
- Resource::Repository::ProjectPush.fabricate! do |push|
- push.ssh_key = key
- push.file_name = 'README.md'
- push.file_content = '# Test Use SSH Key'
- push.commit_message = 'Add README.md'
- end.project.visit!
-
- expect(page).to have_content('README.md')
- expect(page).to have_content('Test Use SSH Key')
-
- Page::Main::Menu.perform(&:click_settings_link)
- Page::Profile::Menu.perform(&:click_ssh_keys)
-
- Page::Profile::SSHKeys.perform do |ssh_keys|
- ssh_keys.remove_key(key_title)
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
index e6589851dd9..ddbeb434955 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
@@ -87,7 +87,7 @@ module QA
repository.init_repository
expect { repository.pull(repository_uri_ssh, branch_name) }
- .to raise_error(QA::Git::Repository::RepositoryCommandError, /[fatal: Could not read from remote repository.]+/)
+ .to raise_error(QA::Git::Repository::RepositoryCommandError, /fatal: Could not read from remote repository\./)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
index 1660944fccd..dc1654b44c8 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
@@ -86,7 +86,7 @@ module QA
repository.init_repository
expect { repository.pull(repository_uri_ssh, branch_name) }
- .to raise_error(QA::Git::Repository::RepositoryCommandError, /[fatal: Could not read from remote repository.]+/)
+ .to raise_error(QA::Git::Repository::RepositoryCommandError, /fatal: Could not read from remote repository\./)
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
new file mode 100644
index 00000000000..ad7455242bc
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ describe 'Open a fork in Web IDE' do
+ let(:parent_project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'parent-project'
+ project.initialize_with_readme = true
+ end
+ end
+
+ context 'when a user does not have permissions to commit to the project' do
+ let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
+
+ context 'when no fork is present' do
+ it 'suggests to create a fork when a user clicks Web IDE in the main project' do
+ Flow::Login.sign_in(as: user)
+
+ parent_project.visit!
+ Page::Project::Show.perform(&:open_web_ide!)
+
+ Page::Project::WebIDE::Edit.perform(&:fork_project!)
+
+ submit_merge_request_upstream
+ end
+ end
+
+ context 'when a fork is already created' do
+ let(:fork_project) do
+ Resource::Fork.fabricate_via_api! do |fork|
+ fork.user = user
+ fork.upstream = parent_project
+ end
+ end
+
+ it 'opens the fork when a user clicks Web IDE in the main project' do
+ Flow::Login.sign_in(as: user)
+ fork_project.upstream.visit!
+ Page::Project::Show.perform do |project_page|
+ expect(project_page).to have_edit_fork_button
+
+ project_page.open_web_ide!
+ end
+
+ submit_merge_request_upstream
+ end
+ end
+
+ def submit_merge_request_upstream
+ Page::Project::WebIDE::Edit.perform do |ide|
+ expect(ide).to have_project_path("#{user.username}/#{parent_project.name}")
+
+ ide.add_file('new file', 'some random text')
+ ide.commit_changes(open_merge_request: true)
+ end
+
+ Page::MergeRequest::New.perform(&:create_merge_request)
+
+ parent_project.visit!
+ Page::Project::Menu.perform(&:click_merge_requests)
+ expect(page).to have_content('Update new file')
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb
new file mode 100644
index 00000000000..e0d54611731
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/project_based_directory_management_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Create' do
+ context 'Wiki' do
+ let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
+ let(:new_path) { "a/new/path" }
+
+ before do
+ Flow::Login.sign_in
+ end
+
+ it 'has changed the directory' do
+ initial_wiki.visit!
+
+ Page::Project::Wiki::Show.perform(&:click_edit)
+
+ Page::Project::Wiki::Edit.perform do |edit|
+ edit.set_title("#{new_path}/home")
+ edit.set_message('changing the path of the home page')
+ end
+
+ Page::Project::Wiki::Edit.perform(&:click_save_changes)
+
+ Page::Project::Wiki::Show.perform do |wiki|
+ expect(wiki).to have_directory(new_path)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
index 41baaa02544..fd342503a5c 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Verify', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/229724', type: :investigating } do
+ RSpec.describe 'Verify' do
describe 'Add or Remove CI variable via UI', :smoke do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/5_package/.gitkeep b/qa/qa/specs/features/browser_ui/5_package/.gitkeep
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/qa/qa/specs/features/browser_ui/5_package/.gitkeep
+++ /dev/null
diff --git a/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
new file mode 100644
index 00000000000..0f04b3b6186
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/maven_repository_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Package', :docker, :orchestrated, :packages do
+ describe 'Maven Repository' do
+ include Runtime::Fixtures
+
+ let(:group_id) { 'com.gitlab.qa' }
+ let(:artifact_id) { 'maven' }
+ let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
+ let(:auth_token) do
+ unless Page::Main::Menu.perform(&:signed_in?)
+ Flow::Login.sign_in
+ end
+
+ Resource::PersonalAccessToken.fabricate!.access_token
+ end
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'maven-package-project'
+ end
+ end
+
+ it 'publishes a maven package and deletes it' do
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ gitlab_address_with_port = "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ pom_xml = {
+ file_path: 'pom.xml',
+ content: <<~XML
+ <project>
+ <groupId>#{group_id}</groupId>
+ <artifactId>#{artifact_id}</artifactId>
+ <version>1.0</version>
+ <modelVersion>4.0.0</modelVersion>
+ <repositories>
+ <repository>
+ <id>#{project.name}</id>
+ <url>#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/maven</url>
+ </repository>
+ </repositories>
+ <distributionManagement>
+ <repository>
+ <id>#{project.name}</id>
+ <url>#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/maven</url>
+ </repository>
+ <snapshotRepository>
+ <id>#{project.name}</id>
+ <url>#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/maven</url>
+ </snapshotRepository>
+ </distributionManagement>
+ </project>
+ XML
+ }
+ settings_xml = {
+ file_path: 'settings.xml',
+ content: <<~XML
+ <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
+ <servers>
+ <server>
+ <id>#{project.name}</id>
+ <configuration>
+ <httpHeaders>
+ <property>
+ <name>Private-Token</name>
+ <value>#{auth_token}</value>
+ </property>
+ </httpHeaders>
+ </configuration>
+ </server>
+ </servers>
+ </settings>
+ XML
+ }
+
+ # Use a maven docker container to deploy the package
+ with_fixtures([pom_xml, settings_xml]) do |dir|
+ Service::DockerRun::Maven.new(dir).publish!
+ end
+
+ project.visit!
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package_name)
+
+ index.click_package(package_name)
+ end
+
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package_name, "1.0")
+
+ show.click_delete
+ end
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_content("Package was removed")
+ expect(index).to have_no_package(package_name)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
new file mode 100644
index 00000000000..471d66c2f21
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/npm_registry_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Package', :docker, :orchestrated, :packages do
+ describe 'NPM registry' do
+ include Runtime::Fixtures
+
+ let(:registry_scope) { project.group.sandbox.path }
+ let(:package_name) { "@#{registry_scope}/#{project.name}" }
+ let(:auth_token) do
+ unless Page::Main::Menu.perform(&:signed_in?)
+ Flow::Login.sign_in
+ end
+
+ Resource::PersonalAccessToken.fabricate!.access_token
+ end
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'npm-registry-project'
+ end
+ end
+
+ it 'publishes an npm package and then deletes it' do
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ gitlab_host_with_port = "#{uri.host}:#{uri.port}"
+ gitlab_address_with_port = "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ package_json = {
+ file_path: 'package.json',
+ content: <<~JSON
+ {
+ "name": "#{package_name}",
+ "version": "1.0.0",
+ "description": "Example package for GitLab NPM registry",
+ "publishConfig": {
+ "@#{registry_scope}:registry": "#{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/npm/"
+ }
+ }
+ JSON
+ }
+ npmrc = {
+ file_path: '.npmrc',
+ content: <<~NPMRC
+ //#{gitlab_host_with_port}/api/v4/projects/#{project.id}/packages/npm/:_authToken=#{auth_token}
+ //#{gitlab_host_with_port}/api/v4/packages/npm/:_authToken=#{auth_token}
+ @#{registry_scope}:registry=#{gitlab_address_with_port}/api/v4/packages/npm/
+ NPMRC
+ }
+
+ # Use a node docker container to publish the package
+ with_fixtures([npmrc, package_json]) do |dir|
+ Service::DockerRun::NodeJs.new(dir).publish!
+ end
+
+ project.visit!
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package_name)
+
+ index.click_package(package_name)
+ end
+
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package_name, "1.0.0")
+
+ show.click_delete
+ end
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_content("Package was removed")
+ expect(index).to have_no_package(package_name)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
index 673125c90f2..ba36e4fa290 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
@@ -8,6 +8,7 @@ module QA
project.name = 'pipelines-dependent-relationship'
end
end
+
let!(:runner) do
Resource::Runner.fabricate_via_api! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
index 05b9859f112..69f66ee4edf 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
@@ -8,6 +8,7 @@ module QA
project.name = 'pipeline-independent-relationship'
end
end
+
let!(:runner) do
Resource::Runner.fabricate_via_api! do |runner|
runner.project = project
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index ad87ee173f5..3e25ecfd45d 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -15,7 +15,7 @@ module QA
disable_optional_jobs(project)
end
- describe 'Auto DevOps support', :orchestrated, :kubernetes do
+ describe 'Auto DevOps support', :orchestrated, :kubernetes, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/230927', type: :stale } do
context 'when rbac is enabled' do
let(:cluster) { Service::KubernetesCluster.new.create! }
@@ -38,7 +38,6 @@ module QA
Resource::KubernetesCluster::ProjectCluster.fabricate! do |k8s_cluster|
k8s_cluster.project = project
k8s_cluster.cluster = cluster
- k8s_cluster.install_helm_tiller = true
k8s_cluster.install_ingress = true
k8s_cluster.install_prometheus = true
k8s_cluster.install_runner = true
diff --git a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
index 9cfdc4277a7..54c7b75d1d1 100644
--- a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
+++ b/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb
@@ -2,12 +2,13 @@
module QA
RSpec.describe 'Monitor' do
- describe 'with Prometheus in a Gitlab-managed cluster', :orchestrated, :kubernetes do
+ describe 'with Prometheus in a Gitlab-managed cluster', :orchestrated, :kubernetes, :requires_admin do
before :all do
- @cluster = Service::KubernetesCluster.new.create!
+ @cluster = Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3s).create!
@project = Resource::Project.fabricate_via_api! do |project|
project.name = 'monitoring-project'
project.auto_devops_enabled = true
+ project.template_name = 'express'
end
deploy_project_with_prometheus
@@ -83,7 +84,7 @@ module QA
%w[
CODE_QUALITY_DISABLED TEST_DISABLED LICENSE_MANAGEMENT_DISABLED
SAST_DISABLED DAST_DISABLED DEPENDENCY_SCANNING_DISABLED
- CONTAINER_SCANNING_DISABLED PERFORMANCE_DISABLED
+ CONTAINER_SCANNING_DISABLED PERFORMANCE_DISABLED SECRET_DETECTION_DISABLED
].each do |key|
Resource::CiVariable.fabricate_via_api! do |resource|
resource.project = @project
@@ -98,22 +99,14 @@ module QA
Resource::KubernetesCluster::ProjectCluster.fabricate! do |cluster_settings|
cluster_settings.project = @project
cluster_settings.cluster = @cluster
- cluster_settings.install_helm_tiller = true
cluster_settings.install_runner = true
cluster_settings.install_ingress = true
cluster_settings.install_prometheus = true
end
- Resource::Repository::ProjectPush.fabricate! do |push|
- push.project = @project
- push.directory = Pathname
- .new(__dir__)
- .join('../../../../fixtures/auto_devops_rack')
- push.commit_message = 'Create AutoDevOps compatible Project for Monitoring'
- end
-
- Page::Project::Menu.perform(&:click_ci_cd_pipelines)
- Page::Project::Pipeline::Index.perform(&:click_on_latest_pipeline)
+ Resource::Pipeline.fabricate_via_api! do |pipeline|
+ pipeline.project = @project
+ end.visit!
Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.click_job('build')