diff --git a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue index 5b392470e41401d035e2455dc3625935ef1dbf7d..7d08815b03360f3e1e9d90dc3fe14ba6ce501b89 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue @@ -116,6 +116,7 @@ export default { :placeholder="placeholder" :value="text" class="note-textarea ide-commit-message-textarea" + data-qa-selector="ide_commit_message_field" dir="auto" name="commit-message" @scroll="handleScroll" diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb index 0be8a4d5472d0593c4c3672cd14df87bd0b54c6a..4732f895b0db4972daec64c2c814e99535145a27 100644 --- a/app/presenters/project_presenter.rb +++ b/app/presenters/project_presenter.rb @@ -106,14 +106,26 @@ def add_license_path add_special_file_path(file_name: 'LICENSE') end + def add_license_ide_path + ide_edit_path(project, default_branch_or_master, 'LICENSE') + end + def add_changelog_path add_special_file_path(file_name: 'CHANGELOG') end + def add_changelog_ide_path + ide_edit_path(project, default_branch_or_master, 'CHANGELOG') + end + def add_contribution_guide_path add_special_file_path(file_name: 'CONTRIBUTING.md', commit_message: 'Add CONTRIBUTING') end + def add_contribution_guide_ide_path + ide_edit_path(project, default_branch_or_master, 'CONTRIBUTING.md') + end + def add_ci_yml_path add_special_file_path(file_name: ci_config_path_or_default) end @@ -122,6 +134,10 @@ def add_readme_path add_special_file_path(file_name: 'README.md') end + def add_readme_ide_path + ide_edit_path(project, default_branch_or_master, 'README.md') + end + def license_short_name license = repository.license license&.nickname || license&.name || 'LICENSE' @@ -218,9 +234,11 @@ def tags_anchor_data def new_file_anchor_data 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, statistic_icon + _('New file'), - project_new_blob_path(project, default_branch_or_master), + new_file_path, 'missing') end end @@ -229,7 +247,7 @@ def readme_anchor_data if current_user && can_current_user_push_to_default_branch? && repository.readme.nil? AnchorData.new(false, statistic_icon + _('Add README'), - add_readme_path) + empty_repo? ? add_readme_ide_path : add_readme_path) elsif repository.readme AnchorData.new(false, statistic_icon('doc-text') + _('README'), @@ -243,7 +261,7 @@ def changelog_anchor_data if current_user && can_current_user_push_to_default_branch? && repository.changelog.blank? AnchorData.new(false, statistic_icon + _('Add CHANGELOG'), - add_changelog_path) + empty_repo? ? add_changelog_ide_path : add_changelog_path) elsif repository.changelog.present? AnchorData.new(false, statistic_icon('doc-text') + _('CHANGELOG'), @@ -264,7 +282,7 @@ def license_anchor_data if current_user && can_current_user_push_to_default_branch? AnchorData.new(false, 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 AnchorData.new(false, icon + content_tag(:span, _('No license. All rights reserved'), class: 'project-stat-value'), @@ -277,7 +295,7 @@ def contribution_guide_anchor_data if current_user && can_current_user_push_to_default_branch? && repository.contribution_guide.blank? AnchorData.new(false, statistic_icon + _('Add CONTRIBUTING'), - add_contribution_guide_path) + empty_repo? ? add_contribution_guide_ide_path : add_contribution_guide_path) elsif repository.contribution_guide.present? AnchorData.new(false, statistic_icon('doc-text') + _('CONTRIBUTING'), diff --git a/changelogs/unreleased/27535-new-project-ide.yml b/changelogs/unreleased/27535-new-project-ide.yml new file mode 100644 index 0000000000000000000000000000000000000000..ce06f1c0380cc96fec196be4d8e53d6e41f2f445 --- /dev/null +++ b/changelogs/unreleased/27535-new-project-ide.yml @@ -0,0 +1,5 @@ +--- +title: Use Web IDE to create new files in empty repos +merge_request: 44287 +author: +type: added diff --git a/qa/qa/page/project/web_ide/edit.rb b/qa/qa/page/project/web_ide/edit.rb index 56c8d343cf530a655c2d99d237a7ea3ef74ccb6a..fc33c753230578aff1ea5ae816cf5f487bfdb899 100644 --- a/qa/qa/page/project/web_ide/edit.rb +++ b/qa/qa/page/project/web_ide/edit.rb @@ -73,6 +73,10 @@ class Edit < Page::Base element :project_path_content end + view 'app/assets/javascripts/ide/components/commit_sidebar/message_field.vue' do + element :ide_commit_message_field + end + def has_file?(file_name) within_element(:file_list) do page.has_content? file_name @@ -83,6 +87,10 @@ def has_project_path?(project_path) has_element?(:project_path_content, project_path: project_path) end + def go_to_project + click_element(:project_path_content, Page::Project::Show) + end + def create_new_file_from_template(file_name, template) click_element(:new_file, Page::Component::WebIDE::Modal::CreateNewFile) @@ -115,7 +123,7 @@ def commit_sha find_element(:commit_sha_content).text 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 # edit to the commit view click_element(:begin_commit_button) @@ -133,6 +141,10 @@ def commit_changes(open_merge_request: false) has_element?(:commit_button) end + if commit_message + fill_element(:ide_commit_message_field, commit_message) + end + if open_merge_request click_element(:commit_button, Page::MergeRequest::New) else diff --git a/qa/qa/resource/file.rb b/qa/qa/resource/file.rb index 76c4c71c48df2a3ae6d6c111ca5cd68e9fc5f91b..f573f3e89f0c06f423b7aa1b66d174b7f455d2e8 100644 --- a/qa/qa/resource/file.rb +++ b/qa/qa/resource/file.rb @@ -27,11 +27,14 @@ def fabricate! Page::Project::Show.perform(&:create_first_new_file!) - Page::File::Form.perform do |form| - form.add_name(@name) - form.add_content(@content) - form.add_commit_message(@commit_message) - form.commit_changes + Page::Project::WebIDE::Edit.perform do |ide| + ide.add_file(@name, @content) + ide.commit_changes(@commit_message) + ide.go_to_project + end + + Page::Project::Show.perform do |project| + project.click_file(@name) end end diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb index 43f4b080c737743224c89e17a20c84a0e4152998..5aa5f0fc0a32517c0fa33f497f81ae743829280e 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb @@ -18,7 +18,6 @@ module QA file.commit_message = commit_message_for_create 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_content) expect(page).to have_content(commit_message_for_create) diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb index ea821f8b3e662f22ce45f131cc83314564a41d5a..f7a2e3081fb49eabb2ac9e7aa5ff60729bca36f5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/create_first_file_in_web_ide_spec.rb @@ -10,7 +10,6 @@ module QA end end - let(:web_ide_url) { current_url + '-/ide/project/' + project.path_with_namespace } let(:file_name) { 'the very first file.txt' } before do @@ -18,10 +17,8 @@ module QA end 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. - # Once the Web IDE button is introduced for empty projects, the test will be modified to go through UI. - # See https://gitlab.com/gitlab-org/gitlab/-/issues/27915 and https://gitlab.com/gitlab-org/gitlab/-/issues/27535. - page.visit(web_ide_url) + project.visit! + Page::Project::Show.perform(&:create_first_new_file!) Page::Project::WebIDE::Edit.perform do |ide| ide.create_first_file(file_name) diff --git a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb index a271a4f43a830d6ae01d495c8c0e439266744120..fda2992af8d5ee1208e8a573bc7c0f0c7b782a13 100644 --- a/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb +++ b/spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb @@ -2,7 +2,9 @@ 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(:project) { create(:project, :empty_repo) } @@ -12,16 +14,19 @@ visit project_path(project) 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' - 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 diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index eed1e7aaf1b1669952b33eb53c450bef7ebcb431..d28e31c08dcde41c5b41f037c9f7611a92c72fbd 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' 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_maintainer) { project.owner } @@ -10,36 +12,35 @@ sign_in(project_maintainer) 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) click_on 'Add LICENSE' - expect(page).to have_content('New file') - expect(current_path).to eq( - project_new_blob_path(project, 'master')) - expect(find('#file_name').value).to eq('LICENSE') - expect(page).to have_selector('.license-selector') + expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE") + + expect(page).to have_selector('.qa-file-templates-bar') select_template('MIT License') - file_content = first('.file-editor') - expect(file_content).to have_content('MIT License') - expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") + expect(ide_editor_value).to have_content('MIT License') + expect(ide_editor_value).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 - click_button 'Commit changes' + expect(page).to have_content('All changes are committed') - expect(current_path).to eq( - project_blob_path(project, 'master/LICENSE')) - expect(page).to have_content('MIT License') - expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") + license_file = project.repository.blob_at('master', 'LICENSE').data + expect(license_file).to have_content('MIT License') + expect(license_file).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end def select_template(template) - page.within('.js-license-selector-wrap') do - click_button 'Apply a template' - click_link template - wait_for_requests - end + click_button 'Choose a template...' + click_button template + wait_for_requests end end diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb index afa9de5ce86fdd4d88462eb9be48eddd4087742e..189aa45ff758c4050dc99fd590c266b18ff8c4f3 100644 --- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb +++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb @@ -46,21 +46,21 @@ visit project_path(project) 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 - 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 - 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 - 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 - 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 - 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 @@ -74,9 +74,9 @@ visit project_path(project) 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 - 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 @@ -144,7 +144,7 @@ expect(project.repository.readme).not_to be_nil 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) end end @@ -164,7 +164,7 @@ end 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) visit project_path(project) diff --git a/spec/features/tags/developer_views_tags_spec.rb b/spec/features/tags/developer_views_tags_spec.rb index 4888611472c257df6c402b5a5acf6bdeed78d47b..6bae53afe6f07aee361ae9acac18dd45ec252356 100644 --- a/spec/features/tags/developer_views_tags_spec.rb +++ b/spec/features/tags/developer_views_tags_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Developer views tags' do + include RepoHelpers + let(:user) { create(:user) } let(:group) { create(:group) } @@ -15,10 +17,13 @@ let(:project) { create(:project_empty_repo, namespace: group) } before do - visit project_path(project) - click_on 'Add README' - fill_in :commit_message, with: 'Add a README file', visible: true - click_button 'Commit changes' + project.repository.create_file( + user, + 'README.md', + 'Example readme', + message: 'Add README', + branch_name: 'master') + visit project_tags_path(project) end