Commit e08deb07 authored by Shinya Maeda's avatar Shinya Maeda

Merge branch '27535-new-project-ide' into 'master'

Use Web IDE to create new files in empty repos

See merge request gitlab-org/gitlab!44287
parents 3dea8549 64eba4a3
...@@ -116,6 +116,7 @@ export default { ...@@ -116,6 +116,7 @@ export default {
:placeholder="placeholder" :placeholder="placeholder"
:value="text" :value="text"
class="note-textarea ide-commit-message-textarea" class="note-textarea ide-commit-message-textarea"
data-qa-selector="ide_commit_message_field"
dir="auto" dir="auto"
name="commit-message" name="commit-message"
@scroll="handleScroll" @scroll="handleScroll"
......
...@@ -106,14 +106,26 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -106,14 +106,26 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
add_special_file_path(file_name: 'LICENSE') add_special_file_path(file_name: 'LICENSE')
end end
def add_license_ide_path
ide_edit_path(project, default_branch_or_master, 'LICENSE')
end
def add_changelog_path def add_changelog_path
add_special_file_path(file_name: 'CHANGELOG') add_special_file_path(file_name: 'CHANGELOG')
end end
def add_changelog_ide_path
ide_edit_path(project, default_branch_or_master, 'CHANGELOG')
end
def add_contribution_guide_path def add_contribution_guide_path
add_special_file_path(file_name: 'CONTRIBUTING.md', commit_message: 'Add CONTRIBUTING') add_special_file_path(file_name: 'CONTRIBUTING.md', commit_message: 'Add CONTRIBUTING')
end end
def add_contribution_guide_ide_path
ide_edit_path(project, default_branch_or_master, 'CONTRIBUTING.md')
end
def add_ci_yml_path def add_ci_yml_path
add_special_file_path(file_name: ci_config_path_or_default) add_special_file_path(file_name: ci_config_path_or_default)
end end
...@@ -122,6 +134,10 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -122,6 +134,10 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
add_special_file_path(file_name: 'README.md') add_special_file_path(file_name: 'README.md')
end end
def add_readme_ide_path
ide_edit_path(project, default_branch_or_master, 'README.md')
end
def license_short_name def license_short_name
license = repository.license license = repository.license
license&.nickname || license&.name || 'LICENSE' license&.nickname || license&.name || 'LICENSE'
...@@ -218,9 +234,11 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -218,9 +234,11 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
def new_file_anchor_data def new_file_anchor_data
if current_user && can_current_user_push_to_default_branch? if current_user && can_current_user_push_to_default_branch?
new_file_path = empty_repo? ? ide_edit_path(project, default_branch_or_master) : project_new_blob_path(project, default_branch_or_master)
AnchorData.new(false, AnchorData.new(false,
statistic_icon + _('New file'), statistic_icon + _('New file'),
project_new_blob_path(project, default_branch_or_master), new_file_path,
'missing') 'missing')
end end
end end
...@@ -229,7 +247,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -229,7 +247,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
if current_user && can_current_user_push_to_default_branch? && repository.readme.nil? if current_user && can_current_user_push_to_default_branch? && repository.readme.nil?
AnchorData.new(false, AnchorData.new(false,
statistic_icon + _('Add README'), statistic_icon + _('Add README'),
add_readme_path) empty_repo? ? add_readme_ide_path : add_readme_path)
elsif repository.readme elsif repository.readme
AnchorData.new(false, AnchorData.new(false,
statistic_icon('doc-text') + _('README'), statistic_icon('doc-text') + _('README'),
...@@ -243,7 +261,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -243,7 +261,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
if current_user && can_current_user_push_to_default_branch? && repository.changelog.blank? if current_user && can_current_user_push_to_default_branch? && repository.changelog.blank?
AnchorData.new(false, AnchorData.new(false,
statistic_icon + _('Add CHANGELOG'), statistic_icon + _('Add CHANGELOG'),
add_changelog_path) empty_repo? ? add_changelog_ide_path : add_changelog_path)
elsif repository.changelog.present? elsif repository.changelog.present?
AnchorData.new(false, AnchorData.new(false,
statistic_icon('doc-text') + _('CHANGELOG'), statistic_icon('doc-text') + _('CHANGELOG'),
...@@ -264,7 +282,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -264,7 +282,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
if current_user && can_current_user_push_to_default_branch? if current_user && can_current_user_push_to_default_branch?
AnchorData.new(false, AnchorData.new(false,
content_tag(:span, statistic_icon + _('Add LICENSE'), class: 'add-license-link d-flex'), content_tag(:span, statistic_icon + _('Add LICENSE'), class: 'add-license-link d-flex'),
add_license_path) empty_repo? ? add_license_ide_path : add_license_path)
else else
AnchorData.new(false, AnchorData.new(false,
icon + content_tag(:span, _('No license. All rights reserved'), class: 'project-stat-value'), icon + content_tag(:span, _('No license. All rights reserved'), class: 'project-stat-value'),
...@@ -277,7 +295,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -277,7 +295,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
if current_user && can_current_user_push_to_default_branch? && repository.contribution_guide.blank? if current_user && can_current_user_push_to_default_branch? && repository.contribution_guide.blank?
AnchorData.new(false, AnchorData.new(false,
statistic_icon + _('Add CONTRIBUTING'), statistic_icon + _('Add CONTRIBUTING'),
add_contribution_guide_path) empty_repo? ? add_contribution_guide_ide_path : add_contribution_guide_path)
elsif repository.contribution_guide.present? elsif repository.contribution_guide.present?
AnchorData.new(false, AnchorData.new(false,
statistic_icon('doc-text') + _('CONTRIBUTING'), statistic_icon('doc-text') + _('CONTRIBUTING'),
......
---
title: Use Web IDE to create new files in empty repos
merge_request: 44287
author:
type: added
...@@ -73,6 +73,10 @@ module QA ...@@ -73,6 +73,10 @@ module QA
element :project_path_content element :project_path_content
end end
view 'app/assets/javascripts/ide/components/commit_sidebar/message_field.vue' do
element :ide_commit_message_field
end
def has_file?(file_name) def has_file?(file_name)
within_element(:file_list) do within_element(:file_list) do
page.has_content? file_name page.has_content? file_name
...@@ -83,6 +87,10 @@ module QA ...@@ -83,6 +87,10 @@ module QA
has_element?(:project_path_content, project_path: project_path) has_element?(:project_path_content, project_path: project_path)
end end
def go_to_project
click_element(:project_path_content, Page::Project::Show)
end
def create_new_file_from_template(file_name, template) def create_new_file_from_template(file_name, template)
click_element(:new_file, Page::Component::WebIDE::Modal::CreateNewFile) click_element(:new_file, Page::Component::WebIDE::Modal::CreateNewFile)
...@@ -115,7 +123,7 @@ module QA ...@@ -115,7 +123,7 @@ module QA
find_element(:commit_sha_content).text find_element(:commit_sha_content).text
end end
def commit_changes(open_merge_request: false) def commit_changes(commit_message = nil, open_merge_request: false)
# Clicking :begin_commit_button switches from the # Clicking :begin_commit_button switches from the
# edit to the commit view # edit to the commit view
click_element(:begin_commit_button) click_element(:begin_commit_button)
...@@ -133,6 +141,10 @@ module QA ...@@ -133,6 +141,10 @@ module QA
has_element?(:commit_button) has_element?(:commit_button)
end end
if commit_message
fill_element(:ide_commit_message_field, commit_message)
end
if open_merge_request if open_merge_request
click_element(:commit_button, Page::MergeRequest::New) click_element(:commit_button, Page::MergeRequest::New)
else else
......
...@@ -27,11 +27,14 @@ module QA ...@@ -27,11 +27,14 @@ module QA
Page::Project::Show.perform(&:create_first_new_file!) Page::Project::Show.perform(&:create_first_new_file!)
Page::File::Form.perform do |form| Page::Project::WebIDE::Edit.perform do |ide|
form.add_name(@name) ide.add_file(@name, @content)
form.add_content(@content) ide.commit_changes(@commit_message)
form.add_commit_message(@commit_message) ide.go_to_project
form.commit_changes end
Page::Project::Show.perform do |project|
project.click_file(@name)
end end
end end
......
...@@ -18,7 +18,6 @@ module QA ...@@ -18,7 +18,6 @@ module QA
file.commit_message = commit_message_for_create file.commit_message = commit_message_for_create
end end
expect(page).to have_content('The file has been successfully created.')
expect(page).to have_content(file_name) expect(page).to have_content(file_name)
expect(page).to have_content(file_content) expect(page).to have_content(file_content)
expect(page).to have_content(commit_message_for_create) expect(page).to have_content(commit_message_for_create)
......
...@@ -10,7 +10,6 @@ module QA ...@@ -10,7 +10,6 @@ module QA
end end
end end
let(:web_ide_url) { current_url + '-/ide/project/' + project.path_with_namespace }
let(:file_name) { 'the very first file.txt' } let(:file_name) { 'the very first file.txt' }
before do before do
...@@ -18,10 +17,8 @@ module QA ...@@ -18,10 +17,8 @@ module QA
end end
it "creates the first file in an empty project via Web IDE", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/847' do it "creates the first file in an empty project via Web IDE", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/847' do
# In the first iteration, the test opens Web IDE by modifying the URL to address past regressions. project.visit!
# Once the Web IDE button is introduced for empty projects, the test will be modified to go through UI. Page::Project::Show.perform(&:create_first_new_file!)
# See https://gitlab.com/gitlab-org/gitlab/-/issues/27915 and https://gitlab.com/gitlab-org/gitlab/-/issues/27535.
page.visit(web_ide_url)
Page::Project::WebIDE::Edit.perform do |ide| Page::Project::WebIDE::Edit.perform do |ide|
ide.create_first_file(file_name) ide.create_first_file(file_name)
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'User creates blob in new project', :js do RSpec.describe 'User creates new blob', :js do
include WebIdeSpecHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :empty_repo) } let(:project) { create(:project, :empty_repo) }
...@@ -12,16 +14,19 @@ RSpec.describe 'User creates blob in new project', :js do ...@@ -12,16 +14,19 @@ RSpec.describe 'User creates blob in new project', :js do
visit project_path(project) visit project_path(project)
end end
it 'allows the user to add a new file' do it 'allows the user to add a new file in Web IDE' do
click_link 'New file' click_link 'New file'
execute_script("monaco.editor.getModels()[0].setValue('Hello world')") wait_for_requests
ide_create_new_file('dummy-file', content: "Hello world\n")
fill_in(:file_name, with: 'dummy-file') ide_commit
click_button('Commit changes') click_button('Commit')
expect(page).to have_content('The file has been successfully created') expect(page).to have_content('All changes are committed')
expect(project.repository.blob_at('master', 'dummy-file').data).to eql("Hello world\n")
end end
end end
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do RSpec.describe 'Projects > Files > Project owner sees a link to create a license file in empty project', :js do
include WebIdeSpecHelpers
let(:project) { create(:project_empty_repo) } let(:project) { create(:project_empty_repo) }
let(:project_maintainer) { project.owner } let(:project_maintainer) { project.owner }
...@@ -10,36 +12,35 @@ RSpec.describe 'Projects > Files > Project owner sees a link to create a license ...@@ -10,36 +12,35 @@ RSpec.describe 'Projects > Files > Project owner sees a link to create a license
sign_in(project_maintainer) sign_in(project_maintainer)
end end
it 'project maintainer creates a license file from a template' do it 'allows project maintainer creates a license file from a template in Web IDE' do
visit project_path(project) visit project_path(project)
click_on 'Add LICENSE' click_on 'Add LICENSE'
expect(page).to have_content('New file')
expect(current_path).to eq( expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE")
project_new_blob_path(project, 'master'))
expect(find('#file_name').value).to eq('LICENSE') expect(page).to have_selector('.qa-file-templates-bar')
expect(page).to have_selector('.license-selector')
select_template('MIT License') select_template('MIT License')
file_content = first('.file-editor') expect(ide_editor_value).to have_content('MIT License')
expect(file_content).to have_content('MIT License') expect(ide_editor_value).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
ide_commit
click_button('Commit')
expect(current_path).to eq("/-/ide/project/#{project.full_path}/tree/master/-/")
fill_in :commit_message, with: 'Add a LICENSE file', visible: true expect(page).to have_content('All changes are committed')
click_button 'Commit changes'
expect(current_path).to eq( license_file = project.repository.blob_at('master', 'LICENSE').data
project_blob_path(project, 'master/LICENSE')) expect(license_file).to have_content('MIT License')
expect(page).to have_content('MIT License') expect(license_file).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
end end
def select_template(template) def select_template(template)
page.within('.js-license-selector-wrap') do click_button 'Choose a template...'
click_button 'Apply a template' click_button template
click_link template wait_for_requests
wait_for_requests
end
end end
end end
...@@ -46,21 +46,21 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do ...@@ -46,21 +46,21 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
visit project_path(project) visit project_path(project)
end end
it '"New file" button linked to new file page' do it '"New file" button linked to IDE new file page' do
page.within('.project-buttons') do page.within('.project-buttons') do
expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master')) expect(page).to have_link('New file', href: presenter.ide_edit_path(project, project.default_branch || 'master'))
end end
end end
it '"Add README" button linked to new file populated for a README' do it '"Add README" button linked to IDE new file populated for a README' do
page.within('.project-buttons') do page.within('.project-buttons') do
expect(page).to have_link('Add README', href: presenter.add_readme_path) expect(page).to have_link('Add README', href: presenter.add_readme_ide_path)
end end
end end
it '"Add license" button linked to new file populated for a license' do it '"Add license" button linked to IDE new file populated for a license' do
page.within('.project-buttons') do page.within('.project-buttons') do
expect(page).to have_link('Add LICENSE', href: presenter.add_license_path) expect(page).to have_link('Add LICENSE', href: presenter.add_license_ide_path)
end end
end end
...@@ -74,9 +74,9 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do ...@@ -74,9 +74,9 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
visit project_path(project) visit project_path(project)
end end
it '"New file" button linked to new file page' do it '"New file" button linked to IDE new file page' do
page.within('.project-buttons') do page.within('.project-buttons') do
expect(page).to have_link('New file', href: project_new_blob_path(project, 'example_branch')) expect(page).to have_link('New file', href: presenter.ide_edit_path(project, 'example_branch'))
end end
end end
end end
...@@ -144,7 +144,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do ...@@ -144,7 +144,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
expect(project.repository.readme).not_to be_nil expect(project.repository.readme).not_to be_nil
page.within('.project-buttons') do page.within('.project-buttons') do
expect(page).not_to have_link('Add README', href: presenter.add_readme_path) expect(page).not_to have_link('Add README', href: presenter.add_readme_ide_path)
expect(page).to have_link('README', href: presenter.readme_path) expect(page).to have_link('README', href: presenter.readme_path)
end end
end end
...@@ -164,7 +164,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do ...@@ -164,7 +164,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
end end
context 'when the project does not have a README' do context 'when the project does not have a README' do
it 'shows the "Add README" button' do it 'shows the single file editor "Add README" button' do
allow(project.repository).to receive(:readme).and_return(nil) allow(project.repository).to receive(:readme).and_return(nil)
visit project_path(project) visit project_path(project)
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Developer views tags' do RSpec.describe 'Developer views tags' do
include RepoHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let(:group) { create(:group) } let(:group) { create(:group) }
...@@ -15,10 +17,13 @@ RSpec.describe 'Developer views tags' do ...@@ -15,10 +17,13 @@ RSpec.describe 'Developer views tags' do
let(:project) { create(:project_empty_repo, namespace: group) } let(:project) { create(:project_empty_repo, namespace: group) }
before do before do
visit project_path(project) project.repository.create_file(
click_on 'Add README' user,
fill_in :commit_message, with: 'Add a README file', visible: true 'README.md',
click_button 'Commit changes' 'Example readme',
message: 'Add README',
branch_name: 'master')
visit project_tags_path(project) visit project_tags_path(project)
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