Commit 3ec34997 authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖

Merge branch 'ce-to-ee-2018-12-11' into 'master'

CE upstream - 2018-12-11 13:21 UTC

See merge request gitlab-org/gitlab-ee!8792
parents 59e20557 f9ea8040
import '~/commons/bootstrap';
import { AwardsHandler } from '~/awards_handler'; import { AwardsHandler } from '~/awards_handler';
class EmojiMenu extends AwardsHandler { class EmojiMenu extends AwardsHandler {
......
...@@ -11,8 +11,21 @@ module Clusters ...@@ -11,8 +11,21 @@ module Clusters
yield(operation) if block_given? yield(operation) if block_given?
rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e
logger.error(
exception: e.class.name,
service: self.class.name,
provider_id: provider.id,
message: e.message
)
provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") provider.make_errored!("Failed to request to CloudPlatform; #{e.message}")
end end
private
def logger
@logger ||= Gitlab::Kubernetes::Logger.build
end
end end
end end
end end
...@@ -16,10 +16,13 @@ module Clusters ...@@ -16,10 +16,13 @@ module Clusters
ClusterPlatformConfigureWorker.perform_async(cluster.id) ClusterPlatformConfigureWorker.perform_async(cluster.id)
rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e
log_service_error(e.class.name, provider.id, e.message)
provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") provider.make_errored!("Failed to request to CloudPlatform; #{e.message}")
rescue Kubeclient::HttpError => e rescue Kubeclient::HttpError => e
log_service_error(e.class.name, provider.id, e.message)
provider.make_errored!("Failed to run Kubeclient: #{e.message}") provider.make_errored!("Failed to run Kubeclient: #{e.message}")
rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordInvalid => e
log_service_error(e.class.name, provider.id, e.message)
provider.make_errored!("Failed to configure Google Kubernetes Engine Cluster: #{e.message}") provider.make_errored!("Failed to configure Google Kubernetes Engine Cluster: #{e.message}")
end end
...@@ -105,6 +108,19 @@ module Clusters ...@@ -105,6 +108,19 @@ module Clusters
def cluster def cluster
@cluster ||= provider.cluster @cluster ||= provider.cluster
end end
def logger
@logger ||= Gitlab::Kubernetes::Logger.build
end
def log_service_error(exception, provider_id, message)
logger.error(
exception: exception.class.name,
service: self.class.name,
provider_id: provider_id,
message: message
)
end
end end
end end
end end
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
= _('Add user(s) to the group:') = _('Add user(s) to the group:')
.card-body.form-holder .card-body.form-holder
%p.light %p.light
- link_to_help = link_to(_("here"), help_page_path("user/permissions"), class: "vlink") - link_to_help = link_to(_("here"), help_page_path("user/permissions"))
= _('Read more about project permissions <strong>%{link_to_help}</strong>').html_safe % { link_to_help: link_to_help } = _('Read more about project permissions <strong>%{link_to_help}</strong>').html_safe % { link_to_help: link_to_help }
= form_tag admin_group_members_update_path(@group), id: "new_project_member", class: "bulk_import", method: :put do = form_tag admin_group_members_update_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
Edit System Hook Edit System Hook
%p.light %p.light
#{link_to 'System hooks ', help_page_path('system_hooks/system_hooks'), class: 'vlink'} can be #{link_to 'System hooks ', help_page_path('system_hooks/system_hooks')} can be
used for binding events when GitLab creates a User or Project. used for binding events when GitLab creates a User or Project.
%hr %hr
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
%h4.prepend-top-0 %h4.prepend-top-0
= page_title = page_title
%p %p
#{link_to 'System hooks ', help_page_path('system_hooks/system_hooks'), class: 'vlink'} can be #{link_to 'System hooks ', help_page_path('system_hooks/system_hooks')} can be
used for binding events when GitLab creates a User or Project. used for binding events when GitLab creates a User or Project.
.col-lg-8.append-bottom-default .col-lg-8.append-bottom-default
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
.col-md-3.col-lg-2 .col-md-3.col-lg-2
= select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "form-control project-access-select" = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "form-control project-access-select"
.form-text.text-muted.append-bottom-10 .form-text.text-muted.append-bottom-10
= link_to "Read more", help_page_path("user/permissions"), class: "vlink" = link_to "Read more", help_page_path("user/permissions")
about role permissions about role permissions
.col-md-3.col-lg-2 .col-md-3.col-lg-2
......
...@@ -10,12 +10,12 @@ ...@@ -10,12 +10,12 @@
%span.append-right-4.js-clone-dropdown-label %span.append-right-4.js-clone-dropdown-label
= _('Clone') = _('Clone')
= sprite_icon("arrow-down", css_class: "icon") = sprite_icon("arrow-down", css_class: "icon")
%form.p-3.dropdown-menu.dropdown-menu-right.dropdown-menu-large.dropdown-menu-selectable.clone-options-dropdown %form.p-3.dropdown-menu.dropdown-menu-right.dropdown-menu-large.dropdown-menu-selectable.clone-options-dropdown.qa-clone-options
%li.pb-2 %li.pb-2
%label.label-bold %label.label-bold
= _('Clone with SSH') = _('Clone with SSH')
.input-group .input-group
= text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' } = text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control qa-ssh-clone-url", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append .input-group-append
= clipboard_button(target: '#ssh_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard") = clipboard_button(target: '#ssh_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo' = render_if_exists 'projects/buttons/geo'
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
%label.label-bold %label.label-bold
= _('Clone with %{http_label}') % { http_label: gitlab_config.protocol.upcase } = _('Clone with %{http_label}') % { http_label: gitlab_config.protocol.upcase }
.input-group .input-group
= text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' } = text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control qa-http-clone-url", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append .input-group-append
= clipboard_button(target: '#http_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard") = clipboard_button(target: '#http_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo' = render_if_exists 'projects/buttons/geo'
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
.prepend-top-20 .prepend-top-20
%nav.project-buttons %nav.project-buttons
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller .scrolling-tabs-container.inner-page-scroll-tabs.is-smaller.qa-quick-actions
.fade-left= icon('angle-left') .fade-left= icon('angle-left')
.fade-right= icon('angle-right') .fade-right= icon('angle-right')
.nav-links.scrolling-tabs.quick-links .nav-links.scrolling-tabs.quick-links
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= select_tag :link_group_access, options_for_select(ProjectGroupLink.access_options, ProjectGroupLink.default_access), class: "form-control select-control" = select_tag :link_group_access, options_for_select(ProjectGroupLink.access_options, ProjectGroupLink.default_access), class: "form-control select-control"
= icon('chevron-down') = icon('chevron-down')
.form-text.text-muted.append-bottom-10 .form-text.text-muted.append-bottom-10
= link_to _("Read more"), help_page_path("user/permissions"), class: "vlink" = link_to _("Read more"), help_page_path("user/permissions")
about role permissions about role permissions
.form-group .form-group
= label_tag :expires_at, _('Access expiration date'), class: 'label-bold' = label_tag :expires_at, _('Access expiration date'), class: 'label-bold'
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "form-control project-access-select select-control" = select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "form-control project-access-select select-control"
= icon('chevron-down') = icon('chevron-down')
.form-text.text-muted.append-bottom-10 .form-text.text-muted.append-bottom-10
= link_to "Read more", help_page_path("user/permissions"), class: "vlink" = link_to "Read more", help_page_path("user/permissions")
about role permissions about role permissions
.form-group .form-group
.clearable-input .clearable-input
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
- if can_collaborate || can_create_mr_from_fork - if can_collaborate || can_create_mr_from_fork
%li.breadcrumb-item %li.breadcrumb-item
%a.btn.add-to-tree{ addtotree_toggle_attributes } %a.btn.add-to-tree.qa-add-to-tree{ addtotree_toggle_attributes }
= sprite_icon('plus', size: 16, css_class: 'float-left') = sprite_icon('plus', size: 16, css_class: 'float-left')
= sprite_icon('arrow-down', size: 16, css_class: 'float-left') = sprite_icon('arrow-down', size: 16, css_class: 'float-left')
- if on_top_of_branch? - if on_top_of_branch?
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
%li.dropdown-header %li.dropdown-header
#{ _('This directory') } #{ _('This directory') }
%li %li
= link_to project_new_blob_path(@project, @id) do = link_to project_new_blob_path(@project, @id), class: 'qa-new-file-option' do
#{ _('New file') } #{ _('New file') }
%li %li
= link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } do = link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } do
......
...@@ -16,6 +16,7 @@ module.exports = { ...@@ -16,6 +16,7 @@ module.exports = {
testMatch: ['<rootDir>/spec/frontend/**/*_spec.js'], testMatch: ['<rootDir>/spec/frontend/**/*_spec.js'],
moduleNameMapper: { moduleNameMapper: {
'^~(.*)$': '<rootDir>/app/assets/javascripts$1', '^~(.*)$': '<rootDir>/app/assets/javascripts$1',
'^helpers(.*)$': '<rootDir>/spec/frontend/helpers$1',
}, },
collectCoverageFrom: ['<rootDir>/app/assets/javascripts/**/*.{js,vue}'], collectCoverageFrom: ['<rootDir>/app/assets/javascripts/**/*.{js,vue}'],
coverageDirectory: '<rootDir>/coverage-frontend/', coverageDirectory: '<rootDir>/coverage-frontend/',
...@@ -23,5 +24,6 @@ module.exports = { ...@@ -23,5 +24,6 @@ module.exports = {
cacheDirectory: '<rootDir>/tmp/cache/jest', cacheDirectory: '<rootDir>/tmp/cache/jest',
modulePathIgnorePatterns: ['<rootDir>/.yarn-cache/'], modulePathIgnorePatterns: ['<rootDir>/.yarn-cache/'],
reporters, reporters,
rootDir: '..', // necessary because this file is in the config/ subdirectory setupTestFrameworkScriptFile: '<rootDir>/spec/frontend/test_setup.js',
restoreMocks: true,
}; };
...@@ -32,6 +32,9 @@ module Gitlab ...@@ -32,6 +32,9 @@ module Gitlab
return true if pipeline.source == pattern return true if pipeline.source == pattern
return true if pipeline.source&.pluralize == pattern return true if pipeline.source&.pluralize == pattern
# patterns can be matched only when branch or tag is used
# the pattern matching does not work for merge requests pipelines
if pipeline.branch? || pipeline.tag?
if pattern.first == "/" && pattern.last == "/" if pattern.first == "/" && pattern.last == "/"
Regexp.new(pattern[1...-1]) =~ pipeline.ref Regexp.new(pattern[1...-1]) =~ pipeline.ref
else else
...@@ -42,4 +45,5 @@ module Gitlab ...@@ -42,4 +45,5 @@ module Gitlab
end end
end end
end end
end
end end
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
"eslint": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue .", "eslint": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue .",
"eslint-fix": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue --fix .", "eslint-fix": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue --fix .",
"eslint-report": "eslint --max-warnings 0 --ext .js,.vue --format html --output-file ./eslint-report.html --no-inline-config .", "eslint-report": "eslint --max-warnings 0 --ext .js,.vue --format html --output-file ./eslint-report.html --no-inline-config .",
"jest": "BABEL_ENV=jest jest --config=config/jest.config.js", "jest": "BABEL_ENV=jest jest",
"karma": "BABEL_ENV=${BABEL_ENV:=karma} karma start --single-run true config/karma.config.js", "karma": "BABEL_ENV=${BABEL_ENV:=karma} karma start --single-run true config/karma.config.js",
"karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js", "karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js",
"karma-start": "BABEL_ENV=karma karma start config/karma.config.js", "karma-start": "BABEL_ENV=karma karma start config/karma.config.js",
......
...@@ -273,6 +273,7 @@ module QA ...@@ -273,6 +273,7 @@ module QA
# #
module Component module Component
autoload :ClonePanel, 'qa/page/component/clone_panel' autoload :ClonePanel, 'qa/page/component/clone_panel'
autoload :LegacyClonePanel, 'qa/page/component/legacy_clone_panel'
autoload :Dropzone, 'qa/page/component/dropzone' autoload :Dropzone, 'qa/page/component/dropzone'
autoload :GroupsFilter, 'qa/page/component/groups_filter' autoload :GroupsFilter, 'qa/page/component/groups_filter'
autoload :Select2, 'qa/page/component/select2' autoload :Select2, 'qa/page/component/select2'
......
...@@ -132,6 +132,10 @@ module QA ...@@ -132,6 +132,10 @@ module QA
Page::Element.new(name).selector_css Page::Element.new(name).selector_css
end end
def click_link_with_text(text)
click_link text
end
def self.path def self.path
raise NotImplementedError raise NotImplementedError
end end
......
...@@ -5,26 +5,20 @@ module QA ...@@ -5,26 +5,20 @@ module QA
module Component module Component
module ClonePanel module ClonePanel
def self.included(base) def self.included(base)
base.view 'app/views/shared/_clone_panel.html.haml' do base.view 'app/views/projects/buttons/_clone.html.haml' do
element :clone_dropdown element :clone_dropdown
element :clone_options_dropdown, '.clone-options-dropdown' # rubocop:disable QA/ElementWithPattern element :clone_options
element :project_repository_location, 'text_field_tag :project_clone' # rubocop:disable QA/ElementWithPattern element :ssh_clone_url
element :http_clone_url
end end
end end
def choose_repository_clone_http def repository_clone_http_location
choose_repository_clone('HTTP', 'http') repository_clone_location(:http_clone_url)
end end
def choose_repository_clone_ssh def repository_clone_ssh_location
# It's not always beginning with ssh:// so detecting with @ repository_clone_location(:ssh_clone_url)
# would be more reliable because ssh would always contain it.
# We can't use .git because HTTP also contain that part.
choose_repository_clone('SSH', '@')
end
def repository_location
Git::Location.new(find('#project_clone').value)
end end
def wait_for_push def wait_for_push
...@@ -34,16 +28,13 @@ module QA ...@@ -34,16 +28,13 @@ module QA
private private
def choose_repository_clone(kind, detect_text) def repository_clone_location(kind)
wait(reload: false) do wait(reload: false) do
click_element :clone_dropdown click_element :clone_dropdown
page.within('.clone-options-dropdown') do within_element :clone_options do
click_link(kind) Git::Location.new(find_element(kind).value)
end end
# Ensure git clone textbox was updated
repository_location.git_uri.include?(detect_text)
end end
end end
end end
......
# frozen_string_literal: true
module QA
module Page
module Component
module LegacyClonePanel
def self.included(base)
base.view 'app/views/shared/_clone_panel.html.haml' do
element :clone_dropdown
element :clone_options_dropdown, '.clone-options-dropdown' # rubocop:disable QA/ElementWithPattern
element :project_repository_location, 'text_field_tag :project_clone' # rubocop:disable QA/ElementWithPattern
end
end
def choose_repository_clone_http
choose_repository_clone('HTTP', 'http')
end
def choose_repository_clone_ssh
# It's not always beginning with ssh:// so detecting with @
# would be more reliable because ssh would always contain it.
# We can't use .git because HTTP also contain that part.
choose_repository_clone('SSH', '@')
end
def repository_location
Git::Location.new(find('#project_clone').value)
end
def wait_for_push
sleep 5
refresh
end
private
def choose_repository_clone(kind, detect_text)
wait(reload: false) do
click_element :clone_dropdown
page.within('.clone-options-dropdown') do
click_link(kind)
end
# Ensure git clone textbox was updated
repository_location.git_uri.include?(detect_text)
end
end
end
end
end
end
...@@ -29,11 +29,9 @@ module QA ...@@ -29,11 +29,9 @@ module QA
element :fly_out, "classList.add('fly-out-list')" # rubocop:disable QA/ElementWithPattern element :fly_out, "classList.add('fly-out-list')" # rubocop:disable QA/ElementWithPattern
end end
def click_repository_settings def click_ci_cd_pipelines
hover_settings do within_sidebar do
within_submenu do click_element :link_pipelines
click_link('Repository')
end
end end
end end
...@@ -45,11 +43,9 @@ module QA ...@@ -45,11 +43,9 @@ module QA
end end
end end
def click_operations_environments def click_issues
hover_operations do within_sidebar do
within_submenu do click_link('Issues')
click_element(:operations_environments_link)
end
end end
end end
...@@ -61,61 +57,71 @@ module QA ...@@ -61,61 +57,71 @@ module QA
end end
end end
def click_operations_kubernetes def click_merge_requests
within_sidebar do
click_link('Merge Requests')
end
end
def click_operations_environments
hover_operations do hover_operations do
within_submenu do within_submenu do
click_link('Kubernetes') click_element(:operations_environments_link)
end end
end end
end end
def click_ci_cd_pipelines def click_operations_kubernetes
within_sidebar do hover_operations do
click_element :link_pipelines within_submenu do
click_link('Kubernetes')
end
end end
end end
def go_to_settings def click_milestones
within_sidebar do within_sidebar do
click_on 'Settings' click_element :milestones_link
end end
end end
def click_issues def click_repository
within_sidebar do within_sidebar do
click_link('Issues') click_link('Repository')
end end
end end
def go_to_labels def click_repository_settings
hover_issues do hover_settings do
within_submenu do within_submenu do
click_element(:labels_link) click_link('Repository')
end end
end end
end end
def click_merge_requests def click_wiki
within_sidebar do within_sidebar do
click_link('Merge Requests') click_link('Wiki')
end end
end end
def click_milestones def go_to_activity
within_sidebar do within_sidebar do
click_element :milestones_link click_on 'Activity'
end end
end end
def click_wiki def go_to_labels
within_sidebar do hover_issues do
click_link('Wiki') within_submenu do
click_element(:labels_link)
end
end end
end end
def click_repository def go_to_settings
within_sidebar do within_sidebar do
click_link('Repository') click_on 'Settings'
end end
end end
...@@ -129,17 +135,17 @@ module QA ...@@ -129,17 +135,17 @@ module QA
end end
end end
def hover_settings def hover_operations
within_sidebar do within_sidebar do
find('.qa-settings-item').hover find('.shortcuts-operations').hover
yield yield
end end
end end
def hover_operations def hover_settings
within_sidebar do within_sidebar do
find('.shortcuts-operations').hover find('.qa-settings-item').hover
yield yield
end end
...@@ -151,12 +157,6 @@ module QA ...@@ -151,12 +157,6 @@ module QA
end end
end end
def go_to_activity
within_sidebar do
click_on 'Activity'
end
end
def within_submenu def within_submenu
page.within('.fly-out-list') do page.within('.fly-out-list') do
yield yield
......
...@@ -8,6 +8,11 @@ module QA ...@@ -8,6 +8,11 @@ module QA
include Page::Component::ClonePanel include Page::Component::ClonePanel
view 'app/views/layouts/header/_new_dropdown.haml' do
element :new_menu_toggle
element :new_issue_link, "link_to _('New issue'), new_project_issue_path(@project)" # rubocop:disable QA/ElementWithPattern
end
view 'app/views/projects/_last_push.html.haml' do view 'app/views/projects/_last_push.html.haml' do
element :create_merge_request element :create_merge_request
end end
...@@ -16,14 +21,12 @@ module QA ...@@ -16,14 +21,12 @@ module QA
element :project_name element :project_name
end end
view 'app/views/layouts/header/_new_dropdown.haml' do view 'app/views/projects/_files.html.haml' do
element :new_menu_toggle element :tree_holder, '.tree-holder' # rubocop:disable QA/ElementWithPattern
element :new_issue_link, "link_to _('New issue'), new_project_issue_path(@project)" # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/shared/_ref_switcher.html.haml' do view 'app/views/projects/buttons/_dropdown.html.haml' do
element :branches_select element :create_new_dropdown
element :branches_dropdown
end end
view 'app/views/projects/buttons/_fork.html.haml' do view 'app/views/projects/buttons/_fork.html.haml' do
...@@ -31,44 +34,50 @@ module QA ...@@ -31,44 +34,50 @@ module QA
element :fork_link, "link_to new_project_fork_path(@project)" # rubocop:disable QA/ElementWithPattern element :fork_link, "link_to new_project_fork_path(@project)" # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/projects/_files.html.haml' do view 'app/views/projects/empty.html.haml' do
element :tree_holder, '.tree-holder' # rubocop:disable QA/ElementWithPattern element :quick_actions
end end
view 'app/views/projects/buttons/_dropdown.html.haml' do view 'app/views/projects/tree/_tree_content.html.haml' do
element :create_new_dropdown element :file_tree
element :new_file_option
end end
view 'app/views/projects/tree/_tree_header.html.haml' do view 'app/views/projects/tree/_tree_header.html.haml' do
element :add_to_tree
element :new_file_option
element :web_ide_button element :web_ide_button
end end
view 'app/views/projects/tree/_tree_content.html.haml' do view 'app/views/shared/_ref_switcher.html.haml' do
element :file_tree element :branches_select
element :branches_dropdown
end end
def project_name def create_first_new_file!
find('.qa-project-name').text within_element(:quick_actions) do
click_link_with_text 'New file'
end
end end
def create_new_file! def create_new_file!
click_element :create_new_dropdown click_element :add_to_tree
click_element :new_file_option click_element :new_file_option
end end
def fork_project
click_on 'Fork'
end
def go_to_file(filename) def go_to_file(filename)
within_element(:file_tree) do within_element(:file_tree) do
click_on filename click_on filename
end end
end end
def switch_to_branch(branch_name) def go_to_new_issue
find_element(:branches_select).click click_element :new_menu_toggle
within_element(:branches_dropdown) do click_link 'New issue'
click_on branch_name
end
end end
def last_commit_content def last_commit_content
...@@ -83,24 +92,26 @@ module QA ...@@ -83,24 +92,26 @@ module QA
click_element :create_merge_request click_element :create_merge_request
end end
def wait_for_import def open_web_ide!
wait(reload: true) do click_element :web_ide_button
has_css?('.tree-holder')
end end
def project_name
find('.qa-project-name').text
end end
def go_to_new_issue def switch_to_branch(branch_name)
click_element :new_menu_toggle find_element(:branches_select).click
click_link 'New issue' within_element(:branches_dropdown) do
click_on branch_name
end end
def fork_project
click_on 'Fork'
end end
def open_web_ide! def wait_for_import
click_element :web_ide_button wait(reload: true) do
has_css?('.tree-holder')
end
end end
end end
end end
......
...@@ -5,7 +5,7 @@ module QA ...@@ -5,7 +5,7 @@ module QA
module Project module Project
module Wiki module Wiki
class Show < Page::Base class Show < Page::Base
include Page::Component::ClonePanel include Page::Component::LegacyClonePanel
view 'app/views/projects/wikis/pages.html.haml' do view 'app/views/projects/wikis/pages.html.haml' do
element :clone_repository_link, 'Clone repository' # rubocop:disable QA/ElementWithPattern element :clone_repository_link, 'Clone repository' # rubocop:disable QA/ElementWithPattern
......
...@@ -22,7 +22,7 @@ module QA ...@@ -22,7 +22,7 @@ module QA
def fabricate! def fabricate!
project.visit! project.visit!
Page::Project::Show.perform(&:create_new_file!) Page::Project::Show.perform(&:create_first_new_file!)
Page::File::Form.perform do |page| Page::File::Form.perform do |page|
page.add_name(@name) page.add_name(@name)
......
...@@ -14,15 +14,13 @@ module QA ...@@ -14,15 +14,13 @@ module QA
attribute :repository_ssh_location do attribute :repository_ssh_location do
Page::Project::Show.perform do |page| Page::Project::Show.perform do |page|
page.choose_repository_clone_ssh page.repository_clone_ssh_location
page.repository_location
end end
end end
attribute :repository_http_location do attribute :repository_http_location do
Page::Project::Show.perform do |page| Page::Project::Show.perform do |page|
page.choose_repository_clone_http page.repository_clone_http_location
page.repository_location
end end
end end
......
...@@ -20,23 +20,11 @@ module QA ...@@ -20,23 +20,11 @@ module QA
end end
def repository_http_uri def repository_http_uri
@repository_http_uri ||= begin @repository_http_uri ||= project.repository_http_location.uri
project.visit!
Page::Project::Show.act do
choose_repository_clone_http
repository_location.uri
end
end
end end
def repository_ssh_uri def repository_ssh_uri
@repository_ssh_uri ||= begin @repository_ssh_uri ||= project.repository_ssh_location.uri
project.visit!
Page::Project::Show.act do
choose_repository_clone_ssh
repository_location.uri
end
end
end end
end end
end end
......
...@@ -5,17 +5,17 @@ module QA ...@@ -5,17 +5,17 @@ module QA
describe 'Project activity' do describe 'Project activity' do
it 'user creates an event in the activity page upon Git push' do it 'user creates an event in the activity page upon Git push' do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
Resource::Repository::ProjectPush.fabricate! do |push| project_push = Resource::Repository::ProjectPush.fabricate! do |push|
push.file_name = 'README.md' push.file_name = 'README.md'
push.file_content = '# This is a test project' push.file_content = '# This is a test project'
push.commit_message = 'Add README.md' push.commit_message = 'Add README.md'
end end
project_push.project.visit!
Page::Project::Menu.act { go_to_activity } Page::Project::Menu.perform(&:go_to_activity)
Page::Project::Activity.perform(&:go_to_push_events)
Page::Project::Activity.act { go_to_push_events }
expect(page).to have_content('pushed new branch master') expect(page).to have_content('pushed new branch master')
end end
......
...@@ -5,7 +5,7 @@ module QA ...@@ -5,7 +5,7 @@ module QA
describe 'Merge request squashing' do describe 'Merge request squashing' do
it 'user squashes commits while merging' do it 'user squashes commits while merging' do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
project = Resource::Project.fabricate! do |project| project = Resource::Project.fabricate! do |project|
project.name = "squash-before-merge" project.name = "squash-before-merge"
...@@ -38,13 +38,12 @@ module QA ...@@ -38,13 +38,12 @@ module QA
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = Page::Project::Show.act do repository.uri = Page::Project::Show.act do
choose_repository_clone_http repository_clone_http_location.uri
repository_location.uri
end end
repository.use_default_credentials repository.use_default_credentials
repository.act { clone } repository.clone
expect(repository.commits.size).to eq 3 expect(repository.commits.size).to eq 3
end end
......
...@@ -7,7 +7,7 @@ module QA ...@@ -7,7 +7,7 @@ module QA
def login def login
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
end end
before(:all) do before(:all) do
...@@ -18,7 +18,15 @@ module QA ...@@ -18,7 +18,15 @@ module QA
project.description = 'Add file templates via the Files view' project.description = 'Add file templates via the Files view'
end end
Page::Main::Menu.act { sign_out } # There's no 'New File' dropdown when the project is blank, so we first
# add a dummy file so that the dropdown will appear
Resource::File.fabricate! do |file|
file.project = @project
file.name = 'README.md'
file.content = '# Readme'
end
Page::Main::Menu.perform(&:sign_out)
end end
templates = [ templates = [
...@@ -55,7 +63,7 @@ module QA ...@@ -55,7 +63,7 @@ module QA
login login
@project.visit! @project.visit!
Page::Project::Show.act { create_new_file! } Page::Project::Show.perform(&:create_new_file!)
Page::File::Form.perform do |page| Page::File::Form.perform do |page|
page.select_template template[:file_name], template[:name] page.select_template template[:file_name], template[:name]
end end
......
...@@ -4,15 +4,12 @@ module QA ...@@ -4,15 +4,12 @@ module QA
context 'Create' do context 'Create' do
describe 'Git clone over HTTP', :ldap_no_tls do describe 'Git clone over HTTP', :ldap_no_tls do
let(:location) do let(:location) do
Page::Project::Show.act do Page::Project::Show.perform(&:repository_clone_http_location).uri
choose_repository_clone_http
repository_location
end
end end
before do before do
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
project = Resource::Project.fabricate! do |scenario| project = Resource::Project.fabricate! do |scenario|
scenario.name = 'project-with-code' scenario.name = 'project-with-code'
...@@ -21,7 +18,7 @@ module QA ...@@ -21,7 +18,7 @@ module QA
project.visit! project.visit!
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = location.uri repository.uri = location
repository.use_default_credentials repository.use_default_credentials
repository.act do repository.act do
...@@ -32,14 +29,15 @@ module QA ...@@ -32,14 +29,15 @@ module QA
push_changes push_changes
end end
end end
Page::Project::Show.perform(&:wait_for_push)
end end
it 'user performs a deep clone' do it 'user performs a deep clone' do
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = location.uri repository.uri = location
repository.use_default_credentials repository.use_default_credentials
repository.act { clone } repository.clone
expect(repository.commits.size).to eq 2 expect(repository.commits.size).to eq 2
end end
...@@ -47,10 +45,10 @@ module QA ...@@ -47,10 +45,10 @@ module QA
it 'user performs a shallow clone' do it 'user performs a shallow clone' do
Git::Repository.perform do |repository| Git::Repository.perform do |repository|
repository.uri = location.uri repository.uri = location
repository.use_default_credentials repository.use_default_credentials
repository.act { shallow_clone } repository.shallow_clone
expect(repository.commits.size).to eq 1 expect(repository.commits.size).to eq 1
expect(repository.commits.first).to include 'Add Readme' expect(repository.commits.first).to include 'Add Readme'
......
...@@ -7,12 +7,12 @@ module QA ...@@ -7,12 +7,12 @@ module QA
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.act { sign_in_using_credentials }
Resource::Repository::ProjectPush.fabricate! do |push| project_push = Resource::Repository::ProjectPush.fabricate! do |push|
push.file_name = 'README.md' push.file_name = 'README.md'
push.file_content = '# This is a test project' push.file_content = '# This is a test project'
push.commit_message = 'Add README.md' push.commit_message = 'Add README.md'
end end
project_push.project.visit!
Page::Project::Show.act { wait_for_push } Page::Project::Show.act { wait_for_push }
expect(page).to have_content('README.md') expect(page).to have_content('README.md')
......
...@@ -16,13 +16,14 @@ module QA ...@@ -16,13 +16,14 @@ module QA
resource.title = key_title resource.title = key_title
end end
Resource::Repository::ProjectPush.fabricate! do |push| project_push = Resource::Repository::ProjectPush.fabricate! do |push|
push.ssh_key = key push.ssh_key = key
push.file_name = 'README.md' push.file_name = 'README.md'
push.file_content = '# Test Use SSH Key' push.file_content = '# Test Use SSH Key'
push.commit_message = 'Add README.md' push.commit_message = 'Add README.md'
end end
project_push.project.visit!
Page::Project::Show.act { wait_for_push } Page::Project::Show.act { wait_for_push }
expect(page).to have_content('README.md') expect(page).to have_content('README.md')
......
...@@ -7,7 +7,7 @@ module QA ...@@ -7,7 +7,7 @@ module QA
def login def login
Runtime::Browser.visit(:gitlab, Page::Main::Login) Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials } Page::Main::Login.perform(&:sign_in_using_credentials)
end end
before(:all) do before(:all) do
...@@ -21,14 +21,14 @@ module QA ...@@ -21,14 +21,14 @@ module QA
# Add a file via the regular Files view because the Web IDE isn't # Add a file via the regular Files view because the Web IDE isn't
# available unless there is a file present # available unless there is a file present
Page::Project::Show.act { create_new_file! } Page::Project::Show.perform(&:create_first_new_file!)
Page::File::Form.perform do |page| Page::File::Form.perform do |page|
page.add_name('dummy') page.add_name('dummy')
page.add_content('Enable the Web IDE') page.add_content('Enable the Web IDE')
page.commit_changes page.commit_changes
end end
Page::Main::Menu.act { sign_out } Page::Main::Menu.perform(&:sign_out)
end end
templates = [ templates = [
...@@ -65,7 +65,7 @@ module QA ...@@ -65,7 +65,7 @@ module QA
login login
@project.visit! @project.visit!
Page::Project::Show.act { open_web_ide! } Page::Project::Show.perform(&:open_web_ide!)
Page::Project::WebIDE::Edit.perform do |page| Page::Project::WebIDE::Edit.perform do |page|
page.create_new_file_from_template template[:file_name], template[:name] page.create_new_file_from_template template[:file_name], template[:name]
...@@ -75,9 +75,7 @@ module QA ...@@ -75,9 +75,7 @@ module QA
expect(page).to have_button('Undo') expect(page).to have_button('Undo')
expect(page).to have_content(content[0..100]) expect(page).to have_content(content[0..100])
Page::Project::WebIDE::Edit.perform do |page| Page::Project::WebIDE::Edit.perform(&:commit_changes)
page.commit_changes
end
expect(page).to have_content(template[:file_name]) expect(page).to have_content(template[:file_name])
expect(page).to have_content(content[0..100]) expect(page).to have_content(content[0..100])
......
...@@ -6,4 +6,4 @@ plugins: ...@@ -6,4 +6,4 @@ plugins:
settings: settings:
import/resolver: import/resolver:
jest: jest:
jestConfigFile: "config/jest.config.js" jestConfigFile: "jest.config.js"
// eslint-disable-next-line import/prefer-default-export
export const TEST_HOST = 'http://test.host';
import $ from 'jquery'; import $ from 'jquery';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import EmojiMenu from '~/pages/profiles/show/emoji_menu'; import EmojiMenu from '~/pages/profiles/show/emoji_menu';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
describe('EmojiMenu', () => { describe('EmojiMenu', () => {
const dummyEmojiTag = '<dummy></tag>'; const dummyEmojiTag = '<dummy></tag>';
...@@ -56,7 +56,7 @@ describe('EmojiMenu', () => { ...@@ -56,7 +56,7 @@ describe('EmojiMenu', () => {
}); });
it('does not make an axios requst', done => { it('does not make an axios requst', done => {
spyOn(axios, 'request').and.stub(); jest.spyOn(axios, 'request').mockReturnValue();
emojiMenu.addAward(dummyVotesBlock(), dummyAwardUrl, dummyEmoji, false, () => { emojiMenu.addAward(dummyVotesBlock(), dummyAwardUrl, dummyEmoji, false, () => {
expect(axios.request).not.toHaveBeenCalled(); expect(axios.request).not.toHaveBeenCalled();
...@@ -67,7 +67,7 @@ describe('EmojiMenu', () => { ...@@ -67,7 +67,7 @@ describe('EmojiMenu', () => {
describe('bindEvents', () => { describe('bindEvents', () => {
beforeEach(() => { beforeEach(() => {
spyOn(emojiMenu, 'registerEventListener').and.stub(); jest.spyOn(emojiMenu, 'registerEventListener').mockReturnValue();
}); });
it('binds event listeners to custom toggle button', () => { it('binds event listeners to custom toggle button', () => {
......
const testTimeoutInMs = 300;
jest.setTimeout(testTimeoutInMs);
let testStartTime;
// https://github.com/facebook/jest/issues/6947
beforeEach(() => {
testStartTime = Date.now();
});
afterEach(() => {
const elapsedTimeInMs = Date.now() - testStartTime;
if (elapsedTimeInMs > testTimeoutInMs) {
throw new Error(`Test took too long (${elapsedTimeInMs}ms > ${testTimeoutInMs}ms)!`);
}
});
...@@ -810,6 +810,64 @@ describe Ci::CreatePipelineService do ...@@ -810,6 +810,64 @@ describe Ci::CreatePipelineService do
end end
end end
end end
context "when config uses regular expression for only keyword" do
let(:config) do
{
build: {
stage: 'build',
script: 'echo',
only: ["/^#{ref_name}$/"]
}
}
end
context 'when merge request is specified' do
let(:merge_request) do
create(:merge_request,
source_project: project,
source_branch: ref_name,
target_project: project,
target_branch: 'master')
end
it 'does not create a merge request pipeline' do
expect(pipeline).not_to be_persisted
expect(pipeline.errors[:base])
.to eq(['No stages / jobs for this pipeline.'])
end
end
end
context "when config has 'except: [tags]'" do
let(:config) do
{
build: {
stage: 'build',
script: 'echo',
except: ['tags']
}
}
end
context 'when merge request is specified' do
let(:merge_request) do
create(:merge_request,
source_project: project,
source_branch: ref_name,
target_project: project,
target_branch: 'master')
end
it 'does not create a merge request pipeline' do
expect(pipeline).not_to be_persisted
expect(pipeline.errors[:base])
.to eq(['No stages / jobs for this pipeline.'])
end
end
end
end end
context 'when source is web' do context 'when source is web' 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