Commit 393facf4 authored by Mark Lapierre's avatar Mark Lapierre

Merge branch 'acunskis-github-import' into 'master'

Refactor Github importer e2e spec

See merge request gitlab-org/gitlab!63402
parents 1a9a0e69 e9976937
......@@ -18,10 +18,10 @@
- experiment(:new_repo, user: current_user) do |e|
- e.use do
= nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
= link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo" } do
= link_to new_project_path(anchor: 'blank_project'), data: { track_label: "projects_dropdown_blank_project", track_event: "click_link", track_experiment: "new_repo", qa_selector: "create_project_link" } do
= _('Create blank project')
= nav_link(path: 'projects/new#import_project') do
= link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo" } do
= link_to new_project_path(anchor: 'import_project'), data: { track_label: "projects_dropdown_import_project", track_event: "click_link", track_experiment: "new_repo", qa_selector: "import_project_link" } do
= _('Import project')
- e.try do
= nav_link(path: 'projects/new#blank_project', html_options: { class: 'gl-border-0 gl-border-t-1 gl-border-solid gl-border-gray-100' }) do
......
......@@ -55,13 +55,17 @@ module QA
end
def go_to_projects
go_to_menu_dropdown_option(:projects_dropdown)
within_element(:menu_subview_container) do
within_projects_menu do
click_element(:menu_item_link, title: 'Your projects')
end
end
def go_to_create_project
within_projects_menu do
click_element(:menu_item_link, title: 'Create new project')
end
end
def go_to_menu_dropdown_option(option_name)
within_top_menu do
click_element(:navbar_dropdown, title: 'Menu')
......@@ -84,11 +88,11 @@ module QA
def go_to_admin_area
click_admin_area
if has_text?('Enter Admin Mode', wait: 1.0)
Admin::NewSession.perform do |new_session|
new_session.set_password(Runtime::User.admin_password)
new_session.click_enter_admin_mode
end
return unless has_text?('Enter Admin Mode', wait: 1.0)
Admin::NewSession.perform do |new_session|
new_session.set_password(Runtime::User.admin_password)
new_session.click_enter_admin_mode
end
end
......@@ -166,19 +170,15 @@ module QA
private
def within_top_menu
within_element(:navbar) do
yield
end
def within_top_menu(&block)
within_element(:navbar, &block)
end
def within_user_menu
def within_user_menu(&block)
within_top_menu do
click_element :user_avatar
within_element(:user_menu) do
yield
end
within_element(:user_menu, &block)
end
end
......@@ -188,6 +188,12 @@ module QA
within_element(:menu_subview_container, &block)
end
def within_projects_menu(&block)
go_to_menu_dropdown_option(:projects_dropdown)
within_element(:menu_subview_container, &block)
end
def click_admin_area
go_to_menu_dropdown_option(:admin_area_link)
end
......
......@@ -32,24 +32,20 @@ module QA
end
def import!(full_path, name)
unless already_imported(full_path)
choose_test_namespace(full_path)
set_path(full_path, name)
import_project(full_path)
wait_for_success
end
return if already_imported(full_path)
go_to_project(name)
choose_test_namespace(full_path)
set_path(full_path, name)
import_project(full_path)
wait_for_success
end
private
def within_repo_path(full_path)
def within_repo_path(full_path, &block)
project_import_row = find_element(:project_import_row, text: full_path)
within(project_import_row) do
yield
end
within(project_import_row, &block)
end
def choose_test_namespace(full_path)
......@@ -75,8 +71,13 @@ module QA
def wait_for_success
# TODO: set reload:false and remove skip_finished_loading_check_on_refresh when
# https://gitlab.com/gitlab-org/gitlab/-/issues/292861 is fixed
wait_until(max_duration: 60, sleep_interval: 5.0, reload: true, skip_finished_loading_check_on_refresh: true) do
page.has_no_content?('Importing 1 repository', wait: 3.0)
wait_until(
max_duration: 60,
sleep_interval: 5.0,
reload: true,
skip_finished_loading_check_on_refresh: true
) do
page.has_no_content?('Importing 1 repository')
end
end
......
......@@ -10,10 +10,10 @@ module QA
include Visibility
attr_accessor :repository_storage # requires admin access
attr_writer :initialize_with_readme
attr_writer :auto_devops_enabled
attr_writer :github_personal_access_token
attr_writer :github_repository_path
attr_writer :initialize_with_readme,
:auto_devops_enabled,
:github_personal_access_token,
:github_repository_path
attribute :id
attribute :name
......@@ -40,15 +40,11 @@ module QA
end
attribute :repository_ssh_location do
Page::Project::Show.perform do |show|
show.repository_clone_ssh_location
end
Page::Project::Show.perform(&:repository_clone_ssh_location)
end
attribute :repository_http_location do
Page::Project::Show.perform do |show|
show.repository_clone_http_location
end
Page::Project::Show.perform(&:repository_clone_http_location)
end
def initialize
......@@ -104,7 +100,7 @@ module QA
def has_file?(file_path)
response = repository_tree
raise ResourceNotFoundError, "#{response[:message]}" if response.is_a?(Hash) && response.has_key?(:message)
raise ResourceNotFoundError, (response[:message]).to_s if response.is_a?(Hash) && response.has_key?(:message)
response.any? { |file| file[:path] == file_path }
end
......@@ -115,14 +111,14 @@ module QA
def has_branches?(branches)
branches.all? do |branch|
response = get(Runtime::API::Request.new(api_client, "#{api_repository_branches_path}/#{branch}").url)
response = get(request_url("#{api_repository_branches_path}/#{branch}"))
response.code == HTTP_STATUS_OK
end
end
def has_tags?(tags)
tags.all? do |tag|
response = get(Runtime::API::Request.new(api_client, "#{api_repository_tags_path}/#{tag}").url)
response = get(request_url("#{api_repository_tags_path}/#{tag}"))
response.code == HTTP_STATUS_OK
end
end
......@@ -183,6 +179,10 @@ module QA
"#{api_get_path}/pipeline_schedules"
end
def api_issues_path
"#{api_get_path}/issues"
end
def api_put_path
"/projects/#{id}"
end
......@@ -217,19 +217,28 @@ module QA
def change_repository_storage(new_storage)
put_body = { repository_storage: new_storage }
response = put Runtime::API::Request.new(api_client, api_put_path).url, put_body
response = put(request_url(api_put_path), put_body)
unless response.code == HTTP_STATUS_OK
raise ResourceUpdateFailedError, "Could not change repository storage to #{new_storage}. Request returned (#{response.code}): `#{response}`."
raise(
ResourceUpdateFailedError,
"Could not change repository storage to #{new_storage}. Request returned (#{response.code}): `#{response}`."
)
end
wait_until(sleep_interval: 1) { Runtime::API::RepositoryStorageMoves.has_status?(self, 'finished', new_storage) }
wait_until(sleep_interval: 1) do
Runtime::API::RepositoryStorageMoves.has_status?(self, 'finished', new_storage)
end
rescue Support::Repeater::RepeaterConditionExceededError
raise Runtime::API::RepositoryStorageMoves::RepositoryStorageMovesError, 'Timed out while waiting for the repository storage move to finish'
raise(
Runtime::API::RepositoryStorageMoves::RepositoryStorageMovesError,
'Timed out while waiting for the repository storage move to finish'
)
end
def commits
parse_body(get(Runtime::API::Request.new(api_client, api_commits_path).url))
response = get(request_url(api_commits_path))
parse_body(response)
end
def default_branch
......@@ -237,7 +246,7 @@ module QA
end
def import_status
response = get Runtime::API::Request.new(api_client, "/projects/#{id}/import").url
response = get(request_url("/projects/#{id}/import"))
unless response.code == HTTP_STATUS_OK
raise ResourceQueryError, "Could not get import status. Request returned (#{response.code}): `#{response}`."
......@@ -251,7 +260,8 @@ module QA
end
def merge_requests
parse_body(get(Runtime::API::Request.new(api_client, api_merge_requests_path).url))
response = get(request_url(api_merge_requests_path))
parse_body(response)
end
def merge_request_with_title(title)
......@@ -260,42 +270,52 @@ module QA
def runners(tag_list: nil)
response = if tag_list
get Runtime::API::Request.new(api_client, "#{api_runners_path}?tag_list=#{tag_list.compact.join(',')}", per_page: '100').url
get(request_url("#{api_runners_path}?tag_list=#{tag_list.compact.join(',')}", per_page: '100'))
else
get Runtime::API::Request.new(api_client, "#{api_runners_path}", per_page: '100').url
get(request_url(api_runners_path, per_page: '100'))
end
parse_body(response)
end
def registry_repositories
response = get Runtime::API::Request.new(api_client, "#{api_registry_repositories_path}").url
response = get(request_url(api_registry_repositories_path))
parse_body(response)
end
def packages
response = get Runtime::API::Request.new(api_client, "#{api_packages_path}").url
response = get(request_url(api_packages_path))
parse_body(response)
end
def repository_branches
parse_body(get(Runtime::API::Request.new(api_client, api_repository_branches_path).url))
response = get(request_url(api_repository_branches_path))
parse_body(response)
end
def repository_tags
parse_body(get(Runtime::API::Request.new(api_client, api_repository_tags_path).url))
response = get(request_url(api_repository_tags_path))
parse_body(response)
end
def repository_tree
parse_body(get(Runtime::API::Request.new(api_client, api_repository_tree_path).url))
response = get(request_url(api_repository_tree_path))
parse_body(response)
end
def pipelines
parse_body(get(Runtime::API::Request.new(api_client, api_pipelines_path).url))
response = get(request_url(api_pipelines_path))
parse_body(response)
end
def pipeline_schedules
parse_body(get(Runtime::API::Request.new(api_client, api_pipeline_schedules_path).url))
response = get(request_url(api_pipeline_schedules_path))
parse_body(response)
end
def issues
response = get(request_url(api_issues_path))
parse_body(response)
end
private
......@@ -307,6 +327,14 @@ module QA
Git::Location.new(api_resource[:http_url_to_repo])
api_resource
end
# Get api request url
#
# @param [String] path
# @return [String]
def request_url(path, **opts)
Runtime::API::Request.new(api_client, path, **opts).url
end
end
end
end
......@@ -7,23 +7,19 @@ module QA
class ProjectImportedFromGithub < Resource::Project
def fabricate!
self.import = true
super
group.visit!
Page::Main::Menu.perform(&:go_to_create_project)
Page::Group::Show.perform(&:go_to_new_project)
go_to_import_page
Page::Project::New.perform(&:click_github_link)
Page::Project::New.perform do |project_page|
project_page.click_import_project
project_page.click_github_link
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)
end
end
def go_to_import_page
Page::Project::New.perform(&:click_import_project)
end
end
end
end
......@@ -3,25 +3,26 @@
module QA
RSpec.describe 'Manage', :github, :requires_admin do
describe 'Project import' do
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
let!(:user) do
Resource::User.fabricate_via_api! do |resource|
resource.api_client = Runtime::API::Client.as_admin
resource.api_client = api_client
resource.hard_delete_on_api_removal = true
end
end
let(:group) { Resource::Group.fabricate_via_api! }
let(:imported_project) do
Resource::ProjectImportedFromGithub.fabricate_via_browser_ui! do |project|
project.name = 'imported-project'
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = 'gitlab-qa-github/test-project'
project.api_client = api_client
end
end
before do
Runtime::Feature.enable(:invite_members_group_modal, group: group)
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
end
......@@ -32,90 +33,49 @@ module QA
it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1762' do
Flow::Login.sign_in(as: user)
imported_project # import the project
imported_project.reload! # import the project and reload all fields
Page::Main::Menu.perform(&:go_to_projects)
Page::Dashboard::Projects.perform do |dashboard|
dashboard.go_to_project(imported_project.name)
aggregate_failures do
verify_repository_import
verify_issues_import
verify_merge_requests_import
end
Page::Project::Show.perform(&:wait_for_import)
verify_repository_import
verify_issues_import
verify_merge_requests_import
verify_labels_import
verify_milestones_import
verify_wiki_import
end
def verify_repository_import
Page::Project::Show.perform do |project|
expect(project).to have_content('This test project is used for automated GitHub import by GitLab QA.')
expect(project).to have_content(imported_project.name)
end
expect(imported_project.api_response).to include(
description: 'A new repo for test',
import_status: 'finished',
import_error: nil
)
end
def verify_issues_import
QA::Support::Retrier.retry_on_exception do
Page::Project::Menu.perform(&:click_issues)
Page::Project::Issue::Show.perform do |issue_page|
expect(issue_page).to have_content('This is a sample issue')
click_link 'This is a sample issue'
expect(issue_page).to have_content('This is a sample first comment')
# Comments
comment_text = 'This is a comment from @sliaquat'
expect(issue_page).to have_comment(comment_text)
expect(issue_page).to have_label('custom new label')
expect(issue_page).to have_label('help wanted')
expect(issue_page).to have_label('good first issue')
end
end
issues = imported_project.issues
expect(issues.length).to eq(1)
expect(issues.first).to include(
title: 'This is a sample issue',
description: "*Created by: gitlab-qa-github*\n\nThis is a sample first comment",
labels: ['custom new label', 'good first issue', 'help wanted'],
user_notes_count: 1
)
end
def verify_merge_requests_import
Page::Project::Menu.perform(&:click_merge_requests)
Page::MergeRequest::Show.perform do |merge_request|
expect(merge_request).to have_content('Improve readme')
click_link 'Improve readme'
expect(merge_request).to have_content('This improves the README file a bit.')
# Comments
expect(merge_request).to have_content('[PR comment by @sliaquat] Nice work!')
# Diff comments
expect(merge_request).to have_content('[Single diff comment] Good riddance')
expect(merge_request).to have_content('[Single diff comment] Nice addition')
expect(merge_request).to have_label('bug')
expect(merge_request).to have_label('documentation')
end
end
def verify_labels_import
# TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/19228
# to build upon it.
end
def verify_milestones_import
# TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18727
# to build upon it.
end
def verify_wiki_import
Page::Project::Menu.perform(&:click_wiki)
Page::Project::Wiki::Show.perform do |wiki|
expect(wiki).to have_content('Welcome to the test-project wiki!')
end
merge_requests = imported_project.merge_requests
expect(merge_requests.length).to eq(1)
expect(merge_requests.first).to include(
title: 'Improve readme',
state: 'opened',
target_branch: 'main',
source_branch: 'improve-readme',
labels: %w[bug documentation],
description: <<~DSC.strip
*Created by: gitlab-qa-github*\n\nThis improves the README file a bit.\r\n\r\nTODO:\r\n\r\n \r\n\r\n- [ ] Do foo\r\n- [ ] Make bar\r\n - [ ] Think about baz
DSC
)
end
end
end
......
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