summaryrefslogtreecommitdiff
path: root/qa/qa/resource
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /qa/qa/resource
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
downloadgitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'qa/qa/resource')
-rw-r--r--qa/qa/resource/base.rb218
-rw-r--r--qa/qa/resource/deploy_token.rb2
-rw-r--r--qa/qa/resource/group.rb4
-rw-r--r--qa/qa/resource/group_base.rb10
-rw-r--r--qa/qa/resource/import_project.rb35
-rw-r--r--qa/qa/resource/kubernetes_cluster/project_cluster.rb17
-rw-r--r--qa/qa/resource/merge_request.rb70
-rw-r--r--qa/qa/resource/package.rb7
-rw-r--r--qa/qa/resource/personal_access_token.rb24
-rw-r--r--qa/qa/resource/personal_access_token_cache.rb17
-rw-r--r--qa/qa/resource/project.rb32
-rw-r--r--qa/qa/resource/project_imported_from_github.rb65
-rw-r--r--qa/qa/resource/project_imported_from_url.rb27
-rw-r--r--qa/qa/resource/repository/wiki_push.rb1
-rw-r--r--qa/qa/resource/user.rb2
15 files changed, 352 insertions, 179 deletions
diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb
index 873ba353051..ca0087cf709 100644
--- a/qa/qa/resource/base.rb
+++ b/qa/qa/resource/base.rb
@@ -1,70 +1,143 @@
# frozen_string_literal: true
-require 'forwardable'
require 'capybara/dsl'
require 'active_support/core_ext/array/extract_options'
module QA
module Resource
class Base
- extend SingleForwardable
include ApiFabricator
extend Capybara::DSL
NoValueError = Class.new(RuntimeError)
- def_delegators :evaluator, :attribute
+ class << self
+ # Initialize new instance of class without fabrication
+ #
+ # @param [Proc] prepare_block
+ def init(&prepare_block)
+ new.tap(&prepare_block)
+ end
- def self.fabricate!(*args, &prepare_block)
- fabricate_via_api!(*args, &prepare_block)
- rescue NotImplementedError
- fabricate_via_browser_ui!(*args, &prepare_block)
- end
+ def fabricate!(*args, &prepare_block)
+ fabricate_via_api!(*args, &prepare_block)
+ rescue NotImplementedError
+ fabricate_via_browser_ui!(*args, &prepare_block)
+ end
- def self.fabricate_via_browser_ui!(*args, &prepare_block)
- options = args.extract_options!
- resource = options.fetch(:resource) { new }
- parents = options.fetch(:parents) { [] }
+ def fabricate_via_browser_ui!(*args, &prepare_block)
+ options = args.extract_options!
+ resource = options.fetch(:resource) { new }
+ parents = options.fetch(:parents) { [] }
- do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
- log_fabrication(:browser_ui, resource, parents, args) { resource.fabricate!(*args) }
+ do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
+ log_fabrication(:browser_ui, resource, parents, args) { resource.fabricate!(*args) }
- current_url
+ current_url
+ end
end
- end
- def self.fabricate_via_api!(*args, &prepare_block)
- options = args.extract_options!
- resource = options.fetch(:resource) { new }
- parents = options.fetch(:parents) { [] }
+ def fabricate_via_api!(*args, &prepare_block)
+ options = args.extract_options!
+ resource = options.fetch(:resource) { new }
+ parents = options.fetch(:parents) { [] }
+
+ raise NotImplementedError unless resource.api_support?
+
+ resource.eager_load_api_client!
+
+ do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
+ log_fabrication(:api, resource, parents, args) { resource.fabricate_via_api! }
+ end
+ end
+
+ def remove_via_api!(*args, &prepare_block)
+ options = args.extract_options!
+ resource = options.fetch(:resource) { new }
+ parents = options.fetch(:parents) { [] }
+
+ resource.eager_load_api_client!
+
+ do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
+ log_fabrication(:api, resource, parents, args) { resource.remove_via_api! }
+ end
+ end
- raise NotImplementedError unless resource.api_support?
+ private
- resource.eager_load_api_client!
+ def do_fabricate!(resource:, prepare_block:, parents: [])
+ prepare_block.call(resource) if prepare_block
- do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
- log_fabrication(:api, resource, parents, args) { resource.fabricate_via_api! }
+ resource_web_url = yield
+ resource.web_url = resource_web_url
+
+ resource
+ end
+
+ def log_fabrication(method, resource, parents, args)
+ return yield unless Runtime::Env.debug?
+
+ start = Time.now
+ prefix = "==#{'=' * parents.size}>"
+ msg = [prefix]
+ msg << "Built a #{name}"
+ msg << "as a dependency of #{parents.last}" if parents.any?
+ msg << "via #{method}"
+
+ yield.tap do
+ msg << "in #{Time.now - start} seconds"
+ puts msg.join(' ')
+ puts if parents.empty?
+ end
+ end
+
+ # Define custom attribute
+ #
+ # @param [Symbol] name
+ # @return [void]
+ def attribute(name, &block)
+ (@attribute_names ||= []).push(name) # save added attributes
+
+ attr_writer(name)
+
+ define_method(name) do
+ instance_variable_get("@#{name}") || instance_variable_set("@#{name}", populate_attribute(name, block))
+ end
+ end
+
+ # Define multiple custom attributes
+ #
+ # @param [Array] names
+ # @return [void]
+ def attributes(*names)
+ names.each { |name| attribute(name) }
end
end
- def self.remove_via_api!(*args, &prepare_block)
- options = args.extract_options!
- resource = options.fetch(:resource) { new }
- parents = options.fetch(:parents) { [] }
+ # Override api reload! and update custom attributes from api_resource
+ #
+ api_reload = instance_method(:reload!)
+ define_method(:reload!) do
+ api_reload.bind_call(self)
+ return self unless api_resource
- resource.eager_load_api_client!
+ all_attributes.each do |attribute_name|
+ api_value = api_resource[attribute_name]
- do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
- log_fabrication(:api, resource, parents, args) { resource.remove_via_api! }
+ instance_variable_set("@#{attribute_name}", api_value) if api_value
end
+
+ self
end
+ attribute :web_url
+
def fabricate!(*_args)
raise NotImplementedError
end
def visit!
- Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"])
+ Runtime::Logger.debug(%(Visiting #{self.class.name} at "#{web_url}"))
# Just in case an async action is not yet complete
Support::WaitForRequests.wait_for_requests
@@ -78,14 +151,12 @@ module QA
Support::WaitForRequests.wait_for_requests
end
- def populate(*attributes)
- attributes.each(&method(:public_send))
+ def populate(*attribute_names)
+ attribute_names.each { |attribute_name| public_send(attribute_name) }
end
- def wait_until(max_duration: 60, sleep_interval: 0.1)
- QA::Support::Waiter.wait_until(max_duration: max_duration, sleep_interval: sleep_interval) do
- yield
- end
+ def wait_until(max_duration: 60, sleep_interval: 0.1, &block)
+ QA::Support::Waiter.wait_until(max_duration: max_duration, sleep_interval: sleep_interval, &block)
end
private
@@ -101,70 +172,27 @@ module QA
def attribute_value(name, block)
api_value = api_resource&.dig(name)
- if api_value && block
- log_having_both_api_result_and_block(name, api_value)
- end
+ log_having_both_api_result_and_block(name, api_value) if api_value && block
api_value || (block && instance_exec(&block))
end
- def log_having_both_api_result_and_block(name, api_value)
- QA::Runtime::Logger.info "<#{self.class}> Attribute #{name.inspect} has both API response `#{api_value}` and a block. API response will be picked. Block will be ignored."
+ # Get all defined attributes across all parents
+ #
+ # @return [Array<Symbol>]
+ def all_attributes
+ @all_attributes ||= self.class.ancestors
+ .select { |clazz| clazz <= QA::Resource::Base }
+ .map { |clazz| clazz.instance_variable_get(:@attribute_names) }
+ .flatten
+ .compact
end
- def self.do_fabricate!(resource:, prepare_block:, parents: [])
- prepare_block.call(resource) if prepare_block
-
- resource_web_url = yield
- resource.web_url = resource_web_url
-
- resource
- end
- private_class_method :do_fabricate!
-
- def self.log_fabrication(method, resource, parents, args)
- return yield unless Runtime::Env.debug?
-
- start = Time.now
- prefix = "==#{'=' * parents.size}>"
- msg = [prefix]
- msg << "Built a #{name}"
- msg << "as a dependency of #{parents.last}" if parents.any?
- msg << "via #{method}"
-
- yield.tap do
- msg << "in #{Time.now - start} seconds"
- puts msg.join(' ')
- puts if parents.empty?
- end
- end
- private_class_method :log_fabrication
-
- def self.evaluator
- @evaluator ||= Base::DSL.new(self)
- end
- private_class_method :evaluator
-
- class DSL
- def initialize(base)
- @base = base
- end
-
- def attribute(name, &block)
- @base.module_eval do
- attr_writer(name)
-
- define_method(name) do
- instance_variable_get("@#{name}") ||
- instance_variable_set(
- "@#{name}",
- populate_attribute(name, block))
- end
- end
- end
+ def log_having_both_api_result_and_block(name, api_value)
+ QA::Runtime::Logger.info(<<~MSG.strip)
+ <#{self.class}> Attribute #{name.inspect} has both API response `#{api_value}` and a block. API response will be picked. Block will be ignored.
+ MSG
end
-
- attribute :web_url
end
end
end
diff --git a/qa/qa/resource/deploy_token.rb b/qa/qa/resource/deploy_token.rb
index 0ba8dbbf287..cd638ad2f85 100644
--- a/qa/qa/resource/deploy_token.rb
+++ b/qa/qa/resource/deploy_token.rb
@@ -37,7 +37,7 @@ module QA
setting.expand_deploy_tokens do |page|
page.fill_token_name(name)
page.fill_token_expires_at(expires_at)
- page.fill_scopes(read_repository: true, read_registry: false)
+ page.fill_scopes(read_repository: true, read_package_registry: true)
page.add_token
end
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index 0f06113f85b..ce85273c3b2 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -3,7 +3,7 @@
module QA
module Resource
class Group < GroupBase
- attr_accessor :description
+ attributes :require_two_factor_authentication, :description
attribute :full_path do
determine_full_path
@@ -15,8 +15,6 @@ module QA
end
end
- attribute :require_two_factor_authentication
-
def initialize
@path = Runtime::Namespace.name
@description = "QA test run at #{Runtime::Namespace.time}"
diff --git a/qa/qa/resource/group_base.rb b/qa/qa/resource/group_base.rb
index 025d98f50e0..652c6cf7d1e 100644
--- a/qa/qa/resource/group_base.rb
+++ b/qa/qa/resource/group_base.rb
@@ -9,17 +9,17 @@ module QA
attr_accessor :path
- attribute :id
- attribute :runners_token
- attribute :name
- attribute :full_path
+ attributes :id,
+ :runners_token,
+ :name,
+ :full_path
# Get group labels
#
# @return [Array<QA::Resource::GroupLabel>]
def labels
parse_body(api_get_from("#{api_get_path}/labels")).map do |label|
- GroupLabel.new.tap do |resource|
+ GroupLabel.init do |resource|
resource.api_client = api_client
resource.group = self
resource.id = label[:id]
diff --git a/qa/qa/resource/import_project.rb b/qa/qa/resource/import_project.rb
new file mode 100644
index 00000000000..105d75285f1
--- /dev/null
+++ b/qa/qa/resource/import_project.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class ImportProject < Resource::Project
+ attr_writer :file_path
+
+ def initialize
+ @name = "ImportedProject-#{SecureRandom.hex(8)}"
+ @file_path = ::File.join('qa', 'fixtures', 'export.tar.gz')
+ end
+
+ def fabricate!
+ self.import = true
+ super
+
+ group.visit!
+
+ Page::Group::Show.perform(&:go_to_new_project)
+
+ Page::Project::New.perform do |new_project|
+ new_project.click_import_project
+ new_project.click_gitlab
+ new_project.set_imported_project_name(@name)
+ new_project.attach_exported_file(@file_path)
+ new_project.click_import_gitlab_project
+ end
+ end
+
+ def fabricate_via_api!
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/kubernetes_cluster/project_cluster.rb b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
index b66a75d978b..b3eba77fc46 100644
--- a/qa/qa/resource/kubernetes_cluster/project_cluster.rb
+++ b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
@@ -3,6 +3,8 @@
module QA
module Resource
module KubernetesCluster
+ # TODO: This resource is currently broken, since one-click apps have been removed.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/333818
class ProjectCluster < Base
attr_writer :cluster,
:install_ingress, :install_prometheus, :install_runner, :domain
@@ -11,8 +13,8 @@ module QA
Resource::Project.fabricate!
end
- attribute :ingress_ip do
- Page::Project::Infrastructure::Kubernetes::Show.perform(&:ingress_ip)
+ def ingress_ip
+ @ingress_ip ||= @cluster.fetch_external_ip_for_ingress
end
def fabricate!
@@ -40,17 +42,6 @@ module QA
# We must wait a few seconds for permissions to be set up correctly for new cluster
sleep 25
- # Open applications tab
- show.open_applications
-
- show.install!(:ingress) if @install_ingress
- show.install!(:prometheus) if @install_prometheus
- show.install!(:runner) if @install_runner
-
- show.await_installed(:ingress) if @install_ingress
- show.await_installed(:prometheus) if @install_prometheus
- show.await_installed(:runner) if @install_runner
-
if @install_ingress
populate(:ingress_ip)
diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb
index 5a24bb32475..8d9de0ea718 100644
--- a/qa/qa/resource/merge_request.rb
+++ b/qa/qa/resource/merge_request.rb
@@ -1,17 +1,12 @@
# frozen_string_literal: true
require 'securerandom'
-require 'active_support/core_ext/object/blank'
module QA
module Resource
class MergeRequest < Base
attr_accessor :approval_rules,
- :id,
- :title,
- :description,
:source_branch,
- :target_branch,
:target_new_branch,
:assignee,
:milestone,
@@ -22,9 +17,12 @@ module QA
:wait_for_merge,
:template
- attribute :merge_when_pipeline_succeeds
- attribute :merge_status
- attribute :state
+ attributes :iid,
+ :title,
+ :description,
+ :merge_when_pipeline_succeeds,
+ :merge_status,
+ :state
attribute :project do
Project.fabricate! do |resource|
@@ -32,11 +30,15 @@ module QA
end
end
+ attribute :target_branch do
+ project.default_branch
+ end
+
attribute :target do
Repository::ProjectPush.fabricate! do |resource|
resource.project = project
resource.branch_name = target_branch
- resource.new_branch = @target_new_branch
+ resource.new_branch = target_new_branch
resource.remote_branch = target_branch
end
end
@@ -62,13 +64,14 @@ module QA
@labels = []
@file_name = "added_file-#{SecureRandom.hex(8)}.txt"
@file_content = "File Added"
- @target_branch = project.default_branch
@target_new_branch = true
@no_preparation = false
@wait_for_merge = true
end
def fabricate!
+ return fabricate_large_merge_request if Runtime::Scenario.large_setup?
+
populate_target_and_source_if_required
project.visit!
@@ -89,21 +92,21 @@ module QA
end
def fabricate_via_api!
- raise ResourceNotFoundError unless id
+ return fabricate_large_merge_request if Runtime::Scenario.large_setup?
resource_web_url(api_get)
- rescue ResourceNotFoundError
+ rescue ResourceNotFoundError, NoValueError # rescue if iid not populated
populate_target_and_source_if_required
super
end
def api_merge_path
- "/projects/#{project.id}/merge_requests/#{id}/merge"
+ "/projects/#{project.id}/merge_requests/#{iid}/merge"
end
def api_get_path
- "/projects/#{project.id}/merge_requests/#{id}"
+ "/projects/#{project.id}/merge_requests/#{iid}"
end
def api_post_path
@@ -112,18 +115,22 @@ module QA
def api_post_body
{
- description: @description,
- source_branch: @source_branch,
- target_branch: @target_branch,
- title: @title
+ description: description,
+ source_branch: source_branch,
+ target_branch: target_branch,
+ title: title
}
end
+ def api_comments_path
+ "#{api_get_path}/notes"
+ end
+
def merge_via_api!
Support::Waiter.wait_until(sleep_interval: 1) do
- QA::Runtime::Logger.debug("Waiting until merge request with id '#{id}' can be merged")
+ QA::Runtime::Logger.debug("Waiting until merge request with id '#{iid}' can be merged")
- reload!.api_resource[:merge_status] == 'can_be_merged'
+ reload!.merge_status == 'can_be_merged'
end
Support::Retrier.retry_on_exception do
@@ -141,12 +148,21 @@ module QA
end
end
- def reload!
- # Refabricate so that we can return a new object with updated attributes
- self.class.fabricate_via_api! do |resource|
- resource.project = project
- resource.id = api_resource[:iid]
- end
+ def fabricate_large_merge_request
+ @project = Resource::ImportProject.fabricate_via_browser_ui!
+ # Setting the name here, since otherwise some tests will look for an existing file in
+ # the proejct without ever knowing what is in it.
+ @file_name = "github_controller_spec.rb"
+ visit("#{project.web_url}/-/merge_requests/1")
+ current_url
+ end
+
+ # Get MR comments
+ #
+ # @return [Array]
+ def comments
+ response = get(Runtime::API::Request.new(api_client, api_comments_path).url)
+ parse_body(response)
end
private
@@ -158,8 +174,6 @@ module QA
end
def populate_target_and_source_if_required
- @target_branch ||= project.default_branch
-
populate(:target, :source) unless @no_preparation
end
end
diff --git a/qa/qa/resource/package.rb b/qa/qa/resource/package.rb
index 1009353a296..0e8c3ee95de 100644
--- a/qa/qa/resource/package.rb
+++ b/qa/qa/resource/package.rb
@@ -15,11 +15,10 @@ module QA
end
attribute :id do
- packages = project.packages
-
- return unless (this_package = packages&.find { |package| package[:name] == "#{project.path_with_namespace}/#{name}" }) # rubocop:disable Cop/AvoidReturnFromBlocks
+ this_package = project.packages
+ &.find { |package| package[:name] == name }
- this_package[:id]
+ this_package.try(:fetch, :id)
end
def fabricate!
diff --git a/qa/qa/resource/personal_access_token.rb b/qa/qa/resource/personal_access_token.rb
index 59ae8f4de7a..924e4206166 100644
--- a/qa/qa/resource/personal_access_token.rb
+++ b/qa/qa/resource/personal_access_token.rb
@@ -11,21 +11,25 @@ module QA
# This *could* be different than the api_client.user or the api_user provided by the QA::Resource::ApiFabricator module
attr_writer :user
- attribute :token do
- Page::Profile::PersonalAccessTokens.perform(&:created_access_token)
- end
+ attribute :token
# Only Admins can create PAT via the API.
# If Runtime::Env.admin_personal_access_token is provided, fabricate via the API,
# else, fabricate via the browser.
def fabricate_via_api!
- if Runtime::Env.admin_personal_access_token && !@user.nil?
- self.api_client = Runtime::API::Client.as_admin
+ @token = QA::Resource::PersonalAccessTokenCache.get_token_for_username(user.username)
+ return if @token
- super
- else
- fabricate!
- end
+ resource = if Runtime::Env.admin_personal_access_token && !@user.nil?
+ self.api_client = Runtime::API::Client.as_admin
+
+ super
+ else
+ fabricate!
+ end
+
+ QA::Resource::PersonalAccessTokenCache.set_token_for_username(user.username, self.token)
+ resource
end
# When a user is not provided, use default user
@@ -66,6 +70,8 @@ module QA
# Expire in 2 days just in case the token is created just before midnight
token_page.fill_expiry_date(Time.now.utc.to_date + 2)
token_page.click_create_token_button
+
+ self.token = Page::Profile::PersonalAccessTokens.perform(&:created_access_token)
end
end
end
diff --git a/qa/qa/resource/personal_access_token_cache.rb b/qa/qa/resource/personal_access_token_cache.rb
new file mode 100644
index 00000000000..617779173bd
--- /dev/null
+++ b/qa/qa/resource/personal_access_token_cache.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class PersonalAccessTokenCache
+ @personal_access_tokens = {}
+
+ def self.get_token_for_username(username)
+ @personal_access_tokens[username]
+ end
+
+ def self.set_token_for_username(username, token)
+ @personal_access_tokens[username] = token
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index f8cf816d6e4..d111b070863 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -9,21 +9,23 @@ module QA
include Members
include Visibility
- attr_accessor :repository_storage # requires admin access
- attr_writer :initialize_with_readme,
- :auto_devops_enabled,
- :github_personal_access_token,
- :github_repository_path
-
- attribute :id
- attribute :name
- attribute :add_name_uuid
- attribute :description
- attribute :standalone
- attribute :runners_token
- attribute :visibility
- attribute :template_name
- attribute :import
+ attr_accessor :repository_storage, # requires admin access
+ :initialize_with_readme,
+ :auto_devops_enabled,
+ :github_personal_access_token,
+ :github_repository_path
+
+ attributes :id,
+ :name,
+ :add_name_uuid,
+ :description,
+ :standalone,
+ :runners_token,
+ :visibility,
+ :template_name,
+ :import,
+ :import_status,
+ :import_error
attribute :group do
Group.fabricate!
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index 93cd166a191..214e8f517bb 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -1,25 +1,82 @@
# frozen_string_literal: true
-require 'securerandom'
+require 'octokit'
module QA
module Resource
class ProjectImportedFromGithub < Resource::Project
+ attribute :github_repo_id do
+ github_client.repository(github_repository_path).id
+ end
+
def fabricate!
self.import = true
Page::Main::Menu.perform(&:go_to_create_project)
+ go_to_import_page
+
+ Page::Project::Import::Github.perform do |import_page|
+ import_page.add_personal_access_token(github_personal_access_token)
+ import_page.import!(github_repository_path, name)
+ import_page.go_to_project(name)
+ end
+ end
+
+ def go_to_import_page
Page::Project::New.perform do |project_page|
project_page.click_import_project
project_page.click_github_link
end
+ end
- Page::Project::Import::Github.perform do |import_page|
- import_page.add_personal_access_token(@github_personal_access_token)
- import_page.import!(@github_repository_path, @name)
+ def fabricate_via_api!
+ super
+ rescue ResourceURLMissingError
+ "#{Runtime::Scenario.gitlab_address}/#{group.full_path}/#{name}"
+ end
+
+ def api_post_path
+ '/import/github'
+ end
+
+ def api_trigger_mirror_pull_path
+ "#{api_get_path}/mirror/pull"
+ end
+
+ def api_post_body
+ {
+ repo_id: github_repo_id,
+ new_name: name,
+ target_namespace: group.full_path,
+ personal_access_token: github_personal_access_token,
+ ci_cd_only: false
+ }
+ end
+
+ def transform_api_resource(api_resource)
+ api_resource
+ end
+
+ def trigger_project_mirror
+ Runtime::Logger.info "Triggering pull mirror request"
+
+ Support::Retrier.retry_until(max_attempts: 6, sleep_interval: 10) do
+ response = post(request_url(api_trigger_mirror_pull_path), nil)
+
+ Runtime::Logger.info "Mirror pull request response: #{response}"
+ response.code == Support::Api::HTTP_STATUS_OK
end
end
+
+ private
+
+ # Github client
+ #
+ # @return [Octokit::Client]
+ def github_client
+ @github_client ||= Octokit::Client.new(access_token: github_personal_access_token)
+ end
end
end
end
diff --git a/qa/qa/resource/project_imported_from_url.rb b/qa/qa/resource/project_imported_from_url.rb
new file mode 100644
index 00000000000..f159a174840
--- /dev/null
+++ b/qa/qa/resource/project_imported_from_url.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'securerandom'
+
+module QA
+ module Resource
+ class ProjectImportedFromURL < Resource::Project
+ def fabricate!
+ self.import = true
+ super
+
+ group.visit!
+
+ Page::Group::Show.perform(&:go_to_new_project)
+
+ Page::Project::New.perform do |project_page|
+ project_page.click_import_project
+ project_page.click_repo_by_url_link
+ end
+
+ Page::Project::Import::RepoByURL.perform do |import_page|
+ import_page.import!(@gitlab_repository_path, @name)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/repository/wiki_push.rb b/qa/qa/resource/repository/wiki_push.rb
index edf76c7cd78..aa69d831bff 100644
--- a/qa/qa/resource/repository/wiki_push.rb
+++ b/qa/qa/resource/repository/wiki_push.rb
@@ -16,7 +16,6 @@ module QA
@file_name = 'Home.md'
@file_content = 'This line was created using git push'
@commit_message = 'Updating using git push'
- @branch_name = 'master'
@new_branch = false
end
diff --git a/qa/qa/resource/user.rb b/qa/qa/resource/user.rb
index 8957dbcbe84..c424d7319fe 100644
--- a/qa/qa/resource/user.rb
+++ b/qa/qa/resource/user.rb
@@ -25,7 +25,7 @@ module QA
end
def self.default
- Resource::User.new.tap do |user|
+ Resource::User.init do |user|
user.username = Runtime::User.ldap_user? ? Runtime::User.ldap_username : Runtime::User.username
user.password = Runtime::User.ldap_user? ? Runtime::User.ldap_password : Runtime::User.password
end