diff options
Diffstat (limited to 'qa/qa/specs')
31 files changed, 685 insertions, 349 deletions
diff --git a/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb index 799a5f7eaf2..a6655471591 100644 --- a/qa/qa/specs/features/api/1_manage/bulk_import_group_spec.rb +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true module QA - # run only base UI validation on staging because test requires top level group creation which is problematic - # on staging environment - RSpec.describe 'Manage', :requires_admin, except: { subdomain: :staging } do + RSpec.describe 'Manage', :requires_admin do describe 'Gitlab migration' do let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } } let(:admin_api_client) { Runtime::API::Client.as_admin } @@ -22,9 +20,18 @@ module QA end end + let(:destination_group) do + Resource::Group.fabricate_via_api! do |group| + group.api_client = api_client + group.sandbox = sandbox + group.path = "destination-group-for-import-#{SecureRandom.hex(4)}" + end + end + let(:source_group) do - Resource::Sandbox.fabricate_via_api! do |group| + Resource::Group.fabricate_via_api! do |group| group.api_client = api_client + group.sandbox = sandbox group.path = "source-group-for-import-#{SecureRandom.hex(4)}" group.avatar = File.new('qa/fixtures/designs/tanuki.jpg', 'r') end @@ -33,8 +40,8 @@ module QA let(:imported_group) do Resource::BulkImportGroup.fabricate_via_api! do |group| group.api_client = api_client - group.sandbox = sandbox - group.source_group_path = source_group.path + group.sandbox = destination_group + group.source_group = source_group end end @@ -167,7 +174,6 @@ module QA expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration) imported_member = imported_group.reload!.members.find { |usr| usr.username == member.username } - aggregate_failures do expect(imported_member).not_to be_nil expect(imported_member.access_level).to eq(Resource::Members::AccessLevel::DEVELOPER) diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb new file mode 100644 index 00000000000..8a2a382ac45 --- /dev/null +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_issue_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require_relative 'gitlab_project_migration_common' + +module QA + RSpec.describe 'Manage', :requires_admin do + describe 'Gitlab migration', quarantine: { + only: { job: 'praefect' }, + type: :investigating, + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999' + } do + include_context 'with gitlab project migration' + + context 'with project issues' do + let!(:source_issue) do + Resource::Issue.fabricate_via_api! do |issue| + issue.api_client = api_client + issue.project = source_project + issue.labels = %w[label_one label_two] + end + end + + let!(:source_comment) { source_issue.add_comment(body: 'This is a test comment!') } + + let(:imported_issues) { imported_projects.first.issues } + + let(:imported_issue) do + issue = imported_issues.first + Resource::Issue.init do |resource| + resource.api_client = api_client + resource.project = imported_projects.first + resource.iid = issue[:iid] + end + end + + let(:imported_comments) { imported_issue.comments } + + it( + 'successfully imports issue', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347608' + ) do + expect_import_finished + + aggregate_failures do + expect(imported_issues.count).to eq(1) + expect(imported_issue).to eq(source_issue.reload!) + + expect(imported_comments.count).to eq(1) + expect(imported_comments.first[:body]).to include(source_comment[:body]) + end + end + end + end + end +end 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 new file mode 100644 index 00000000000..9dce9bff3c1 --- /dev/null +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_mr_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require_relative 'gitlab_project_migration_common' + +module QA + RSpec.describe 'Manage', :requires_admin do + describe 'Gitlab migration', quarantine: { + only: { job: 'praefect' }, + type: :investigating, + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999' + } do + include_context 'with gitlab project migration' + + context 'with merge request' do + let!(:source_project_with_readme) { true } + + let!(:other_user) do + Resource::User + .fabricate_via_api! { |usr| usr.api_client = admin_api_client } + .tap do |usr| + usr.set_public_email + source_project.add_member(usr, Resource::Members::AccessLevel::MAINTAINER) + end + end + + let!(:source_mr) do + Resource::MergeRequest.fabricate_via_api! do |mr| + mr.project = source_project + mr.api_client = Runtime::API::Client.new(user: other_user) + end + end + + let!(:source_comment) { source_mr.add_comment('This is a test comment!') } + + let(:imported_mrs) { imported_project.merge_requests } + let(:imported_mr_comments) { imported_mr.comments } + + let(:imported_mr) do + Resource::MergeRequest.init do |mr| + mr.project = imported_project + mr.iid = imported_mrs.first[:iid] + mr.api_client = api_client + end + end + + after do + other_user.remove_via_api! + end + + it( + 'successfully imports merge request', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348478' + ) do + expect_import_finished + + aggregate_failures do + expect(imported_mrs.count).to eq(1) + # TODO: remove custom comparison after member migration is implemented + # https://gitlab.com/gitlab-org/gitlab/-/issues/341886 + expect(imported_mr.comparable.except(:author)).to eq(source_mr.reload!.comparable.except(:author)) + + expect(imported_mr_comments.count).to eq(1) + expect(imported_mr_comments.first[:body]).to include(source_comment[:body]) + # Comment will have mention of original user since members are not migrated yet + expect(imported_mr_comments.first[:body]).to include(other_user.name) + end + end + end + end + end +end 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 new file mode 100644 index 00000000000..a0c758c99e6 --- /dev/null +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require_relative 'gitlab_project_migration_common' + +module QA + RSpec.describe 'Manage', :requires_admin do + describe 'Gitlab migration', quarantine: { + only: { job: 'praefect' }, + type: :investigating, + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999' + } do + include_context 'with gitlab project migration' + + context 'with uninitialized project' do + it( + 'successfully imports project', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347610' + ) do + expect_import_finished + + expect(imported_projects.first).to eq(source_project) + end + end + + context 'with repository' do + let(:source_project_with_readme) { true } + let(:source_commits) { source_project.commits.map { |c| c.except(:web_url) } } + let(:source_tags) do + source_project.repository_tags.tap do |tags| + tags.each { |t| t[:commit].delete(:web_url) } + end + end + + let(:source_branches) do + source_project.repository_branches.tap do |branches| + branches.each do |b| + b.delete(:web_url) + b[:commit].delete(:web_url) + end + end + end + + let(:imported_commits) { imported_project.commits.map { |c| c.except(:web_url) } } + let(:imported_tags) do + imported_project.repository_tags.tap do |tags| + tags.each { |t| t[:commit].delete(:web_url) } + end + end + + let(:imported_branches) do + imported_project.repository_branches.tap do |branches| + branches.each do |b| + b.delete(:web_url) + b[:commit].delete(:web_url) + end + end + end + + before do + source_project.create_repository_branch('test-branch') + source_project.create_repository_tag('v0.0.1') + end + + it( + 'successfully imports repository', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347570' + ) do + expect_import_finished + + aggregate_failures do + expect(imported_commits).to match_array(source_commits) + expect(imported_tags).to match_array(source_tags) + expect(imported_branches).to match_array(source_branches) + end + end + end + + context 'with wiki' do + before do + source_project.create_wiki_page(title: 'Import test project wiki', content: 'Wiki content') + end + + it( + 'successfully imports project wiki', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347567' + ) do + expect_import_finished + + expect(imported_projects.first.wikis).to eq(source_project.wikis) + end + end + end + end +end diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb new file mode 100644 index 00000000000..827ebc1f5e2 --- /dev/null +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module QA + RSpec.shared_context 'with gitlab project migration' do + let(:source_project_with_readme) { false } + let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } } + let(:admin_api_client) { Runtime::API::Client.as_admin } + let(:user) do + Resource::User.fabricate_via_api! do |usr| + usr.api_client = admin_api_client + usr.hard_delete_on_api_removal = true + end + end + + let(:api_client) { Runtime::API::Client.new(user: user) } + + let(:sandbox) do + Resource::Sandbox.fabricate_via_api! do |group| + group.api_client = admin_api_client + end + end + + let(:destination_group) do + Resource::Group.fabricate_via_api! do |group| + group.api_client = api_client + group.sandbox = sandbox + group.path = "destination-group-for-import-#{SecureRandom.hex(4)}" + end + end + + let(:source_group) do + Resource::Group.fabricate_via_api! do |group| + group.api_client = api_client + group.path = "source-group-for-import-#{SecureRandom.hex(4)}" + end + end + + let(:source_project) do + Resource::Project.fabricate_via_api! do |project| + project.api_client = api_client + project.group = source_group + project.initialize_with_readme = source_project_with_readme + end + end + + let(:imported_group) do + Resource::BulkImportGroup.fabricate_via_api! do |group| + group.api_client = api_client + group.sandbox = destination_group + group.source_group = source_group + end + end + + let(:imported_projects) { imported_group.reload!.projects } + let(:imported_project) { imported_projects.first } + + let(:import_failures) do + imported_group.import_details.sum([]) { |details| details[:failures] } + end + + def expect_import_finished + imported_group # trigger import + + expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration) + expect(imported_projects.count).to eq(1), 'Expected to have 1 imported project' + end + + before do + Runtime::Feature.enable(:bulk_import_projects) + + sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER) + source_project # fabricate source group and project + end + + after do |example| + # Checking for failures in the test currently makes test very flaky + # Just log in case of failure until cause of network errors is found + Runtime::Logger.warn("Import failures: #{import_failures}") if example.exception && !import_failures.empty? + + user.remove_via_api! + ensure + Runtime::Feature.disable(:bulk_import_projects) + end + end +end diff --git a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb index e47e5d22e5e..6a31d173440 100644 --- a/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb +++ b/qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb @@ -37,7 +37,7 @@ module QA push.file_name = 'test.txt' push.file_content = "# This is a test project named #{@project.name}" push.commit_message = 'Add test.txt' - push.branch_name = 'new_branch' + push.branch_name = "new_branch_#{SecureRandom.hex(8)}" push.user = @user end end.to raise_error(QA::Support::Run::CommandError, /You are not allowed to push code to this project/) @@ -48,7 +48,7 @@ module QA Resource::File.fabricate_via_api! do |file| file.api_client = @user_api_client file.project = @project - file.branch = 'new_branch' + file.branch = "new_branch_#{SecureRandom.hex(8)}" file.commit_message = 'Add new file' file.name = 'test.txt' file.content = "New file" @@ -61,7 +61,7 @@ module QA Resource::Repository::Commit.fabricate_via_api! do |commit| commit.api_client = @user_api_client commit.project = @project - commit.branch = 'new_branch' + commit.branch = "new_branch_#{SecureRandom.hex(8)}" commit.start_branch = @project.default_branch commit.commit_message = 'Add new file' commit.add_files([ 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 index 51927a30987..6a9be19efdd 100644 --- 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 @@ -49,7 +49,6 @@ module QA # for Gitaly to be ready for writes again praefect_manager.stop_primary_node praefect_manager.wait_for_primary_node_health_check_failure - praefect_manager.wait_for_gitaly_check Resource::Repository::Commit.fabricate_via_api! do |commit| commit.project = project diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb new file mode 100644 index 00000000000..28469b99d04 --- /dev/null +++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Create' do + context 'Praefect connectivity commands', :orchestrated, :gitaly_cluster do + praefect_manager = Service::PraefectManager.new + + before do + praefect_manager.start_all_nodes + end + + context 'in a healthy environment' do + it 'confirms healthy connection to database', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349937' do + expect(praefect_manager.praefect_sql_ping_healthy?).to be true + end + + it 'confirms healthy connection to gitaly nodes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349938' do + expect(praefect_manager.wait_for_dial_nodes_successful).to be true + end + end + + context 'in an unhealthy environment' do + it 'diagnoses unhealthy connection to database', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349939' do + praefect_manager.stop_node(praefect_manager.postgres) + expect(praefect_manager.praefect_sql_ping_healthy?).to be false + end + + it 'diagnoses connection issues to gitaly nodes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349940' do + praefect_manager.stop_node(praefect_manager.primary_node) + praefect_manager.stop_node(praefect_manager.tertiary_node) + expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.primary_node, false)).to be true + expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.secondary_node)).to be true + expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.tertiary_node, false)).to be true + + praefect_manager.stop_node(praefect_manager.secondary_node) + expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.secondary_node, false)).to be true + end + end + end + end +end diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb index cc49e408954..e27f37abedf 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb +++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - context 'Praefect repository commands', :orchestrated, :gitaly_cluster, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/347415', type: :investigating } do + context 'Praefect repository commands', :orchestrated, :gitaly_cluster do let(:praefect_manager) { Service::PraefectManager.new } let(:repo1) { { "relative_path" => "@hashed/repo1.git", "storage" => "gitaly1", "virtual_storage" => "default" } } @@ -59,6 +59,18 @@ module QA 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/browser_ui/1_manage/group/bulk_import_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb index 74125b092b8..a18e22f52f1 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/group/bulk_import_group_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/group/gitlab_migration_group_spec.rb @@ -1,9 +1,8 @@ # frozen_string_literal: true module QA - RSpec.describe 'Manage', :requires_admin do - describe 'Bulk group import' do - let!(:staging?) { Runtime::Scenario.gitlab_address.include?('staging.gitlab.com') } + describe 'Manage', :requires_admin do + describe 'Gitlab migration' do let!(:admin_api_client) { Runtime::API::Client.as_admin } let!(:user) do Resource::User.fabricate_via_api! do |usr| @@ -32,7 +31,7 @@ module QA Resource::BulkImportGroup.init do |group| group.api_client = api_client group.sandbox = sandbox - group.source_group_path = source_group.path + group.source_group = source_group 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 16f8df5a90d..098c0b3ba63 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 @@ -64,6 +64,7 @@ module QA Page::Profile::Accounts::Show.perform do |show| show.delete_account(user.password) end + Support::Waiter.wait_until { !user.exists? } end it 'allows recreating with same credentials', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347868' do @@ -83,7 +84,7 @@ module QA end after do - @recreated_user.remove_via_api! + @recreated_user&.remove_via_api! end def admin_api_client @@ -117,11 +118,12 @@ module QA Flow::Login.sign_in(as: @user, skip_page_validation: true) - Page::Registration::Welcome.perform(&:click_get_started_button_if_available) + Flow::UserOnboarding.onboard_user - Page::Main::Menu.perform do |menu| - expect(menu).to have_personal_area - end + # In development env and .com the user is asked to create a group and a project which can be skipped for + # the purpose of this test + Runtime::Browser.visit(:gitlab, Page::Dashboard::Welcome) + Page::Main::Menu.perform(&:has_personal_area?) end after do diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb index 6d09c8b1316..895027a588d 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb @@ -1,7 +1,11 @@ # frozen_string_literal: true module QA - RSpec.describe 'Manage', :requires_admin do + RSpec.describe 'Manage', :requires_admin, quarantine: { + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/350598', + type: :needs_update, + only: { subdomain: :staging } + } do describe 'Add project member' do before do Runtime::Feature.enable(:invite_members_group_modal) diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb index 7f40818da03..0063ce2613a 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Manage', :smoke do - describe 'Project', :requires_admin do + describe 'Project' do shared_examples 'successful project creation' do it 'creates a new project' do Page::Project::Show.perform do |project_page| @@ -17,7 +17,6 @@ module QA end before do - Runtime::Feature.enable(:paginatable_namespace_drop_down_for_project_creation) Flow::Login.sign_in project end diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb new file mode 100644 index 00000000000..6997447411a --- /dev/null +++ b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module QA + # Tagging with issue for a transient invite group modal search bug, but does not require quarantine at this time + RSpec.describe 'Manage', :requires_admin, :transient, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/349379' do + describe 'Invite group' do + shared_examples 'invites group to project' do + it 'verifies group is added and members can access project with correct access level' do + Page::Project::Menu.perform(&:click_members) + Page::Project::Members.perform do |project_members| + project_members.invite_group(group.path, 'Developer') + + expect(project_members).to have_group(group.path) + end + + Flow::Login.sign_in(as: @user) + + Page::Dashboard::Projects.perform do |projects| + expect(projects).to have_project_with_access_role(project.name, 'Developer') + end + + project.visit! + + Page::Project::Show.perform do |project_page| + expect(project_page).to have_name(project.name) + end + end + end + + before(:context) do + Runtime::Feature.enable(:invite_members_group_modal) + @user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) + end + + before do + Flow::Login.sign_in + group.add_member(@user, Resource::Members::AccessLevel::MAINTAINER) + project.visit! + end + + context 'to personal namespace project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do + let(:group) do + Resource::Group.fabricate_via_api! do |group| + group.path = "group-for-personal-project-#{SecureRandom.hex(8)}" + end + end + + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'personal-namespace-project' + project.personal_namespace = Runtime::User.username + project.visibility = :private + project.description = 'test personal namespace project' + end + end + + it_behaves_like 'invites group to project' + end + + context 'to group project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349340' do + let(:group) do + Resource::Group.fabricate_via_api! do |group| + group.path = "group-for-group-project-#{SecureRandom.hex(8)}" + end + end + + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'group-project' + project.visibility = :private + project.description = 'test group project' + end + end + + it_behaves_like 'invites group to project' + end + + after do + project&.remove_via_api! + group&.remove_via_api! + end + + after(:context) do + Runtime::Feature.disable(:invite_members_group_modal) + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb index be8567ee0b6..c2bd61155b1 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/project_access_token_spec.rb @@ -9,7 +9,7 @@ module QA expect(project_access_token.token).not_to be_nil project_access_token.revoke_via_ui! - expect(page).to have_text("Revoked project access token #{project_access_token.name}!") + expect(page).to have_text("Revoked access token #{project_access_token.name}!") end after do diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb index 43100929acd..87b51edef08 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/user/follow_user_activity_spec.rb @@ -19,7 +19,7 @@ module QA group = QA::Resource::Group.fabricate_via_api! do |group| group.path = "group_for_follow_user_activity_#{SecureRandom.hex(8)}" end - group.add_member(user) + group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) group end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb index d198d79c5fe..b0c6d01e8ca 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb @@ -2,7 +2,11 @@ module QA RSpec.describe 'Create' do - describe 'Merge request creation from fork' do + describe 'Merge request creation from fork', quarantine: { + only: { subdomain: %i[canary production] }, + issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/343801", + type: :investigation + } do let(:merge_request) do Resource::MergeRequestFromFork.fabricate_via_browser_ui! do |merge_request| merge_request.fork_branch = 'feature-branch' diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb deleted file mode 100644 index 0785b32b225..00000000000 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/view_merge_request_merge_ref_diff_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Create', :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/261793', type: :investigating } do - describe 'View merge request merge-ref diff' do - let(:project) do - Resource::Project.fabricate_via_api! do |project| - project.name = 'merge-ref-diff' - end - end - - let(:merge_request) do - Resource::MergeRequest.fabricate_via_api! do |merge_request| - merge_request.project = project - merge_request.title = 'This is a merge request' - merge_request.description = '... for viewing merge-ref and merge-base diffs' - merge_request.file_content = 'This exists on the source branch only' - end - end - - let(:new_file_name) { "added_file-#{SecureRandom.hex(8)}.txt" } - - context 'when the feature flag default_merge_ref_for_diffs is enabled' do - before do - Runtime::Feature.enable('default_merge_ref_for_diffs', project: project) - - commit_to_branch(merge_request.target_branch, new_file_name) - commit_to_branch(merge_request.source_branch, new_file_name) - - Flow::Login.sign_in - - merge_request.visit! - end - - it 'views the merge-ref diff by default', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347651' do - Page::MergeRequest::Show.perform do |mr_page| - mr_page.click_diffs_tab - mr_page.click_target_version_dropdown - - expect(mr_page.version_dropdown_content).to include("#{project.default_branch} (HEAD)") - expect(mr_page.version_dropdown_content).not_to include("#{project.default_branch} (base)") - expect(mr_page).to have_file(merge_request.file_name) - expect(mr_page).not_to have_file(new_file_name) - end - end - end - - context 'when the feature flag default_merge_ref_for_diffs is disabled' do - before do - Runtime::Feature.disable('default_merge_ref_for_diffs', project: project) - - commit_to_branch(merge_request.target_branch, new_file_name) - commit_to_branch(merge_request.source_branch, new_file_name) - - Flow::Login.sign_in - - merge_request.visit! - end - - it 'views the merge-base diff by default', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347650' do - Page::MergeRequest::Show.perform do |mr_page| - mr_page.click_diffs_tab - mr_page.click_target_version_dropdown - - expect(mr_page.version_dropdown_content).to include("#{project.default_branch} (HEAD)") - expect(mr_page.version_dropdown_content).to include("#{project.default_branch} (base)") - expect(mr_page).to have_file(merge_request.file_name) - expect(mr_page).to have_file(new_file_name) - end - end - end - - def commit_to_branch(branch, file) - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = merge_request.project - commit.branch = branch - commit.commit_message = "Add new file on #{branch}" - commit.add_files( - [ - { - file_path: file, - content: "This exists on source and target branches" - } - ] - ) - end - end - end - 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 index a98925eab98..0bd470fcb77 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb @@ -24,8 +24,6 @@ module QA proj.initialize_with_readme = true end - Runtime::Feature.enable(:delete_branch_confirmation_modals, project: project) - master_branch = project.default_branch Git::Repository.perform do |repository| diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb index a063acbe146..67eee66b3d6 100644 --- a/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/wiki/content_editor_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', :requires_admin do # remove :requires_admin once the ff is enabled by default in https://gitlab.com/gitlab-org/gitlab/-/issues/345398 + RSpec.describe 'Create', :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/350220', type: :investigating } do # remove :requires_admin once the ff is enabled by default in https://gitlab.com/gitlab-org/gitlab/-/issues/345398 context 'Content Editor' do let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! } let(:page_title) { 'Content Editor Page' } diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb new file mode 100644 index 00000000000..8f3284662d7 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Verify' do + describe 'Pipeline editor' 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 + + before do + Flow::Login.sign_in + project.visit! + Page::Project::Menu.perform(&:go_to_pipeline_editor) + end + + after do + project&.remove_via_api! + end + + context 'when CI has valid syntax' do + it 'shows valid validations', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349128' do + Page::Project::PipelineEditor::Show.perform do |show| + aggregate_failures do + expect(show.ci_syntax_validate_message).to have_content('CI configuration is valid') + + 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_lint_tab + expect(show.tab_alert_message).to have_content('Syntax is correct') + + show.go_to_view_merged_yaml_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/349129' do + invalid_msg = 'syntax is invalid' + + Page::Project::PipelineEditor::Show.perform do |show| + show.write_to_editor(SecureRandom.hex(10)) + + aggregate_failures do + show.go_to_visualize_tab + expect(show.tab_alert_message).to have_content(invalid_msg) + + show.go_to_lint_tab + expect(show.tab_alert_message).to have_content('Syntax is incorrect') + + show.go_to_view_merged_yaml_tab + expect(show.tab_alert_message).to have_content(invalid_msg) + + 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/update_ci_file_with_pipeline_editor_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb new file mode 100644 index 00000000000..00c5d4c74d4 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/update_ci_file_with_pipeline_editor_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Verify' do + describe 'Update CI file with pipeline editor' do + let(:random_test_string) { SecureRandom.hex(10) } + + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'pipeline-editor-project' + end + end + + let!(:runner) do + Resource::Runner.fabricate_via_api! do |runner| + runner.project = project + runner.name = random_test_string + runner.tags = [random_test_string] + 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 + test_job: + tags: ['#{random_test_string}'] + script: + - echo "Simple test!" + YAML + } + ] + ) + end + end + + before do + Flow::Login.sign_in + project.visit! + Support::Waiter.wait_until { !project.pipelines.empty? && project.pipelines.first[:status] == 'success' } + Page::Project::Menu.perform(&:go_to_pipeline_editor) + end + + after do + [runner, project].each(&:remove_via_api!) + end + + it 'creates new pipeline and target branch', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349005' do + Page::Project::PipelineEditor::Show.perform do |show| + show.write_to_editor(random_test_string) + show.set_target_branch(random_test_string) + show.submit_changes + + Support::Waiter.wait_until { project.pipelines.size > 1 } + + aggregate_failures do + expect(show.target_branch_name).to eq(random_test_string) + expect(show.current_branch).to eq(random_test_string) + expect(show.editing_content).to have_content(random_test_string) + expect { show.pipeline_id }.to eventually_eq(project.pipelines.pluck(:id).max).within(max_duration: 60, sleep_interval: 3) + end + end + + expect(project).to have_branch(random_test_string) + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb index e8d936e67b1..56e3ec82388 100644 --- a/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/online_garbage_collection_spec.rb @@ -2,8 +2,7 @@ module QA RSpec.describe 'Package' do - # TODO: Remove :requires_admin when the `Runtime::Feature.enable` method call is removed - describe 'Container Registry Online Garbage Collection', :registry_gc, :requires_admin, only: { subdomain: %i[pre] } do + describe 'Container Registry Online Garbage Collection', :registry_gc, only: { subdomain: %i[pre] } do let(:group) { Resource::Group.fabricate_via_api! } let(:imported_project) do @@ -65,8 +64,6 @@ module QA end before do - Runtime::Feature.enable(:paginatable_namespace_drop_down_for_project_creation) - Flow::Login.sign_in imported_project diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb index c58cdec622d..70b31c1beca 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do + RSpec.describe 'Package Registry', :orchestrated, :packages, :object_storage do describe 'npm instance level endpoint' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb index cec902e073a..e25a742493b 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Package Registry', :orchestrated, :packages, :reliable, :object_storage do + RSpec.describe 'Package Registry', :orchestrated, :packages, :object_storage do describe 'npm project level endpoint' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures 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 74a81ff429d..ef0c8d35c37 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 @@ -13,7 +13,7 @@ module QA Resource::Runner.fabricate_via_api! do |runner| runner.project = project runner.name = project.name - runner.tags = ["#{project.name}"] + runner.tags = [project.name] end end diff --git a/qa/qa/specs/features/browser_ui/8_monitor/.gitkeep b/qa/qa/specs/features/browser_ui/8_monitor/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/qa/qa/specs/features/browser_ui/8_monitor/.gitkeep 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 deleted file mode 100644 index c13d2d2dddf..00000000000 --- a/qa/qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb +++ /dev/null @@ -1,142 +0,0 @@ -# frozen_string_literal: true -require_relative 'cluster_with_prometheus' - -module QA - RSpec.describe 'Monitor', :orchestrated, :kubernetes, :requires_admin, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/241448', type: :investigating } do - include_context "cluster with Prometheus installed" - - before do - Flow::Login.sign_in_unless_signed_in - @project.visit! - end - - it 'configures custom metrics', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348082' do - verify_add_custom_metric - verify_edit_custom_metric - verify_delete_custom_metric - end - - it 'duplicates to create dashboard to custom', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348070' do - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |on_dashboard| - on_dashboard.duplicate_dashboard - - expect(on_dashboard).to have_metrics - expect(on_dashboard).to have_edit_dashboard_enabled - end - end - - it 'verifies data on filtered deployed environment', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348071' do - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |on_dashboard| - on_dashboard.filter_environment - - expect(on_dashboard).to have_metrics - end - end - - it 'filters using the quick range', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348083' do - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |on_dashboard| - on_dashboard.show_last('30 minutes') - expect(on_dashboard).to have_metrics - - on_dashboard.show_last('3 hours') - expect(on_dashboard).to have_metrics - - on_dashboard.show_last('1 day') - expect(on_dashboard).to have_metrics - end - end - - it 'observes cluster health graph', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348074' do - Page::Project::Menu.perform(&:go_to_infrastructure_kubernetes) - - Page::Project::Infrastructure::Kubernetes::Index.perform do |cluster_list| - cluster_list.click_on_cluster(@cluster) - end - - Page::Project::Infrastructure::Kubernetes::Show.perform do |cluster_panel| - cluster_panel.open_health - cluster_panel.wait_for_cluster_health - end - end - - it 'uses templating variables for metrics dashboards', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347636' do - templating_dashboard_yml = Pathname - .new(__dir__) - .join('../../../../fixtures/metrics_dashboards/templating.yml') - - Resource::Repository::ProjectPush.fabricate! do |push| - push.project = @project - push.file_name = '.gitlab/dashboards/templating.yml' - push.file_content = File.read(templating_dashboard_yml) - push.commit_message = 'Add templating in dashboard file' - push.new_branch = false - end - - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |dashboard| - dashboard.select_dashboard('templating.yml') - - expect(dashboard).to have_template_metric('CPU usage GitLab Runner') - expect(dashboard).to have_template_metric('Memory usage Postgresql') - expect(dashboard).to have_templating_variable('GitLab Runner') - expect(dashboard).to have_templating_variable('Postgresql') - end - end - - private - - def verify_add_custom_metric - Page::Project::Menu.perform(&:go_to_integrations_settings) - Page::Project::Settings::Integrations.perform(&:click_on_prometheus_integration) - - Page::Project::Settings::Services::Prometheus.perform do |metrics_panel| - metrics_panel.click_on_new_metric - metrics_panel.add_custom_metric - end - - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |on_dashboard| - expect(on_dashboard).to have_custom_metric('HTTP Requests Total') - end - end - - def verify_edit_custom_metric - Page::Project::Menu.perform(&:go_to_integrations_settings) - Page::Project::Settings::Integrations.perform(&:click_on_prometheus_integration) - Page::Project::Settings::Services::Prometheus.perform do |metrics_panel| - metrics_panel.click_on_custom_metric('Business / HTTP Requests Total (req/sec)') - metrics_panel.edit_custom_metric - end - - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |on_dashboard| - expect(on_dashboard).to have_custom_metric('Throughput') - end - end - - def verify_delete_custom_metric - Page::Project::Menu.perform(&:go_to_integrations_settings) - Page::Project::Settings::Integrations.perform(&:click_on_prometheus_integration) - - Page::Project::Settings::Services::Prometheus.perform do |metrics_panel| - metrics_panel.click_on_custom_metric('Business / Throughput (req/sec)') - metrics_panel.delete_custom_metric - end - - Page::Project::Menu.perform(&:go_to_monitor_metrics) - - Page::Project::Monitor::Metrics::Show.perform do |on_dashboard| - expect(on_dashboard).not_to have_custom_metric('Throughput') - end - end - end -end diff --git a/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb b/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb deleted file mode 100644 index 19e49400d5e..00000000000 --- a/qa/qa/specs/features/browser_ui/8_monitor/cluster_with_prometheus.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.shared_context "cluster with Prometheus installed" do - before :all do - @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 - end - - def deploy_project_with_prometheus - %w[ - CODE_QUALITY_DISABLED TEST_DISABLED LICENSE_MANAGEMENT_DISABLED - SAST_DISABLED DAST_DISABLED DEPENDENCY_SCANNING_DISABLED - CONTAINER_SCANNING_DISABLED BROWSER_PERFORMANCE_DISABLED SECRET_DETECTION_DISABLED - ].each do |key| - Resource::CiVariable.fabricate_via_api! do |resource| - resource.project = @project - resource.key = key - resource.value = '1' - resource.masked = false - end - end - - Flow::Login.sign_in - - Resource::KubernetesCluster::ProjectCluster.fabricate! do |cluster_settings| - cluster_settings.project = @project - cluster_settings.cluster = @cluster - cluster_settings.install_runner = true - cluster_settings.install_ingress = true - cluster_settings.install_prometheus = true - end - - Resource::Pipeline.fabricate_via_api! do |pipeline| - pipeline.project = @project - end.visit! - - 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: 600) - - job.click_element(:pipeline_path) - end - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('production') - end - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 1200) - - job.click_element(:pipeline_path) - end - end - - after :all do - @cluster&.remove! - end - end -end diff --git a/qa/qa/specs/helpers/quarantine.rb b/qa/qa/specs/helpers/quarantine.rb index 49d91fc87cd..738c99efb28 100644 --- a/qa/qa/specs/helpers/quarantine.rb +++ b/qa/qa/specs/helpers/quarantine.rb @@ -11,9 +11,9 @@ module QA extend self # Skip tests in quarantine unless we explicitly focus on them. - def skip_or_run_quarantined_tests_or_contexts(filters, example) + def skip_or_run_quarantined_tests_or_contexts(example) if filters.key?(:quarantine) - included_filters = filters_other_than_quarantine(filters) + included_filters = filters_other_than_quarantine # If :quarantine is focused, skip the test/context unless its metadata # includes quarantine and any other filters @@ -29,18 +29,17 @@ module QA elsif example.metadata.key?(:quarantine) quarantine_tag = example.metadata[:quarantine] - if quarantine_tag.is_a?(Hash) && quarantine_tag&.key?(:only) && !ContextSelector.context_matches?(quarantine_tag[:only]) - # If the :quarantine hash contains :only, we respect that. - # For instance `quarantine: { only: { subdomain: :staging } }` will only quarantine the test when it runs against staging. - return - end + # If the :quarantine hash contains :only, we respect that. + # For instance `quarantine: { only: { subdomain: :staging } }` + # will only quarantine the test when it runs against staging. + return if quarantined_different_context?(quarantine_tag) example.metadata[:skip] = quarantine_message(quarantine_tag) end end - def filters_other_than_quarantine(filter) - filter.reject { |key, _| key == :quarantine } + def filters_other_than_quarantine + filters.reject { |key, _| key == :quarantine } end def quarantine_message(quarantine_tag) @@ -70,6 +69,14 @@ module QA (metadata.keys & included_filters.keys).empty? end + + def quarantined_different_context?(quarantine) + quarantine.is_a?(Hash) && quarantine.key?(:only) && !ContextSelector.context_matches?(quarantine[:only]) + end + + def filters + @filters ||= ::RSpec.configuration.inclusion_filter.rules + end end end end diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb index d7d64834e7a..2c9e302fc56 100644 --- a/qa/qa/specs/runner.rb +++ b/qa/qa/specs/runner.rb @@ -9,6 +9,7 @@ module QA attr_accessor :tty, :tags, :options DEFAULT_TEST_PATH_ARGS = ['--', File.expand_path('./features', __dir__)].freeze + DEFAULT_STD_ARGS = [$stderr, $stdout].freeze def initialize @tty = false @@ -19,13 +20,11 @@ module QA def paths_from_knapsack allocator = Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator - QA::Runtime::Logger.info '' + QA::Runtime::Logger.info '==== Knapsack specs to execute =====' QA::Runtime::Logger.info 'Report specs:' QA::Runtime::Logger.info allocator.report_node_tests.join(', ') - QA::Runtime::Logger.info '' QA::Runtime::Logger.info 'Leftover specs:' QA::Runtime::Logger.info allocator.leftover_node_tests.join(', ') - QA::Runtime::Logger.info '' ['--', allocator.node_tests] end @@ -70,8 +69,15 @@ module QA ParallelRunner.run(args.flatten) elsif Runtime::Scenario.attributes[:loop] LoopRunner.run(args.flatten) + elsif Runtime::Scenario.attributes[:count_examples_only] + args.unshift('--dry-run') + out = StringIO.new + RSpec::Core::Runner.run(args.flatten, $stderr, out).tap do |status| + abort if status.nonzero? + end + $stdout.puts out.string.match(/(\d+) examples,/)[1] else - RSpec::Core::Runner.run(args.flatten, $stderr, $stdout).tap do |status| + RSpec::Core::Runner.run(args.flatten, *DEFAULT_STD_ARGS).tap do |status| abort if status.nonzero? end end |