[QA] Add a new scenario to test GitHub import

Signed-off-by: Rémy Coutable <remy@rymai.me>
This commit is contained in:
Rémy Coutable 2018-06-18 17:05:42 +02:00 committed by Grzegorz Bizon
parent 01796734d0
commit 2ad990bba0
18 changed files with 337 additions and 19 deletions

View File

@ -40,7 +40,7 @@
= project.human_import_status_name
- @repos.each do |repo|
%tr{ id: "repo_#{repo.id}" }
%tr{ id: "repo_#{repo.id}", data: { qa: { repo_path: repo.full_name } } }
%td
= provider_project_link(provider, repo.full_name)
%td.import-target
@ -50,7 +50,7 @@
- if current_user.can_select_namespace?
- selected = params[:namespace_id] || :current_user
- opts = current_user.can_create_group? ? { extra_group: Group.new(name: repo.owner.login, path: repo.owner.login) } : {}
= select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'input-group-text select2 js-select-namespace', tabindex: 1 }
= select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'input-group-text select2 js-select-namespace qa-project-namespace-select', tabindex: 1 }
- else
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend

View File

@ -37,7 +37,7 @@
%li.dropdown-bold-header GitLab
- if current_user.can_create_project?
%li
= link_to 'New project', new_project_path
= link_to 'New project', new_project_path, class: 'qa-global-new-project-link'
- if current_user.can_create_group?
%li
= link_to 'New group', new_group_path

View File

@ -40,6 +40,7 @@ module QA
autoload :Issue, 'qa/factory/resource/issue'
autoload :Project, 'qa/factory/resource/project'
autoload :MergeRequest, 'qa/factory/resource/merge_request'
autoload :ProjectImportedFromGithub, 'qa/factory/resource/project_imported_from_github'
autoload :DeployKey, 'qa/factory/resource/deploy_key'
autoload :Branch, 'qa/factory/resource/branch'
autoload :SecretVariable, 'qa/factory/resource/secret_variable'
@ -79,6 +80,7 @@ module QA
autoload :Instance, 'qa/scenario/test/instance'
module Integration
autoload :Github, 'qa/scenario/test/integration/github'
autoload :LDAP, 'qa/scenario/test/integration/ldap'
autoload :Kubernetes, 'qa/scenario/test/integration/kubernetes'
autoload :Mattermost, 'qa/scenario/test/integration/mattermost'
@ -132,6 +134,10 @@ module QA
autoload :Show, 'qa/page/project/show'
autoload :Activity, 'qa/page/project/activity'
module Import
autoload :Github, 'qa/page/project/import/github'
end
module Pipeline
autoload :Index, 'qa/page/project/pipeline/index'
autoload :Show, 'qa/page/project/pipeline/show'
@ -185,7 +191,7 @@ module QA
end
module Issuable
autoload :Show, 'qa/page/issuable/show'
autoload :Sidebar, 'qa/page/issuable/sidebar'
end
module MergeRequest
@ -210,6 +216,7 @@ module QA
#
module Component
autoload :Dropzone, 'qa/page/component/dropzone'
autoload :Select2, 'qa/page/component/select2'
end
end

View File

@ -23,7 +23,7 @@ module QA
Page::Group::New.perform do |group|
group.set_path(@path)
group.set_description(@description)
group.set_visibility('Private')
group.set_visibility('Public')
group.create
end
end

View File

@ -5,16 +5,12 @@ module QA
module Resource
class Project < Factory::Base
attr_writer :description
attr_reader :name
dependency Factory::Resource::Group, as: :group
def name=(name)
@name = "#{name}-#{SecureRandom.hex(8)}"
@description = 'My awesome project'
end
product :name do
Page::Project::Show.act { project_name }
product :name do |factory|
factory.name
end
product :repository_ssh_location do
@ -24,6 +20,14 @@ module QA
end
end
def initialize
@description = 'My awesome project'
end
def name=(raw_name)
@name = "#{raw_name}-#{SecureRandom.hex(8)}"
end
def fabricate!
group.visit!

View File

@ -0,0 +1,37 @@
require 'securerandom'
module QA
module Factory
module Resource
class ProjectImportedFromGithub < Resource::Project
attr_writer :personal_access_token, :github_repository_path
dependency Factory::Resource::Group, as: :group
product :name do |factory|
factory.name
end
def fabricate!
group.visit!
Page::Group::Show.act { go_to_new_project }
Page::Project::New.perform do |page|
page.go_to_import_project
end
Page::Project::New.perform do |page|
page.go_to_github_import
end
Page::Project::Import::Github.perform do |page|
page.add_personal_access_token(@personal_access_token)
page.list_repos
page.import!(@github_repository_path, @name)
end
end
end
end
end
end

View File

@ -21,8 +21,8 @@ module QA
Page::Group::New.perform do |group|
group.set_path(@name)
group.set_description('GitLab QA Sandbox')
group.set_visibility('Private')
group.set_description('GitLab QA Sandbox Group')
group.set_visibility('Public')
group.create
end
end

View File

@ -0,0 +1,11 @@
module QA
module Page
module Component
module Select2
def select_item(item_text)
find('ul.select2-result-sub > li', text: item_text).click
end
end
end
end
end

View File

@ -1,15 +1,14 @@
module QA
module Page
module Issuable
class Show < Page::Base
class Sidebar < Page::Base
view 'app/views/shared/issuable/_sidebar.html.haml' do
element :labels_block, ".issuable-show-labels"
end
def has_label?(label)
page.within('.issuable-show-labels') do
element = find('span', text: label, wait: 1)
!element.nil?
!!find('span', text: label)
end
end
end

View File

@ -10,6 +10,8 @@ module QA
element :operations_kubernetes_link, "title: _('Kubernetes')"
element :issues_link, /link_to.*shortcuts-issues/
element :issues_link_text, "Issues"
element :merge_requests_link, /link_to.*shortcuts-merge_requests/
element :merge_requests_link_text, "Merge Requests"
element :top_level_items, '.sidebar-top-level-items'
element :operations_section, "class: 'shortcuts-operations'"
element :activity_link, "title: 'Activity'"
@ -62,6 +64,12 @@ module QA
end
end
def click_merge_requests
within_sidebar do
click_link('Merge Requests')
end
end
def click_wiki
within_sidebar do
click_link('Wiki')

View File

@ -0,0 +1,66 @@
module QA
module Page
module Project
module Import
class Github < Page::Base
include Page::Component::Select2
view 'app/views/import/github/new.html.haml' do
element :personal_access_token_field, 'text_field_tag :personal_access_token'
element :list_repos_button, "submit_tag _('List your GitHub repositories')"
end
view 'app/views/import/_githubish_status.html.haml' do
element :project_import_row, 'data: { qa: { repo_path: repo.full_name } }'
element :project_namespace_select
element :project_namespace_field, 'select_tag :namespace_id'
element :project_path_field, 'text_field_tag :path, repo.name'
element :import_button, "_('Import')"
end
def add_personal_access_token(personal_access_token)
fill_in 'personal_access_token', with: personal_access_token
end
def list_repos
click_button 'List your GitHub repositories'
end
def import!(full_path, name)
choose_test_namespace(full_path)
set_path(full_path, name)
import_project(full_path)
end
private
def within_repo_path(full_path)
page.within(%Q(tr[data-qa-repo-path="#{full_path}"])) do
yield
end
end
def choose_test_namespace(full_path)
within_repo_path(full_path) do
click_element :project_namespace_select
end
select_item(Runtime::Namespace.path)
end
def set_path(full_path, name)
within_repo_path(full_path) do
fill_in 'path', with: name
end
end
def import_project(full_path)
within_repo_path(full_path) do
click_button 'Import'
end
end
end
end
end
end
end

View File

@ -2,6 +2,12 @@ module QA
module Page
module Project
class New < Page::Base
include Page::Component::Select2
view 'app/views/projects/new.html.haml' do
element :import_project_tab, "Import project"
end
view 'app/views/projects/_new_project_fields.html.haml' do
element :project_namespace_select
element :project_namespace_field, /select :namespace_id.*class: 'select2/
@ -10,10 +16,18 @@ module QA
element :project_create_button, "submit 'Create project'"
end
view 'app/views/projects/_import_project_pane.html.haml' do
element :import_github, "icon('github', text: 'GitHub')"
end
def choose_test_namespace
click_element :project_namespace_select
find('ul.select2-result-sub > li', text: Runtime::Namespace.path).click
select_item(Runtime::Namespace.path)
end
def go_to_import_project
click_on 'Import project'
end
def choose_name(name)
@ -27,6 +41,10 @@ module QA
def create_new_project
click_on 'Create project'
end
def go_to_github_import
click_link 'GitHub'
end
end
end
end

View File

@ -22,6 +22,10 @@ module QA
element :branches_dropdown
end
view 'app/views/projects/_files.html.haml' do
element :tree_holder, '.tree-holder'
end
def project_name
find('.qa-project-name').text
end
@ -46,6 +50,12 @@ module QA
click_element :create_merge_request
end
def wait_for_import
wait(reload: true) do
has_css?('.tree-holder')
end
end
def go_to_new_issue
click_element :new_menu_toggle

View File

@ -66,6 +66,17 @@ module QA
def has_gcloud_credentials?
%w[GCLOUD_ACCOUNT_KEY GCLOUD_ACCOUNT_EMAIL].none? { |var| ENV[var].to_s.empty? }
end
# Specifies the token that can be used for the GitHub API
def github_access_token
ENV['GITHUB_ACCESS_TOKEN'].to_s.strip
end
def require_github_access_token!
return unless github_access_token.empty?
raise ArgumentError, "Please provide GITHUB_ACCESS_TOKEN"
end
end
end
end

View File

@ -16,7 +16,7 @@ module QA
end
def sandbox_name
Runtime::Env.sandbox_name || 'gitlab-qa-sandbox'
Runtime::Env.sandbox_name || 'gitlab-qa-sandbox-group'
end
end
end

View File

@ -0,0 +1,18 @@
module QA
module Scenario
module Test
module Integration
class Github < Test::Instance
tags :github
def perform(address, *rspec_options)
# This test suite requires a GitHub personal access token
Runtime::Env.require_github_access_token!
super
end
end
end
end
end
end

View File

@ -0,0 +1,106 @@
module QA
describe 'user imports a GitHub repo', :core, :github do
let(:imported_project) do
Factory::Resource::ProjectImportedFromGithub.fabricate! do |project|
project.name = 'imported-project'
project.personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = 'gitlab-qa/test-project'
end
end
after do
# We need to delete the imported project because it's impossible to import
# the same GitHub project twice for a given user.
api_client = Runtime::API::Client.new(:gitlab)
delete_project_request = Runtime::API::Request.new(api_client, "/projects/#{CGI.escape("#{Runtime::Namespace.path}/#{imported_project.name}")}")
delete delete_project_request.url
expect_status(202)
end
it 'user imports a GitHub repo' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
imported_project # import the project
Page::Menu::Main.act { go_to_projects }
Page::Dashboard::Projects.perform do |dashboard|
dashboard.go_to_project(imported_project.name)
end
Page::Project::Show.act { 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
expect(page).to have_content('This test project is used for automated GitHub import by GitLab QA.')
expect(page).to have_content(imported_project.name)
end
def verify_issues_import
Page::Menu::Side.act { click_issues }
expect(page).to have_content('This is a sample issue')
click_link 'This is a sample issue'
expect(page).to have_content('We should populate this project with issues, pull requests and wiki pages.')
# Comments
expect(page).to have_content('This is a comment from @rymai.')
Page::Issuable::Sidebar.perform do |issuable|
expect(issuable).to have_label('enhancement')
expect(issuable).to have_label('help wanted')
expect(issuable).to have_label('good first issue')
end
end
def verify_merge_requests_import
Page::Menu::Side.act { click_merge_requests }
expect(page).to have_content('Improve README.md')
click_link 'Improve README.md'
expect(page).to have_content('This improves the README file a bit.')
# Review comment are not supported yet
expect(page).not_to have_content('Really nice change.')
# Comments
expect(page).to have_content('Nice work! This is a comment from @rymai.')
# Diff comments
expect(page).to have_content('[Review comment] I like that!')
expect(page).to have_content('[Review comment] Nice blank line.')
expect(page).to have_content('[Single diff comment] Much better without this line!')
Page::Issuable::Sidebar.perform do |issuable|
expect(issuable).to have_label('bug')
expect(issuable).to have_label('enhancement')
end
end
def verify_labels_import
# TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19228
# to build upon it.
end
def verify_milestones_import
# TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18727
# to build upon it.
end
def verify_wiki_import
Page::Menu::Side.act { click_wiki }
expect(page).to have_content('Welcome to the test-project wiki!')
end
end
end

View File

@ -76,4 +76,27 @@ describe QA::Runtime::Env do
expect { described_class.user_type }.to raise_error(ArgumentError)
end
end
describe '.github_access_token' do
it 'returns "" if GITHUB_ACCESS_TOKEN is not defined' do
expect(described_class.github_access_token).to eq('')
end
it 'returns stripped string if GITHUB_ACCESS_TOKEN is defined' do
stub_env('GITHUB_ACCESS_TOKEN', ' abc123 ')
expect(described_class.github_access_token).to eq('abc123')
end
end
describe '.require_github_access_token!' do
it 'raises ArgumentError if GITHUB_ACCESS_TOKEN is not defined' do
expect { described_class.require_github_access_token! }.to raise_error(ArgumentError)
end
it 'does not raise if GITHUB_ACCESS_TOKEN is defined' do
stub_env('GITHUB_ACCESS_TOKEN', ' abc123 ')
expect { described_class.require_github_access_token! }.not_to raise_error
end
end
end