Commit 687fa664 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'ml-qa-add-file-templates' into 'master'

Add test of adding file templates via Web IDE and Files view

See merge request gitlab-org/gitlab-ce!21914
parents 1e93657c d36055cb
...@@ -117,7 +117,7 @@ export default { ...@@ -117,7 +117,7 @@ export default {
<button <button
:disabled="!hasChanges" :disabled="!hasChanges"
type="button" type="button"
class="btn btn-primary btn-sm btn-block" class="btn btn-primary btn-sm btn-block qa-begin-commit-button"
@click="toggleIsSmall" @click="toggleIsSmall"
> >
{{ __('Commit…') }} {{ __('Commit…') }}
...@@ -147,7 +147,7 @@ export default { ...@@ -147,7 +147,7 @@ export default {
<loading-button <loading-button
:loading="submitCommitLoading" :loading="submitCommitLoading"
:label="commitButtonText" :label="commitButtonText"
container-class="btn btn-success btn-sm float-left" container-class="btn btn-success btn-sm float-left qa-commit-button"
@click="commitChanges" @click="commitChanges"
/> />
<button <button
......
...@@ -47,7 +47,7 @@ export default { ...@@ -47,7 +47,7 @@ export default {
</script> </script>
<template> <template>
<div class="d-flex align-items-center ide-file-templates"> <div class="d-flex align-items-center ide-file-templates qa-file-templates-bar">
<strong class="append-right-default"> <strong class="append-right-default">
{{ __('File templates') }} {{ __('File templates') }}
</strong> </strong>
...@@ -63,7 +63,7 @@ export default { ...@@ -63,7 +63,7 @@ export default {
:is-async-data="true" :is-async-data="true"
:searchable="true" :searchable="true"
:title="__('File templates')" :title="__('File templates')"
class="mr-2" class="mr-2 qa-file-template-dropdown"
@click="selectTemplate" @click="selectTemplate"
/> />
<transition name="fade"> <transition name="fade">
......
...@@ -92,7 +92,7 @@ export default { ...@@ -92,7 +92,7 @@ export default {
v-model="search" v-model="search"
:placeholder="__('Filter...')" :placeholder="__('Filter...')"
type="search" type="search"
class="dropdown-input-field" class="dropdown-input-field qa-dropdown-filter-input"
/> />
<i <i
aria-hidden="true" aria-hidden="true"
......
...@@ -45,7 +45,7 @@ export default { ...@@ -45,7 +45,7 @@ export default {
<new-entry-button <new-entry-button
:label="__('New file')" :label="__('New file')"
:show-label="false" :show-label="false"
class="d-flex border-0 p-0 mr-3" class="d-flex border-0 p-0 mr-3 qa-new-file"
icon="doc-new" icon="doc-new"
@click="openNewEntryModal({ type: 'blob' })" @click="openNewEntryModal({ type: 'blob' })"
/> />
......
...@@ -43,7 +43,7 @@ export default { ...@@ -43,7 +43,7 @@ export default {
<template> <template>
<div <div
class="ide-file-list" class="ide-file-list qa-file-list"
> >
<template v-if="showLoading"> <template v-if="showLoading">
<div <div
......
...@@ -110,12 +110,12 @@ export default { ...@@ -110,12 +110,12 @@ export default {
ref="fieldName" ref="fieldName"
v-model="entryName" v-model="entryName"
type="text" type="text"
class="form-control" class="form-control qa-full-file-path"
placeholder="/dir/file_name" placeholder="/dir/file_name"
/> />
<ul <ul
v-if="isCreatingNew" v-if="isCreatingNew"
class="prepend-top-default list-inline" class="prepend-top-default list-inline qa-template-list"
> >
<li <li
v-for="(template, index) in templateTypes" v-for="(template, index) in templateTypes"
......
...@@ -41,10 +41,14 @@ export default { ...@@ -41,10 +41,14 @@ export default {
}, },
}, },
mounted() { mounted() {
$(this.$el).on('shown.bs.modal', this.opened).on('hidden.bs.modal', this.closed); $(this.$el)
.on('shown.bs.modal', this.opened)
.on('hidden.bs.modal', this.closed);
}, },
beforeDestroy() { beforeDestroy() {
$(this.$el).off('shown.bs.modal', this.opened).off('hidden.bs.modal', this.closed); $(this.$el)
.off('shown.bs.modal', this.opened)
.off('hidden.bs.modal', this.closed);
}, },
methods: { methods: {
emitCancel(event) { emitCancel(event) {
...@@ -103,7 +107,7 @@ export default { ...@@ -103,7 +107,7 @@ export default {
<slot name="footer"> <slot name="footer">
<button <button
type="button" type="button"
class="btn js-modal-cancel-action" class="btn js-modal-cancel-action qa-modal-cancel-button"
data-dismiss="modal" data-dismiss="modal"
@click="emitCancel($event)" @click="emitCancel($event)"
> >
...@@ -112,7 +116,7 @@ export default { ...@@ -112,7 +116,7 @@ export default {
<button <button
:class="`btn-${footerPrimaryButtonVariant}`" :class="`btn-${footerPrimaryButtonVariant}`"
type="button" type="button"
class="btn js-modal-primary-action" class="btn js-modal-primary-action qa-modal-primary-button"
data-dismiss="modal" data-dismiss="modal"
@click="emitSubmit($event)" @click="emitSubmit($event)"
> >
......
...@@ -3,15 +3,15 @@ ...@@ -3,15 +3,15 @@
Template Template
.template-selector-dropdowns-wrap .template-selector-dropdowns-wrap
.template-type-selector.js-template-type-selector-wrap.hidden .template-type-selector.js-template-type-selector-wrap.hidden
= dropdown_tag("Choose type", options: { toggle_class: 'js-template-type-selector', title: "Choose a template type" } ) = dropdown_tag("Choose type", options: { toggle_class: 'js-template-type-selector qa-template-type-dropdown', title: "Choose a template type" } )
.license-selector.js-license-selector-wrap.js-template-selector-wrap.hidden .license-selector.js-license-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag("Apply a license template", options: { toggle_class: 'js-license-selector', title: "Apply a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } ) = dropdown_tag("Apply a license template", options: { toggle_class: 'js-license-selector qa-license-dropdown', title: "Apply a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } )
.gitignore-selector.js-gitignore-selector-wrap.js-template-selector-wrap.hidden .gitignore-selector.js-gitignore-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag("Apply a .gitignore template", options: { toggle_class: 'js-gitignore-selector', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } ) = dropdown_tag("Apply a .gitignore template", options: { toggle_class: 'js-gitignore-selector qa-gitignore-dropdown', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } )
.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden .gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag("Apply a GitLab CI Yaml template", options: { toggle_class: 'js-gitlab-ci-yml-selector', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } ) = dropdown_tag("Apply a GitLab CI Yaml template", options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } )
.dockerfile-selector.js-dockerfile-selector-wrap.js-template-selector-wrap.hidden .dockerfile-selector.js-dockerfile-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag("Apply a Dockerfile template", options: { toggle_class: 'js-dockerfile-selector', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: dockerfile_names } } ) = dropdown_tag("Apply a Dockerfile template", options: { toggle_class: 'js-dockerfile-selector qa-dockerfile-dropdown', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: dockerfile_names } } )
.template-selectors-undo-menu.hidden .template-selectors-undo-menu.hidden
%span.text-info Template applied %span.text-info Template applied
%button.btn.btn-sm.btn-info Undo %button.btn.btn-sm.btn-info Undo
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
- if show_menu - if show_menu
.project-action-button.dropdown.inline .project-action-button.dropdown.inline
%a.btn.dropdown-toggle.has-tooltip{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...'), 'data-display' => 'static' } %a.btn.dropdown-toggle.has-tooltip.qa-create-new-dropdown{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...'), 'data-display' => 'static' }
= icon('plus') = icon('plus')
= icon("caret-down") = icon("caret-down")
%ul.dropdown-menu.dropdown-menu-right.project-home-dropdown %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
%li.dropdown-header= _('This repository') %li.dropdown-header= _('This repository')
- if can_push_code - if can_push_code
%li= link_to _('New file'), project_new_blob_path(@project, @project.default_branch || 'master') %li.qa-new-file-option= link_to _('New file'), project_new_blob_path(@project, @project.default_branch || 'master')
- unless @project.empty_repo? - unless @project.empty_repo?
%li= link_to _('New branch'), new_project_branch_path(@project) %li= link_to _('New branch'), new_project_branch_path(@project)
%li= link_to _('New tag'), new_project_tag_path(@project) %li= link_to _('New tag'), new_project_tag_path(@project)
......
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
- if can_collaborate - if can_collaborate
= succeed " " do = succeed " " do
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default' do = link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
= _('Web IDE') = _('Web IDE')
= render 'projects/buttons/download', project: @project, ref: @ref = render 'projects/buttons/download', project: @project, ref: @ref
...@@ -16,6 +16,8 @@ module QA ...@@ -16,6 +16,8 @@ module QA
autoload :Browser, 'qa/runtime/browser' autoload :Browser, 'qa/runtime/browser'
autoload :Env, 'qa/runtime/env' autoload :Env, 'qa/runtime/env'
autoload :Address, 'qa/runtime/address' autoload :Address, 'qa/runtime/address'
autoload :Path, 'qa/runtime/path'
autoload :Fixtures, 'qa/runtime/fixtures'
module API module API
autoload :Client, 'qa/runtime/api/client' autoload :Client, 'qa/runtime/api/client'
...@@ -214,6 +216,10 @@ module QA ...@@ -214,6 +216,10 @@ module QA
autoload :New, 'qa/page/project/wiki/new' autoload :New, 'qa/page/project/wiki/new'
autoload :Show, 'qa/page/project/wiki/show' autoload :Show, 'qa/page/project/wiki/show'
end end
module WebIDE
autoload :Edit, 'qa/page/project/web_ide/edit'
end
end end
module Profile module Profile
...@@ -260,6 +266,8 @@ module QA ...@@ -260,6 +266,8 @@ module QA
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'
autoload :DropdownFilter, 'qa/page/component/dropdown_filter'
module Issuable module Issuable
autoload :Common, 'qa/page/component/issuable/common' autoload :Common, 'qa/page/component/issuable/common'
end end
......
# frozen_string_literal: true
module QA module QA
module Factory module Factory
module Resource module Resource
...@@ -19,7 +21,7 @@ module QA ...@@ -19,7 +21,7 @@ module QA
def fabricate! def fabricate!
project.visit! project.visit!
Page::Project::Show.act { go_to_new_file! } Page::Project::Show.act { create_new_file! }
Page::File::Form.perform do |page| Page::File::Form.perform do |page|
page.add_name(@name) page.add_name(@name)
......
# frozen_string_literal: true
require 'capybara/dsl' require 'capybara/dsl'
module QA module QA
...@@ -7,6 +9,8 @@ module QA ...@@ -7,6 +9,8 @@ module QA
include Scenario::Actable include Scenario::Actable
extend SingleForwardable extend SingleForwardable
ElementNotFound = Class.new(RuntimeError)
def_delegators :evaluator, :view, :views def_delegators :evaluator, :view, :views
def refresh def refresh
......
# frozen_string_literal: true
module QA
module Page
module Component
module DropdownFilter
def filter_and_select(item)
wait(reload: false) do
page.has_css?('.dropdown-input-field')
end
find('.dropdown-input-field').set(item)
click_link item
end
end
end
end
end
...@@ -3,6 +3,7 @@ module QA ...@@ -3,6 +3,7 @@ module QA
module File module File
class Form < Page::Base class Form < Page::Base
include Shared::CommitMessage include Shared::CommitMessage
include Page::Component::DropdownFilter
view 'app/views/projects/blob/_editor.html.haml' do view 'app/views/projects/blob/_editor.html.haml' do
element :file_name, "text_field_tag 'file_name'" element :file_name, "text_field_tag 'file_name'"
...@@ -13,6 +14,14 @@ module QA ...@@ -13,6 +14,14 @@ module QA
element :commit_changes, "button_tag 'Commit changes'" element :commit_changes, "button_tag 'Commit changes'"
end end
view 'app/views/projects/blob/_template_selectors.html.haml' do
element :template_type_dropdown
element :gitignore_dropdown
element :gitlab_ci_yml_dropdown
element :dockerfile_dropdown
element :license_dropdown
end
def add_name(name) def add_name(name)
fill_in 'file_name', with: name fill_in 'file_name', with: name
end end
...@@ -29,6 +38,25 @@ module QA ...@@ -29,6 +38,25 @@ module QA
click_on 'Commit changes' click_on 'Commit changes'
end end
def select_template(template_type, template)
click_element :template_type_dropdown
click_link template_type
case template_type
when '.gitignore'
click_element :gitignore_dropdown
when '.gitlab-ci.yml'
click_element :gitlab_ci_yml_dropdown
when 'Dockerfile'
click_element :dockerfile_dropdown
when 'LICENSE'
click_element :license_dropdown
else
raise %Q(Unsupported template_type "#{template_type}". Please confirm that it is a valid option.)
end
filter_and_select template
end
private private
def text_area def text_area
......
# frozen_string_literal: true
module QA module QA
module Page module Page
module Project module Project
...@@ -31,16 +33,22 @@ module QA ...@@ -31,16 +33,22 @@ module QA
element :tree_holder, '.tree-holder' element :tree_holder, '.tree-holder'
end end
view 'app/presenters/project_presenter.rb' do view 'app/views/projects/buttons/_dropdown.html.haml' do
element :new_file_button, "_('New file')," element :create_new_dropdown
element :new_file_option
end
view 'app/views/projects/tree/_tree_header.html.haml' do
element :web_ide_button
end end
def project_name def project_name
find('.qa-project-name').text find('.qa-project-name').text
end end
def go_to_new_file! def create_new_file!
click_on 'New file' click_element :create_new_dropdown
click_element :new_file_option
end end
def switch_to_branch(branch_name) def switch_to_branch(branch_name)
...@@ -78,6 +86,10 @@ module QA ...@@ -78,6 +86,10 @@ module QA
def fork_project def fork_project
click_on 'Fork' click_on 'Fork'
end end
def open_web_ide!
click_element :web_ide_button
end
end end
end end
end end
......
# frozen_string_literal: true
module QA
module Page
module Project
module WebIDE
class Edit < Page::Base
include Page::Component::DropdownFilter
view 'app/assets/javascripts/ide/components/ide_tree.vue' do
element :new_file
end
view 'app/assets/javascripts/ide/components/ide_tree_list.vue' do
element :file_list
end
view 'app/assets/javascripts/ide/components/new_dropdown/modal.vue' do
element :full_file_path
element :template_list
end
view 'app/assets/javascripts/ide/components/file_templates/bar.vue' do
element :file_templates_bar
element :file_template_dropdown
end
view 'app/assets/javascripts/ide/components/file_templates/dropdown.vue' do
element :dropdown_filter_input
end
view 'app/assets/javascripts/ide/components/commit_sidebar/form.vue' do
element :begin_commit_button
element :commit_button
end
def has_file?(file_name)
within_element(:file_list) do
page.has_content? file_name
end
end
def create_new_file_from_template(file_name, template)
click_element :new_file
within_element(:template_list) do
begin
click_on file_name
rescue Capybara::ElementNotFound
raise ElementNotFound, %Q(Couldn't find file template named "#{file_name}". Please confirm that it is a valid option.)
end
end
wait(reload: false) do
within_element(:file_templates_bar) do
click_element :file_template_dropdown
fill_element :dropdown_filter_input, template
begin
click_on template
rescue Capybara::ElementNotFound
raise ElementNotFound, %Q(Couldn't find template "#{template}" for #{file_name}. Please confirm that it exists in the list of templates.)
end
end
end
end
def commit_changes
click_element :begin_commit_button
click_element :commit_button
wait(reload: false) do
page.has_content?('Your changes have been committed')
end
end
end
end
end
end
end
# frozen_string_literal: true
module QA
module Runtime
module Fixtures
def fetch_template_from_api(api_path, key)
request = Runtime::API::Request.new(api_client, "/templates/#{api_path}/#{key}")
get request.url
json_body[:content]
end
private
def api_client
@api_client ||= Runtime::API::Client.new(:gitlab)
end
end
end
end
# frozen_string_literal: true
module QA
module Runtime
module Path
extend self
def qa_root
::File.expand_path('../../', __dir__)
end
end
end
end
# frozen_string_literal: true
module QA
context :create do
describe 'File templates' do
include Runtime::Fixtures
def login
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
end
before(:all) do
login
@project = Factory::Resource::Project.fabricate! do |project|
project.name = 'file-template-project'
project.description = 'Add file templates via the Files view'
end
Page::Menu::Main.act { sign_out }
end
templates = [
{
file_name: '.gitignore',
name: 'Android',
api_path: 'gitignores',
api_key: 'Android'
},
{
file_name: '.gitlab-ci.yml',
name: 'Julia',
api_path: 'gitlab_ci_ymls',
api_key: 'Julia'
},
{
file_name: 'Dockerfile',
name: 'Python',
api_path: 'dockerfiles',
api_key: 'Python'
},
{
file_name: 'LICENSE',
name: 'Mozilla Public License 2.0',
api_path: 'licenses',
api_key: 'mpl-2.0'
}
]
templates.each do |template|
it "user adds #{template[:file_name]} via file template #{template[:name]}" do
content = fetch_template_from_api(template[:api_path], template[:api_key])
login
@project.visit!
Page::Project::Show.act { create_new_file! }
Page::File::Form.perform do |page|
page.select_template template[:file_name], template[:name]
end
expect(page).to have_content('Template applied')
expect(page).to have_button('Undo')
expect(page).to have_content(content[0..100])
Page::File::Form.perform(&:commit_changes)
expect(page).to have_content('The file has been successfully created.')
expect(page).to have_content(template[:file_name])
expect(page).to have_content('Add new file')
expect(page).to have_content(content[0..100])
end
end
end
end
end
# frozen_string_literal: true
module QA
context :create do
describe 'Web IDE file templates' do
include Runtime::Fixtures
def login
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
end
before(:all) do
login
@project = Factory::Resource::Project.fabricate! do |project|
project.name = 'file-template-project'
project.description = 'Add file templates via the Web IDE'
end
# Add a file via the regular Files view because the Web IDE isn't
# available unless there is a file present
Page::Project::Show.act { create_new_file! }
Page::File::Form.perform do |page|
page.add_name('dummy')
page.add_content('Enable the Web IDE')
page.commit_changes
end
Page::Menu::Main.act { sign_out }
end
templates = [
{
file_name: '.gitignore',
name: 'Android',
api_path: 'gitignores',
api_key: 'Android'
},
{
file_name: '.gitlab-ci.yml',
name: 'Julia',
api_path: 'gitlab_ci_ymls',
api_key: 'Julia'
},
{
file_name: 'Dockerfile',
name: 'Python',
api_path: 'dockerfiles',
api_key: 'Python'
},
{
file_name: 'LICENSE',
name: 'Mozilla Public License 2.0',
api_path: 'licenses',
api_key: 'mpl-2.0'
}
]
templates.each do |template|
it "user adds #{template[:file_name]} via file template #{template[:name]}" do
content = fetch_template_from_api(template[:api_path], template[:api_key])
login
@project.visit!
Page::Project::Show.act { open_web_ide! }
Page::Project::WebIDE::Edit.perform do |page|
page.create_new_file_from_template template[:file_name], template[:name]
expect(page.has_file?(template[:file_name])).to be_truthy
end
expect(page).to have_button('Undo')
expect(page).to have_content(content[0..100])
Page::Project::WebIDE::Edit.perform do |page|
page.commit_changes
end
expect(page).to have_content(template[:file_name])
expect(page).to have_content(content[0..100])
end
end
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