Commit 664bd757 authored by Mark Lapierre's avatar Mark Lapierre

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

E2E: Update github import spec with proper validation

See merge request gitlab-org/gitlab!67410
parents 44612758 ff7f164d
......@@ -103,6 +103,7 @@ export default {
<tr
class="gl-h-11 gl-border-0 gl-border-solid gl-border-t-1 gl-border-gray-100 gl-h-11"
data-qa-selector="project_import_row"
:data-qa-source-project="repo.importSource.fullName"
>
<td class="gl-p-4">
<gl-link :href="repo.importSource.providerLink" target="_blank" data-testid="providerLink"
......@@ -155,7 +156,7 @@ export default {
</template>
<template v-else-if="repo.importedProject">{{ displayFullPath }}</template>
</td>
<td class="gl-p-4">
<td class="gl-p-4" data-qa-selector="import_status_indicator">
<import-status :status="importStatus" />
</td>
<td data-testid="actions">
......
......@@ -21,7 +21,7 @@ module QA
end
def to_s
<<~MSG.strip % { page: @page_class }
format(<<~MSG.strip, page: @page_class)
%{page} has no required elements.
See https://docs.gitlab.com/ee/development/testing_guide/end_to_end/dynamic_element_validation.html#required-elements
MSG
......@@ -232,7 +232,7 @@ module QA
visible = kwargs.delete(:visible)
visible = visible.nil? && true
try_find_element = ->(wait) do
try_find_element = lambda do |wait|
if disabled.nil?
has_css?(element_selector_css(name, kwargs), text: text, wait: wait, class: klass, visible: visible)
else
......@@ -322,13 +322,13 @@ module QA
# It would be ideal if we could detect when the animation is complete
# but in some cases there's nothing we can easily access via capybara
# so instead we wait for the element, and then we wait a little longer
raise ElementNotFound, %Q(Couldn't find element named "#{name}") unless has_element?(name)
raise ElementNotFound, %(Couldn't find element named "#{name}") unless has_element?(name)
sleep 1
end
def within_element(name, **kwargs)
wait_for_requests
wait_for_requests(skip_finished_loading_check: kwargs.delete(:skip_finished_loading_check))
text = kwargs.delete(:text)
page.within(element_selector_css(name, kwargs), text: text) do
......@@ -386,9 +386,7 @@ module QA
end
def self.errors
if views.empty?
return ["Page class does not have views / elements defined!"]
end
return ["Page class does not have views / elements defined!"] if views.empty?
views.flat_map(&:errors)
end
......
......@@ -18,12 +18,17 @@ module QA
element :import_button
element :project_path_content
element :go_to_project_button
element :import_status_indicator
end
view "app/assets/javascripts/import_entities/components/group_dropdown.vue" do
element :target_namespace_selector_dropdown
end
# Add personal access token
#
# @param [String] personal_access_token
# @return [void]
def add_personal_access_token(personal_access_token)
# If for some reasons this process is retried, user cannot re-enter github token in the same group
# In this case skip this step and proceed to import project row
......@@ -34,71 +39,50 @@ module QA
finished_loading?
end
def import!(full_path, name)
return if already_imported(full_path)
choose_test_namespace(full_path)
set_path(full_path, name)
import_project(full_path)
wait_for_success
end
# TODO: refactor to use 'go to project' button instead of generic main menu
def go_to_project(name)
Page::Main::Menu.perform(&:go_to_projects)
Page::Dashboard::Projects.perform do |dashboard|
dashboard.go_to_project(name)
end
end
private
def within_repo_path(full_path, &block)
project_import_row = find_element(:project_import_row, text: full_path)
within(project_import_row, &block)
end
def choose_test_namespace(full_path)
within_repo_path(full_path) do
within_element(:target_namespace_selector_dropdown) { click_button(class: 'dropdown-toggle') }
click_element(:target_group_dropdown_item, group_name: Runtime::Namespace.path)
end
end
def set_path(full_path, name)
within_repo_path(full_path) do
fill_element(:project_path_field, name)
end
end
def import_project(full_path)
within_repo_path(full_path) do
# Import project
#
# @param [String] source_project_name
# @param [String] target_group_path
# @return [void]
def import!(gh_project_name, target_group_path, project_name)
within_element(:project_import_row, source_project: gh_project_name) do
click_element(:target_namespace_selector_dropdown)
click_element(:target_group_dropdown_item, group_name: target_group_path)
fill_element(:project_path_field, project_name)
click_element(:import_button)
end
end
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: 90,
sleep_interval: 5.0,
reload: true,
skip_finished_loading_check_on_refresh: true
) do
# TODO: Refactor to explicitly wait for specific project import successful status
# This check can create false positive if main importing message appears with delay and check exits early
page.has_no_content?('Importing 1 repository', wait: 3)
# Check Go to project button present
#
# @param [String] gh_project_name
# @return [Boolean]
def has_go_to_project_button?(gh_project_name)
within_element(:project_import_row, source_project: gh_project_name) do
has_element?(:go_to_project_button)
end
end
def already_imported(full_path)
within_repo_path(full_path) do
has_element?(:project_path_content) && has_element?(:go_to_project_button)
# Check if import page has a successfully imported project
#
# @param [String] source_project_name
# @param [Integer] wait
# @return [Boolean]
def has_imported_project?(gh_project_name, wait: QA::Support::WaitForRequests::DEFAULT_MAX_WAIT_TIME)
within_element(:project_import_row, source_project: gh_project_name, skip_finished_loading_check: true) do
# TODO: remove retrier with reload:true once https://gitlab.com/gitlab-org/gitlab/-/issues/292861 is fixed
wait_until(
max_duration: wait,
sleep_interval: 5,
reload: true,
skip_finished_loading_check_on_refresh: true
) do
has_element?(:import_status_indicator, text: "Complete")
end
end
end
alias_method :wait_for_success, :has_imported_project?
end
end
end
......
......@@ -18,9 +18,12 @@ module QA
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)
import_page.import!(github_repository_path, group.full_path, name)
import_page.wait_for_success(github_repository_path)
end
reload!
visit!
end
def go_to_import_page
......
......@@ -3,9 +3,11 @@
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
let(:github_repo) { 'gitlab-qa-github/test-project' }
let(:imported_project_name) { 'imported-project' }
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 = api_client
resource.hard_delete_on_api_removal = true
......@@ -13,16 +15,25 @@ module QA
end
let(:imported_project) do
Resource::ProjectImportedFromGithub.fabricate_via_browser_ui! do |project|
project.name = 'imported-project'
Resource::ProjectImportedFromGithub.init do |project|
project.import = true
project.add_name_uuid = false
project.name = imported_project_name
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = 'gitlab-qa-github/test-project'
project.github_repository_path = github_repo
end
end
before do
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
Flow::Login.sign_in(as: user)
Page::Main::Menu.perform(&:go_to_create_project)
Page::Project::New.perform do |project_page|
project_page.click_import_project
project_page.click_github_link
end
end
after do
......@@ -30,13 +41,24 @@ module QA
end
it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1762' do
Flow::Login.sign_in(as: user)
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(Runtime::Env.github_access_token)
import_page.import!(github_repo, group.full_path, imported_project_name)
imported_project # import the project
aggregate_failures do
expect(import_page).to have_imported_project(github_repo)
# validate button is present instead of navigating to avoid dealing with multiple tabs
# which makes the test more complicated
expect(import_page).to have_go_to_project_button(github_repo)
end
end
imported_project.reload!.visit!
Page::Project::Show.perform do |project|
expect(project).to have_content(imported_project.name)
expect(project).to have_content('This test project is used for automated GitHub import by GitLab QA.')
aggregate_failures do
expect(project).to have_content(imported_project_name)
expect(project).to have_content('This test project is used for automated GitHub import by GitLab QA.')
end
end
end
end
......
......@@ -51,7 +51,7 @@ module QA
group.add_member(user, Resource::Members::AccessLevel::OWNER)
Flow::Login.sign_in(as: user)
imported_project.reload! # import project and populate attributes
imported_project # import project
end
after 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