Commit ba32265b authored by Andrejs Cunskis's avatar Andrejs Cunskis

Improve selectors and simplify code

Add correct group comparison

Use plain args

Add waiting check

Add testcase link

Remove failure aggregate

Explicitly remove imported group first

Use sandbox group as target
parent bce037cf
...@@ -122,6 +122,7 @@ export default { ...@@ -122,6 +122,7 @@ export default {
<tr <tr
class="gl-border-gray-200 gl-border-0 gl-border-b-1 gl-border-solid" class="gl-border-gray-200 gl-border-0 gl-border-b-1 gl-border-solid"
data-qa-selector="import_item" data-qa-selector="import_item"
:data-qa-source-group="group.full_path"
> >
<td class="gl-p-4"> <td class="gl-p-4">
<gl-link <gl-link
...@@ -166,6 +167,8 @@ export default { ...@@ -166,6 +167,8 @@ export default {
<gl-dropdown-item <gl-dropdown-item
v-for="ns in availableNamespaces" v-for="ns in availableNamespaces"
:key="ns.full_path" :key="ns.full_path"
data-qa-selector="target_group_dropdown_item"
:data-qa-group-name="ns.full_path"
@click="$emit('update-target-namespace', ns.full_path)" @click="$emit('update-target-namespace', ns.full_path)"
> >
{{ ns.full_path }} {{ ns.full_path }}
......
...@@ -11,35 +11,35 @@ module QA ...@@ -11,35 +11,35 @@ module QA
view "app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue" do view "app/assets/javascripts/import_entities/import_groups/components/import_table_row.vue" do
element :import_item element :import_item
element :target_namespace_selector_dropdown element :target_namespace_selector_dropdown
element :target_group_dropdown_item
element :import_status_indicator element :import_status_indicator
element :import_group_button element :import_group_button
end end
# Wait until list of groups has been loaded
#
# @return [void]
def wait_for_groups_to_load
has_element?(:import_group_table)
end
# Import source group in to target group # Import source group in to target group
# #
# @param [String] source_group_name # @param [String] source_group_name
# @param [String] target_group_name # @param [String] target_group_name
# @return [Boolean] # @return [void]
def import_group(source_group_name, target_group_name) def import_group(source_group_name, target_group_name)
source_group = all_elements(:import_item, minimum: 1).detect { |el| el.has_text?(source_group_name) } finished_loading?
raise("Import entry for #{source_group_name} not found!") unless source_group
within(source_group) do within_element(:import_item, source_group: source_group_name) do
click_element(:target_namespace_selector_dropdown) click_element(:target_namespace_selector_dropdown)
find_button(target_group_name).click click_element(:target_group_dropdown_item, group_name: target_group_name)
click_element(:import_group_button) click_element(:import_group_button)
wait_until(sleep_interval: 0.5, reload: false, raise_on_failure: false) do
find_element(:import_status_indicator).text == "Complete"
end end
end end
# Check if import page has a successfully imported group
#
# @param [String] source_group_name
# @param [Integer] wait
# @return [Boolean]
def has_imported_group?(source_group_name, wait: QA::Support::WaitForRequests::DEFAULT_MAX_WAIT_TIME)
within_element(:import_item, source_group: source_group_name) do
has_element?(:import_status_indicator, text: "Complete", wait: wait)
end
end end
end end
end end
......
...@@ -7,61 +7,77 @@ module QA ...@@ -7,61 +7,77 @@ module QA
let!(:user) { Resource::User.fabricate_via_api! { |usr| usr.api_client = api_client } } let!(:user) { Resource::User.fabricate_via_api! { |usr| usr.api_client = api_client } }
let!(:personal_access_token) { Runtime::API::Client.new(user: user).personal_access_token } let!(:personal_access_token) { Runtime::API::Client.new(user: user).personal_access_token }
let(:source_group) do let!(:sandbox) do
Resource::Sandbox.fabricate_via_api! do |group| Resource::Sandbox.fabricate_via_api! do |group|
group.api_client = api_client group.api_client = api_client
group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
end end
end end
let(:target_group) do let!(:source_group) do
Resource::Sandbox.fabricate_via_api! do |group| Resource::Sandbox.fabricate_via_api! do |group|
group.api_client = api_client group.api_client = api_client
group.path = "target-group-for-import-#{SecureRandom.hex(4)}" group.path = "source-group-for-import-#{SecureRandom.hex(4)}"
end end
end end
let(:imported_group) do let(:imported_group) do
Resource::Group.fabricate_via_api! do |group| Resource::Group.new.tap do |group|
group.api_client = api_client group.api_client = api_client
group.sandbox = target_group
group.path = source_group.path group.path = source_group.path
end.reload!
rescue Resource::ApiFabricator::ResourceNotFoundError
nil
end end
# Return subset of fields for comparing groups
#
# @param [Resource::Group, nil] group
# @return [Hash]
def comparable_group(group)
group&.api_resource&.except(
:id,
:web_url,
:visibility,
:full_name,
:full_path,
:created_at,
:parent_id,
:runners_token
)
end end
before do before do
Runtime::Feature.enable(:bulk_import) Runtime::Feature.enable(:bulk_import)
sandbox.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
source_group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) source_group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
target_group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
Flow::Login.sign_in(as: user) Flow::Login.sign_in(as: user)
Page::Main::Menu.new.go_to_import_group Page::Main::Menu.new.go_to_import_group
Page::Group::New.new.connect_gitlab_instance(Runtime::Scenario.gitlab_address, personal_access_token) Page::Group::New.new.connect_gitlab_instance(Runtime::Scenario.gitlab_address, personal_access_token)
end end
it "performs bulk group import from another gitlab instance" do it(
import = Page::Group::BulkImport.perform do |import_page| "performs bulk group import from another gitlab instance",
import_page.wait_for_groups_to_load testcase: "https://gitlab.com/gitlab-org/quality/testcases/-/issues/1785"
import_page.import_group(source_group.path, target_group.path) ) do
end Page::Group::BulkImport.perform do |import_page|
import_page.import_group(source_group.path, sandbox.path)
aggregate_failures do aggregate_failures do
expect(import).to be_truthy, "Group bulk import did not finish successfully" expect(import_page).to have_imported_group(source_group.path, wait: 60)
expect(imported_group.path).to eq(source_group.path) expect(comparable_group(imported_group)).to eq(comparable_group(source_group))
end
end end
end end
after do after do
Runtime::Feature.disable(:bulk_import) Runtime::Feature.disable(:bulk_import)
source_group&.remove_via_api! # Add additional maintainer to imported group so user is not sole maintainer and can be deleted
target_group&.remove_via_api! imported_group&.add_member(Runtime::User.admin, Resource::Members::AccessLevel::MAINTAINER)
source_group.remove_via_api!
# Imported group might not be immediately removed and 'user' is sole maintainer, so remove might fail user.remove_via_api!
QA::Support::Retrier.retry_on_exception do
user&.remove_via_api!
end
end end
end end
end end
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
require_relative '../qa' require_relative '../qa'
require 'rspec/retry' require 'rspec/retry'
require 'rspec-parameterized' require 'rspec-parameterized'
require 'active_support/core_ext/hash'
if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK'] if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK']
require 'knapsack' require 'knapsack'
......
# frozen_string_literal: true # frozen_string_literal: true
require 'active_support/core_ext/hash'
RSpec.describe QA::Specs::Runner do RSpec.describe QA::Specs::Runner do
shared_examples 'excludes orchestrated, transient, and geo' do shared_examples 'excludes orchestrated, transient, and geo' do
it 'excludes the orchestrated, transient, and geo tags, and includes default args' do it 'excludes the orchestrated, transient, and geo tags, and includes default args' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment