Merge branch 'qa-264' into 'master'
Adding spec to test basic forking functionalities See merge request gitlab-org/gitlab-ce!20097
This commit is contained in:
commit
0399b644ec
|
@ -55,7 +55,7 @@ Since the arguments would be passed to `rspec`, you could use all `rspec`
|
||||||
options there. For example, passing `--backtrace` and also line number:
|
options there. For example, passing `--backtrace` and also line number:
|
||||||
|
|
||||||
```
|
```
|
||||||
bin/qa Test::Instance http://localhost qa/specs/features/login/standard_spec.rb:3 --backtrace
|
bin/qa Test::Instance http://localhost qa/specs/features/project/create_spec.rb:3 --backtrace
|
||||||
```
|
```
|
||||||
|
|
||||||
### Overriding the authenticated user
|
### Overriding the authenticated user
|
||||||
|
|
12
qa/qa.rb
12
qa/qa.rb
|
@ -41,14 +41,17 @@ module QA
|
||||||
autoload :Project, 'qa/factory/resource/project'
|
autoload :Project, 'qa/factory/resource/project'
|
||||||
autoload :MergeRequest, 'qa/factory/resource/merge_request'
|
autoload :MergeRequest, 'qa/factory/resource/merge_request'
|
||||||
autoload :ProjectImportedFromGithub, 'qa/factory/resource/project_imported_from_github'
|
autoload :ProjectImportedFromGithub, 'qa/factory/resource/project_imported_from_github'
|
||||||
|
autoload :MergeRequestFromFork, 'qa/factory/resource/merge_request_from_fork'
|
||||||
autoload :DeployKey, 'qa/factory/resource/deploy_key'
|
autoload :DeployKey, 'qa/factory/resource/deploy_key'
|
||||||
autoload :Branch, 'qa/factory/resource/branch'
|
autoload :Branch, 'qa/factory/resource/branch'
|
||||||
autoload :SecretVariable, 'qa/factory/resource/secret_variable'
|
autoload :SecretVariable, 'qa/factory/resource/secret_variable'
|
||||||
autoload :Runner, 'qa/factory/resource/runner'
|
autoload :Runner, 'qa/factory/resource/runner'
|
||||||
autoload :PersonalAccessToken, 'qa/factory/resource/personal_access_token'
|
autoload :PersonalAccessToken, 'qa/factory/resource/personal_access_token'
|
||||||
autoload :KubernetesCluster, 'qa/factory/resource/kubernetes_cluster'
|
autoload :KubernetesCluster, 'qa/factory/resource/kubernetes_cluster'
|
||||||
|
autoload :User, 'qa/factory/resource/user'
|
||||||
autoload :ProjectMilestone, 'qa/factory/resource/project_milestone'
|
autoload :ProjectMilestone, 'qa/factory/resource/project_milestone'
|
||||||
autoload :Wiki, 'qa/factory/resource/wiki'
|
autoload :Wiki, 'qa/factory/resource/wiki'
|
||||||
|
autoload :Fork, 'qa/factory/resource/fork'
|
||||||
end
|
end
|
||||||
|
|
||||||
module Repository
|
module Repository
|
||||||
|
@ -107,6 +110,7 @@ module QA
|
||||||
module Main
|
module Main
|
||||||
autoload :Login, 'qa/page/main/login'
|
autoload :Login, 'qa/page/main/login'
|
||||||
autoload :OAuth, 'qa/page/main/oauth'
|
autoload :OAuth, 'qa/page/main/oauth'
|
||||||
|
autoload :SignUp, 'qa/page/main/sign_up'
|
||||||
end
|
end
|
||||||
|
|
||||||
module Settings
|
module Settings
|
||||||
|
@ -167,6 +171,10 @@ module QA
|
||||||
autoload :Index, 'qa/page/project/issue/index'
|
autoload :Index, 'qa/page/project/issue/index'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Fork
|
||||||
|
autoload :New, 'qa/page/project/fork/new'
|
||||||
|
end
|
||||||
|
|
||||||
module Milestone
|
module Milestone
|
||||||
autoload :New, 'qa/page/project/milestone/new'
|
autoload :New, 'qa/page/project/milestone/new'
|
||||||
autoload :Index, 'qa/page/project/milestone/index'
|
autoload :Index, 'qa/page/project/milestone/index'
|
||||||
|
@ -200,6 +208,10 @@ module QA
|
||||||
autoload :Sidebar, 'qa/page/issuable/sidebar'
|
autoload :Sidebar, 'qa/page/issuable/sidebar'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Layout
|
||||||
|
autoload :Banner, 'qa/page/layout/banner'
|
||||||
|
end
|
||||||
|
|
||||||
module MergeRequest
|
module MergeRequest
|
||||||
autoload :New, 'qa/page/merge_request/new'
|
autoload :New, 'qa/page/merge_request/new'
|
||||||
autoload :Show, 'qa/page/merge_request/show'
|
autoload :Show, 'qa/page/merge_request/show'
|
||||||
|
|
|
@ -11,6 +11,8 @@ module QA
|
||||||
factory.output
|
factory.output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
product(:project) { |factory| factory.project }
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@file_name = 'file.txt'
|
@file_name = 'file.txt'
|
||||||
@file_content = '# This is test project'
|
@file_content = '# This is test project'
|
||||||
|
|
|
@ -5,7 +5,8 @@ module QA
|
||||||
module Repository
|
module Repository
|
||||||
class Push < Factory::Base
|
class Push < Factory::Base
|
||||||
attr_accessor :file_name, :file_content, :commit_message,
|
attr_accessor :file_name, :file_content, :commit_message,
|
||||||
:branch_name, :new_branch, :output, :repository_uri
|
:branch_name, :new_branch, :output, :repository_uri,
|
||||||
|
:user
|
||||||
|
|
||||||
attr_writer :remote_branch
|
attr_writer :remote_branch
|
||||||
|
|
||||||
|
@ -31,9 +32,20 @@ module QA
|
||||||
def fabricate!
|
def fabricate!
|
||||||
Git::Repository.perform do |repository|
|
Git::Repository.perform do |repository|
|
||||||
repository.uri = repository_uri
|
repository.uri = repository_uri
|
||||||
|
|
||||||
repository.use_default_credentials
|
repository.use_default_credentials
|
||||||
|
username = 'GitLab QA'
|
||||||
|
email = 'root@gitlab.com'
|
||||||
|
|
||||||
|
if user
|
||||||
|
repository.username = user.username
|
||||||
|
repository.password = user.password
|
||||||
|
username = user.name
|
||||||
|
email = user.email
|
||||||
|
end
|
||||||
|
|
||||||
repository.clone
|
repository.clone
|
||||||
repository.configure_identity('GitLab QA', 'root@gitlab.com')
|
repository.configure_identity(username, email)
|
||||||
|
|
||||||
if new_branch
|
if new_branch
|
||||||
repository.checkout_new_branch(branch_name)
|
repository.checkout_new_branch(branch_name)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
module QA
|
||||||
|
module Factory
|
||||||
|
module Resource
|
||||||
|
class Fork < Factory::Base
|
||||||
|
dependency Factory::Repository::ProjectPush, as: :push
|
||||||
|
|
||||||
|
dependency Factory::Resource::User, as: :user
|
||||||
|
|
||||||
|
product(:user) { |factory| factory.user }
|
||||||
|
|
||||||
|
def fabricate!
|
||||||
|
push.project.visit!
|
||||||
|
Page::Project::Show.act { fork_project }
|
||||||
|
|
||||||
|
Page::Project::Fork::New.perform do |fork_new|
|
||||||
|
fork_new.choose_namespace(user.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
Page::Layout::Banner.act { has_notice?('The project was successfully forked.') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
module QA
|
||||||
|
module Factory
|
||||||
|
module Resource
|
||||||
|
class MergeRequestFromFork < MergeRequest
|
||||||
|
attr_accessor :fork_branch
|
||||||
|
|
||||||
|
dependency Factory::Resource::Fork, as: :fork
|
||||||
|
|
||||||
|
dependency Factory::Repository::ProjectPush, as: :push do |push, factory|
|
||||||
|
push.project = factory.fork
|
||||||
|
push.branch_name = factory.fork_branch
|
||||||
|
push.file_name = 'file2.txt'
|
||||||
|
push.user = factory.fork.user
|
||||||
|
end
|
||||||
|
|
||||||
|
def fabricate!
|
||||||
|
fork.visit!
|
||||||
|
Page::Project::Show.act { new_merge_request }
|
||||||
|
Page::MergeRequest::New.act { create_merge_request }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -37,6 +37,7 @@ module QA
|
||||||
page.choose_test_namespace
|
page.choose_test_namespace
|
||||||
page.choose_name(@name)
|
page.choose_name(@name)
|
||||||
page.add_description(@description)
|
page.add_description(@description)
|
||||||
|
page.set_visibility('Public')
|
||||||
page.create_new_project
|
page.create_new_project
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
require 'securerandom'
|
||||||
|
|
||||||
|
module QA
|
||||||
|
module Factory
|
||||||
|
module Resource
|
||||||
|
class User < Factory::Base
|
||||||
|
attr_accessor :name, :username, :email, :password
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@name = "name-#{SecureRandom.hex(8)}"
|
||||||
|
@username = "username-#{SecureRandom.hex(8)}"
|
||||||
|
@email = "mail#{SecureRandom.hex(8)}@mail.com"
|
||||||
|
@password = 'password'
|
||||||
|
end
|
||||||
|
|
||||||
|
product(:name) { |factory| factory.name }
|
||||||
|
|
||||||
|
product(:username) { |factory| factory.username }
|
||||||
|
|
||||||
|
product(:email) { |factory| factory.email }
|
||||||
|
|
||||||
|
product(:password) { |factory| factory.password }
|
||||||
|
|
||||||
|
def fabricate!
|
||||||
|
Page::Menu::Main.act { sign_out }
|
||||||
|
Page::Main::Login.act { switch_to_register_tab }
|
||||||
|
Page::Main::SignUp.perform do |page|
|
||||||
|
page.sign_up!(name: name, username: username, email: email, password: password)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,17 @@
|
||||||
|
module QA
|
||||||
|
module Page
|
||||||
|
module Layout
|
||||||
|
class Banner < Page::Base
|
||||||
|
view 'app/views/layouts/header/_read_only_banner.html.haml' do
|
||||||
|
element :flash_notice, ".flash-notice"
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_notice?(message)
|
||||||
|
page.within('.flash-notice') do
|
||||||
|
!!find('span', text: message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -25,19 +25,24 @@ module QA
|
||||||
element :standard_tab, "link_to 'Standard'"
|
element :standard_tab, "link_to 'Standard'"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
view 'app/views/devise/shared/_tabs_normal.html.haml' do
|
||||||
|
element :sign_in_tab, /nav-link.*login-pane.*Sign in/
|
||||||
|
element :register_tab, /nav-link.*register-pane.*Register/
|
||||||
|
end
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
# The login page is usually the entry point for all the scenarios so
|
# The login page is usually the entry point for all the scenarios so
|
||||||
# we need to wait for the instance to start. That said, in some cases
|
# we need to wait for the instance to start. That said, in some cases
|
||||||
# we are already logged-in so we check both cases here.
|
# we are already logged-in so we check both cases here.
|
||||||
wait(max: 500) do
|
wait(max: 500) do
|
||||||
page.has_css?('.login-page') ||
|
page.has_css?('.login-page') ||
|
||||||
Page::Menu::Main.act { has_personal_area? }
|
Page::Menu::Main.act { has_personal_area?(wait: 0) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign_in_using_credentials
|
def sign_in_using_credentials
|
||||||
# Don't try to log-in if we're already logged-in
|
# Don't try to log-in if we're already logged-in
|
||||||
return if Page::Menu::Main.act { has_personal_area? }
|
return if Page::Menu::Main.act { has_personal_area?(wait: 0) }
|
||||||
|
|
||||||
using_wait_time 0 do
|
using_wait_time 0 do
|
||||||
set_initial_password_if_present
|
set_initial_password_if_present
|
||||||
|
@ -48,12 +53,22 @@ module QA
|
||||||
sign_in_using_gitlab_credentials
|
sign_in_using_gitlab_credentials
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Page::Menu::Main.act { has_personal_area? }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.path
|
def self.path
|
||||||
'/users/sign_in'
|
'/users/sign_in'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def switch_to_sign_in_tab
|
||||||
|
click_on 'Sign in'
|
||||||
|
end
|
||||||
|
|
||||||
|
def switch_to_register_tab
|
||||||
|
click_on 'Register'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def sign_in_using_ldap_credentials
|
def sign_in_using_ldap_credentials
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
module QA
|
||||||
|
module Page
|
||||||
|
module Main
|
||||||
|
class SignUp < Page::Base
|
||||||
|
view 'app/views/devise/shared/_signup_box.html.haml' do
|
||||||
|
element :name, 'text_field :name'
|
||||||
|
element :username, 'text_field :username'
|
||||||
|
element :email_field, 'email_field :email'
|
||||||
|
element :email_confirmation, 'email_field :email_confirmation'
|
||||||
|
element :password, 'password_field :password'
|
||||||
|
element :register_button, 'submit "Register"'
|
||||||
|
end
|
||||||
|
|
||||||
|
def sign_up!(name:, username:, email:, password:)
|
||||||
|
fill_in :new_user_name, with: name
|
||||||
|
fill_in :new_user_username, with: username
|
||||||
|
fill_in :new_user_email, with: email
|
||||||
|
fill_in :new_user_email_confirmation, with: email
|
||||||
|
fill_in :new_user_password, with: password
|
||||||
|
click_button 'Register'
|
||||||
|
|
||||||
|
Page::Menu::Main.act { has_personal_area? }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -60,9 +60,9 @@ module QA
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_personal_area?
|
def has_personal_area?(wait: Capybara.default_max_wait_time)
|
||||||
# No need to wait, either we're logged-in, or not.
|
# No need to wait, either we're logged-in, or not.
|
||||||
using_wait_time(0) { page.has_selector?('.qa-user-avatar') }
|
using_wait_time(wait) { page.has_selector?('.qa-user-avatar') }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
module QA
|
||||||
|
module Page
|
||||||
|
module Project
|
||||||
|
module Fork
|
||||||
|
class New < Page::Base
|
||||||
|
view 'app/views/projects/forks/_fork_button.html.haml' do
|
||||||
|
element :namespace, 'link_to project_forks_path'
|
||||||
|
end
|
||||||
|
|
||||||
|
def choose_namespace(namespace = Runtime::Namespace.path)
|
||||||
|
click_on namespace
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -14,6 +14,7 @@ module QA
|
||||||
element :project_path, 'text_field :path'
|
element :project_path, 'text_field :path'
|
||||||
element :project_description, 'text_area :description'
|
element :project_description, 'text_area :description'
|
||||||
element :project_create_button, "submit 'Create project'"
|
element :project_create_button, "submit 'Create project'"
|
||||||
|
element :visibility_radios, 'visibility_level:'
|
||||||
end
|
end
|
||||||
|
|
||||||
view 'app/views/projects/_import_project_pane.html.haml' do
|
view 'app/views/projects/_import_project_pane.html.haml' do
|
||||||
|
@ -42,6 +43,10 @@ module QA
|
||||||
click_on 'Create project'
|
click_on 'Create project'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_visibility(visibility)
|
||||||
|
choose visibility
|
||||||
|
end
|
||||||
|
|
||||||
def go_to_github_import
|
def go_to_github_import
|
||||||
click_link 'GitHub'
|
click_link 'GitHub'
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,6 +22,11 @@ module QA
|
||||||
element :branches_dropdown
|
element :branches_dropdown
|
||||||
end
|
end
|
||||||
|
|
||||||
|
view 'app/views/projects/buttons/_fork.html.haml' do
|
||||||
|
element :fork_label, "%span= s_('GoToYourFork|Fork')"
|
||||||
|
element :fork_link, "link_to new_project_fork_path(@project)"
|
||||||
|
end
|
||||||
|
|
||||||
view 'app/views/projects/_files.html.haml' do
|
view 'app/views/projects/_files.html.haml' do
|
||||||
element :tree_holder, '.tree-holder'
|
element :tree_holder, '.tree-holder'
|
||||||
end
|
end
|
||||||
|
@ -61,6 +66,10 @@ module QA
|
||||||
|
|
||||||
click_link 'New issue'
|
click_link 'New issue'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fork_project
|
||||||
|
click_on 'Fork'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
module QA
|
|
||||||
describe 'standard user login', :core do
|
|
||||||
it 'user logs in using credentials' do
|
|
||||||
Runtime::Browser.visit(:gitlab, Page::Main::Login)
|
|
||||||
Page::Main::Login.act { sign_in_using_credentials }
|
|
||||||
|
|
||||||
# TODO, since `Signed in successfully` message was removed
|
|
||||||
# this is the only way to tell if user is signed in correctly.
|
|
||||||
#
|
|
||||||
Page::Menu::Main.perform do |menu|
|
|
||||||
expect(menu).to have_personal_area
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
module QA
|
||||||
|
describe 'Project fork', :core do
|
||||||
|
it 'can submit merge requests to upstream master' do
|
||||||
|
Runtime::Browser.visit(:gitlab, Page::Main::Login)
|
||||||
|
Page::Main::Login.act { sign_in_using_credentials }
|
||||||
|
|
||||||
|
merge_request = Factory::Resource::MergeRequestFromFork.fabricate! do |merge_request|
|
||||||
|
merge_request.fork_branch = 'feature-branch'
|
||||||
|
end
|
||||||
|
|
||||||
|
Page::Menu::Main.act { sign_out }
|
||||||
|
Page::Main::Login.act do
|
||||||
|
switch_to_sign_in_tab
|
||||||
|
sign_in_using_credentials
|
||||||
|
end
|
||||||
|
|
||||||
|
merge_request.visit!
|
||||||
|
Page::MergeRequest::Show.act { merge! }
|
||||||
|
|
||||||
|
expect(page).to have_content('The changes were merged')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue