diff options
Diffstat (limited to 'spec/features/projects')
51 files changed, 1012 insertions, 276 deletions
diff --git a/spec/features/projects/activity/user_sees_design_activity_spec.rb b/spec/features/projects/activity/user_sees_design_activity_spec.rb new file mode 100644 index 00000000000..27a52b87178 --- /dev/null +++ b/spec/features/projects/activity/user_sees_design_activity_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Projects > Activity > User sees design Activity', :js do + include DesignManagementTestHelpers + + let_it_be(:uploader) { create(:user) } + let_it_be(:editor) { create(:user) } + let_it_be(:deleter) { create(:user) } + let_it_be(:archiver) { create(:user) } + + def design_activity(user, action) + [user.name, user.to_reference, action, 'design'].join(' ') + end + + shared_examples 'being able to see design activity' do + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:design) { create(:design, issue: issue) } + + before_all do + project.add_developer(user) # implicitly adds a project join event. + common_attrs = { project: project, design: design } + create(:design_event, :created, author: uploader, **common_attrs) + create(:design_event, :updated, author: editor, **common_attrs) + create(:design_event, :destroyed, author: deleter, **common_attrs) + create(:design_event, :archived, author: archiver, **common_attrs) + end + + before do + enable_design_management + sign_in(user) + end + + it 'shows the design comment action in the activity page' do + visit activity_project_path(project) + + expect(page).to have_content('joined project') + expect(page).to have_content(design_activity(uploader, 'uploaded')) + expect(page).to have_content(design_activity(editor, 'revised')) + expect(page).to have_content(design_activity(deleter, 'deleted')) + expect(page).to have_content(design_activity(archiver, 'archived')) + end + + it 'allows filtering out the design events', :aggregate_failures do + visit activity_project_path(project, event_filter: EventFilter::ISSUE) + + expect(page).not_to have_content(design_activity(uploader, 'uploaded')) + expect(page).not_to have_content(design_activity(editor, 'revised')) + expect(page).not_to have_content(design_activity(deleter, 'deleted')) + expect(page).not_to have_content(design_activity(archiver, 'archived')) + end + + it 'allows filtering in the design events', :aggregate_failures do + visit activity_project_path(project, event_filter: EventFilter::DESIGNS) + + expect(page).not_to have_content('joined project') + expect(page).to have_content(design_activity(uploader, 'uploaded')) + expect(page).to have_content(design_activity(editor, 'revised')) + expect(page).to have_content(design_activity(deleter, 'deleted')) + expect(page).to have_content(design_activity(archiver, 'archived')) + end + end + + context 'the project is public' do + let_it_be(:project) { create(:project, :repository, :public) } + let_it_be(:user) { create(:user) } + + it_behaves_like 'being able to see design activity' + end + + context 'the project is private' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { create(:user, developer_projects: [project]) } + + it_behaves_like 'being able to see design activity' + end +end diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index cce656a1260..3032d115a00 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -589,7 +589,7 @@ RSpec.describe 'File blob', :js do aggregate_failures do # shows that dashboard yaml is invalid expect(page).to have_content('Metrics Dashboard YAML definition is invalid:') - expect(page).to have_content("panel_groups: can't be blank") + expect(page).to have_content("panel_groups: should be an array of panel_groups objects") # shows a learn more link expect(page).to have_link('Learn more') diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index a369bacc4dd..5aca994f53e 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -11,10 +11,6 @@ RSpec.describe 'Editing file blob', :js do let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] } let(:readme_file_path) { 'README.md' } - before do - stub_feature_flags(web_ide_default: false) - end - context 'as a developer' do let(:user) { create(:user) } let(:role) { :developer } @@ -36,8 +32,7 @@ RSpec.describe 'Editing file blob', :js do def fill_editor(content: 'class NextFeature\\nend\\n') wait_for_requests - find('#editor') - execute_script("ace.edit('editor').setValue('#{content}')") + execute_script("monaco.editor.getModels()[0].setValue('#{content}')") end context 'from MR diff' do @@ -67,6 +62,15 @@ RSpec.describe 'Editing file blob', :js do expect(find_by_id('file_path').value).to eq('ci/.gitlab-ci.yml') end + it 'updating file path updates syntax highlighting' do + visit project_edit_blob_path(project, tree_join(branch, readme_file_path)) + expect(find('#editor')['data-mode-id']).to eq('markdown') + + find('#file_path').send_keys('foo.txt') do + expect(find('#editor')['data-mode-id']).to eq('plaintext') + end + end + context 'from blob file path' do before do visit project_blob_path(project, tree_join(branch, file_path)) 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 d250a01c050..a271a4f43a8 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 @@ -15,8 +15,7 @@ RSpec.describe 'User creates blob in new project', :js do it 'allows the user to add a new file' do click_link 'New file' - find('#editor') - execute_script('ace.edit("editor").setValue("Hello world")') + execute_script("monaco.editor.getModels()[0].setValue('Hello world')") fill_in(:file_name, with: 'dummy-file') diff --git a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb index 5270774b541..8b43687c71c 100644 --- a/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb +++ b/spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb @@ -32,6 +32,8 @@ RSpec.describe 'User follows pipeline suggest nudge spec when feature is enabled end it 'displays suggest_gitlab_ci_yml popover' do + page.find(:css, '.gitlab-ci-yml-selector').click + popover_selector = '.suggest-gitlab-ci-yml' expect(page).to have_css(popover_selector, visible: true) diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index 3e1006920e7..2e6a366f77a 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -139,6 +139,19 @@ RSpec.describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do end end + context 'when a user adds an existing cluster' do + before do + visit project_clusters_path(project) + + click_link 'Add Kubernetes cluster' + click_link 'Add existing cluster' + end + + it 'user sees the "Environment scope" field' do + expect(page).to have_css('#cluster_environment_scope') + end + end + context 'when user destroys the cluster' do before do click_link 'Advanced Settings' @@ -155,19 +168,6 @@ RSpec.describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do end end - context 'when a user cannot edit the environment scope' do - before do - visit project_clusters_path(project) - - click_link 'Add Kubernetes cluster' - click_link 'Add existing cluster' - end - - it 'user does not see the "Environment scope" field' do - expect(page).not_to have_css('#cluster_environment_scope') - end - end - context 'when user has not dismissed GCP signup offer' do before do visit project_clusters_path(project) diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb index 1cf214a5c4e..c56a1ed1711 100644 --- a/spec/features/projects/clusters_spec.rb +++ b/spec/features/projects/clusters_spec.rb @@ -25,6 +25,168 @@ RSpec.describe 'Clusters', :js do end end + context 'when user has a cluster' do + before do + allow_any_instance_of(Clusters::Cluster).to receive(:retrieve_connection_status).and_return(:connected) + end + + context 'when user adds an existing cluster' do + before do + create(:cluster, :provided_by_user, name: 'default-cluster', environment_scope: '*', projects: [project]) + visit project_clusters_path(project) + end + + it 'user sees an add cluster button' do + expect(page).to have_selector('.js-add-cluster:not(.readonly)') + end + + context 'when user filled form with environment scope' do + before do + click_link 'Add Kubernetes cluster' + click_link 'Add existing cluster' + fill_in 'cluster_name', with: 'staging-cluster' + fill_in 'cluster_environment_scope', with: 'staging/*' + click_button 'Add Kubernetes cluster' + end + + it 'user sees a cluster details page' do + expect(page.find_field('cluster[name]').value).to eq('staging-cluster') + expect(page.find_field('cluster[environment_scope]').value).to eq('staging/*') + end + end + + context 'when user updates environment scope' do + before do + click_link 'default-cluster' + fill_in 'cluster_environment_scope', with: 'production/*' + within '.js-cluster-integration-form' do + click_button 'Save changes' + end + end + + it 'updates the environment scope' do + expect(page.find_field('cluster[environment_scope]').value).to eq('production/*') + end + end + + context 'when user updates duplicated environment scope' do + before do + click_link 'Add Kubernetes cluster' + click_link 'Add existing cluster' + fill_in 'cluster_name', with: 'staging-cluster' + fill_in 'cluster_environment_scope', with: '*' + fill_in 'cluster_platform_kubernetes_attributes_api_url', with: 'https://0.0.0.0' + fill_in 'cluster_platform_kubernetes_attributes_token', with: 'token' + + click_button 'Add Kubernetes cluster' + end + + it 'users sees an environment scope validation error' do + expect(page).to have_content('cannot add duplicated environment scope') + end + end + end + + context 'when user adds a Google Kubernetes Engine cluster' do + before do + allow_any_instance_of(Projects::ClustersController) + .to receive(:token_in_session).and_return('token') + allow_any_instance_of(Projects::ClustersController) + .to receive(:expires_at_in_session).and_return(1.hour.since.to_i.to_s) + + allow_any_instance_of(Projects::ClustersController).to receive(:authorize_google_project_billing) + allow_any_instance_of(Projects::ClustersController).to receive(:google_project_billing_status).and_return(true) + + allow_any_instance_of(GoogleApi::CloudPlatform::Client) + .to receive(:projects_zones_clusters_create) do + OpenStruct.new( + self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123', + status: 'RUNNING' + ) + end + + allow(WaitForClusterCreationWorker).to receive(:perform_in).and_return(nil) + + create(:cluster, :provided_by_gcp, name: 'default-cluster', environment_scope: '*', projects: [project]) + visit project_clusters_path(project) + end + + it 'user sees a add cluster button ' do + expect(page).to have_selector('.js-add-cluster:not(.readonly)') + end + + context 'when user filled form with environment scope' do + before do + click_link 'Add Kubernetes cluster' + click_link 'Create new cluster' + click_link 'Google GKE' + + sleep 2 # wait for ajax + execute_script('document.querySelector(".js-gcp-project-id-dropdown input").setAttribute("type", "text")') + execute_script('document.querySelector(".js-gcp-zone-dropdown input").setAttribute("type", "text")') + execute_script('document.querySelector(".js-gcp-machine-type-dropdown input").setAttribute("type", "text")') + execute_script('document.querySelector(".js-gke-cluster-creation-submit").removeAttribute("disabled")') + + fill_in 'cluster_name', with: 'staging-cluster' + fill_in 'cluster_environment_scope', with: 'staging/*' + fill_in 'cluster[provider_gcp_attributes][gcp_project_id]', with: 'gcp-project-123' + fill_in 'cluster[provider_gcp_attributes][zone]', with: 'us-central1-a' + fill_in 'cluster[provider_gcp_attributes][machine_type]', with: 'n1-standard-2' + click_button 'Create Kubernetes cluster' + + # The frontend won't show the details until the cluster is + # created, and we don't want to make calls out to GCP. + provider = Clusters::Cluster.last.provider + provider.make_created + end + + it 'user sees a cluster details page' do + expect(page).to have_content('GitLab Integration') + expect(page.find_field('cluster[environment_scope]').value).to eq('staging/*') + end + end + + context 'when user updates environment scope' do + before do + click_link 'default-cluster' + fill_in 'cluster_environment_scope', with: 'production/*' + within ".js-cluster-integration-form" do + click_button 'Save changes' + end + end + + it 'updates the environment scope' do + expect(page.find_field('cluster[environment_scope]').value).to eq('production/*') + end + end + + context 'when user updates duplicated environment scope' do + before do + click_link 'Add Kubernetes cluster' + click_link 'Create new cluster' + click_link 'Google GKE' + + sleep 2 # wait for ajax + execute_script('document.querySelector(".js-gcp-project-id-dropdown input").setAttribute("type", "text")') + execute_script('document.querySelector(".js-gcp-zone-dropdown input").setAttribute("type", "text")') + execute_script('document.querySelector(".js-gcp-machine-type-dropdown input").setAttribute("type", "text")') + execute_script('document.querySelector(".js-gke-cluster-creation-submit").removeAttribute("disabled")') + + fill_in 'cluster_name', with: 'staging-cluster' + fill_in 'cluster_environment_scope', with: '*' + fill_in 'cluster[provider_gcp_attributes][gcp_project_id]', with: 'gcp-project-123' + fill_in 'cluster[provider_gcp_attributes][zone]', with: 'us-central1-a' + fill_in 'cluster[provider_gcp_attributes][machine_type]', with: 'n1-standard-2' + click_button 'Create Kubernetes cluster' + end + + it 'users sees an environment scope validation error' do + expect(page).to have_content('cannot add duplicated environment scope') + end + end + end + end + context 'when user has a cluster and visits cluster index page' do let!(:cluster) { create(:cluster, :project, :provided_by_gcp) } let(:project) { cluster.project } diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb index 13f73b8cf44..f97abc5bd8b 100644 --- a/spec/features/projects/commit/builds_spec.rb +++ b/spec/features/projects/commit/builds_spec.rb @@ -6,23 +6,32 @@ RSpec.describe 'project commit pipelines', :js do let(:project) { create(:project, :repository) } before do + create(:ci_pipeline, project: project, + sha: project.commit.sha, + ref: 'master') + user = create(:user) project.add_maintainer(user) sign_in(user) + + visit pipelines_project_commit_path(project, project.commit.sha) end context 'when no builds triggered yet' do - before do - create(:ci_pipeline, project: project, - sha: project.commit.sha, - ref: 'master') + it 'shows the ID of the first pipeline' do + page.within('.table-holder') do + expect(page).to have_content project.ci_pipelines[0].id # pipeline ids + end end + end - it 'user views commit pipelines page' do - visit pipelines_project_commit_path(project, project.commit.sha) + context 'with no related merge requests' do + it 'shows the correct text for no related MRs' do + wait_for_requests - page.within('.table-holder') do - expect(page).to have_content project.ci_pipelines[0].id # pipeline ids + page.within('.merge-request-info') do + expect(page).not_to have_selector '.spinner' + expect(page).to have_content 'No related merge requests found' end end end diff --git a/spec/features/projects/commits/user_browses_commits_spec.rb b/spec/features/projects/commits/user_browses_commits_spec.rb index 2796156bfbf..dee964005a4 100644 --- a/spec/features/projects/commits/user_browses_commits_spec.rb +++ b/spec/features/projects/commits/user_browses_commits_spec.rb @@ -137,6 +137,33 @@ RSpec.describe 'User browses commits' do .and have_selector('entry summary', text: commit.description[0..10].delete("\r\n")) end + context "when commit has a filename with pathspec characters" do + let(:path) { ':wq' } + let(:filename) { File.join(path, 'test.txt') } + let(:ref) { project.repository.root_ref } + let(:newrev) { project.repository.commit('master').sha } + let(:short_newrev) { project.repository.commit('master').short_id } + let(:message) { 'Glob characters'} + + before do + create_file_in_repo(project, ref, ref, filename, 'Test file', commit_message: message) + visit project_commits_path(project, "#{ref}/#{path}", limit: 1) + wait_for_requests + end + + it 'searches commit', :js do + expect(page).to have_content(message) + + fill_in 'commits-search', with: 'bogus12345' + + expect(page).to have_content "Your search didn't match any commits" + + fill_in 'commits-search', with: 'Glob' + + expect(page).to have_content message + end + end + context 'when a commit links to a confidential issue' do let(:confidential_issue) { create(:issue, confidential: true, title: 'Secret issue!', project: project) } diff --git a/spec/features/projects/confluence/user_views_confluence_page_spec.rb b/spec/features/projects/confluence/user_views_confluence_page_spec.rb new file mode 100644 index 00000000000..d39c97291db --- /dev/null +++ b/spec/features/projects/confluence/user_views_confluence_page_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User views the Confluence page' do + let_it_be(:user) { create(:user) } + let(:project) { create(:project, :public) } + + before do + sign_in(user) + end + + it 'shows the page when the Confluence integration is enabled' do + service = create(:confluence_service, project: project) + + visit project_wikis_confluence_path(project) + + element = page.find('.row.empty-state') + + expect(element).to have_link('Go to Confluence', href: service.confluence_url) + end + + it 'does not show the page when the Confluence integration disabled' do + visit project_wikis_confluence_path(project) + + expect(page).to have_gitlab_http_status(:not_found) + end +end diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb index f561149d2ad..7514a26f020 100644 --- a/spec/features/projects/container_registry_spec.rb +++ b/spec/features/projects/container_registry_spec.rb @@ -84,7 +84,7 @@ RSpec.describe 'Container Registry', :js do expect(service).to receive(:execute).with(container_repository) { { status: :success } } expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['1']) { service } - first('[data-testid="singleDeleteButton"]').click + first('[data-testid="single-delete-button"]').click expect(find('.modal .modal-title')).to have_content _('Remove tag') find('.modal .modal-footer .btn-danger').click end diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb index a3b979d0f42..c72f88205b5 100644 --- a/spec/features/projects/environments/environment_metrics_spec.rb +++ b/spec/features/projects/environments/environment_metrics_spec.rb @@ -28,8 +28,9 @@ RSpec.describe 'Environment > Metrics' do shared_examples 'has environment selector' do it 'has a working environment selector', :js do click_link('See metrics') - - expect(page).to have_metrics_path(environment) + # TODO: See metrics on the sidebar still points to the old metrics URL + # https://gitlab.com/gitlab-org/gitlab/-/issues/229277 + expect(page).to have_current_path(metrics_project_environment_path(project, id: environment.id)) expect(page).to have_css('[data-qa-selector="environments_dropdown"]') within('[data-qa-selector="environments_dropdown"]') do @@ -40,7 +41,7 @@ RSpec.describe 'Environment > Metrics' do click_on(staging.name) end - expect(page).to have_metrics_path(staging) + expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: staging.id)) wait_for_requests end @@ -67,8 +68,4 @@ RSpec.describe 'Environment > Metrics' do def visit_environment(environment) visit project_environment_path(environment.project, environment) end - - def have_metrics_path(environment) - have_current_path(metrics_project_environment_path(project, id: environment.id)) - end end diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb index 82dafbc6237..c491cd62d85 100644 --- a/spec/features/projects/environments_pod_logs_spec.rb +++ b/spec/features/projects/environments_pod_logs_spec.rb @@ -12,11 +12,12 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do let(:service) { create(:cluster_platform_kubernetes, :configured) } before do - create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [project]) + cluster = create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [project]) create(:deployment, :success, environment: environment) stub_kubeclient_pods(environment.deployment_namespace) stub_kubeclient_logs(pod_name, environment.deployment_namespace, container: 'container-0') + stub_kubeclient_nodes_and_nodes_metrics(cluster.platform.api_url) sign_in(project.owner) end @@ -37,7 +38,7 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do dropdown_items = find(".dropdown-menu").all(".dropdown-item") expect(dropdown_items.first).to have_content(environment.name) - expect(dropdown_items.size).to eq(2) + expect(dropdown_items.size).to eq(3) end end diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb index ede22204dbd..fda024e893d 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -8,8 +8,9 @@ RSpec.describe 'Projects > Files > User uses soft wrap while editing file', :js user = project.owner sign_in user visit project_new_blob_path(project, 'master', file_name: 'test_file-name') + page.within('.file-editor.code') do - find('.ace_text-input', visible: false).send_keys 'Touch water with paw then recoil in horror chase dog then + find('.inputarea', visible: false).send_keys 'Touch water with paw then recoil in horror chase dog then run away chase the pig around the house eat owner\'s food, and knock dish off table head butt cant eat out of my own dish. Cat is love, cat is life rub face on everything poop on grasses so meow. Playing with @@ -26,17 +27,20 @@ RSpec.describe 'Projects > Files > User uses soft wrap while editing file', :js it 'user clicks the "Soft wrap" button and then "No wrap" button' do wrapped_content_width = get_content_width - toggle_button.click - expect(toggle_button).to have_content 'No wrap' - unwrapped_content_width = get_content_width - expect(unwrapped_content_width).to be < wrapped_content_width - - toggle_button.click - expect(toggle_button).to have_content 'Soft wrap' - expect(get_content_width).to be > unwrapped_content_width + + toggle_button.click do + expect(toggle_button).to have_content 'Soft wrap' + unwrapped_content_width = get_content_width + expect(unwrapped_content_width).to be > wrapped_content_width + end + + toggle_button.click do + expect(toggle_button).to have_content 'No wrap' + expect(get_content_width).to be < unwrapped_content_width + end end def get_content_width - find('.ace_content')[:style].slice!(/width: \d+/).slice!(/\d+/).to_i + find('.view-lines', visible: false)[:style].slice!(/width: \d+/).slice!(/\d+/).to_i end end diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index dae1164f7f2..5a39f2bcd98 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -25,6 +25,6 @@ RSpec.describe 'Projects > Files > User wants to add a .gitignore file' do expect(page).to have_css('.gitignore-selector .dropdown-toggle-text', text: 'Apply a template') expect(page).to have_content('/.bundle') - expect(page).to have_content('# Gemfile.lock, .ruby-version, .ruby-gemset') + expect(page).to have_content('config/initializers/secret_token.rb') end end diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb index 44b5833a8c8..e5259bd88be 100644 --- a/spec/features/projects/files/user_browses_files_spec.rb +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -3,6 +3,8 @@ require "spec_helper" RSpec.describe "User browses files" do + include RepoHelpers + let(:fork_message) do "You're not allowed to make changes to this project directly. "\ "A fork of this project has been created that you can make changes in, so you can submit a merge request." @@ -339,6 +341,24 @@ RSpec.describe "User browses files" do end end + context "when browsing a file with pathspec characters" do + let(:filename) { ':wq' } + let(:newrev) { project.repository.commit('master').sha } + + before do + create_file_in_repo(project, 'master', 'master', filename, 'Test file') + path = File.join('master', filename) + + visit(project_blob_path(project, path)) + end + + it "shows a raw file content" do + click_link("Open raw") + + expect(source).to eq("") # Body is filled in by gitlab-workhorse + end + end + context "when browsing a raw file" do before do path = File.join(RepoHelpers.sample_commit.id, RepoHelpers.sample_blob.path) diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb index cc90f0cf294..5abc048c135 100644 --- a/spec/features/projects/files/user_creates_files_spec.rb +++ b/spec/features/projects/files/user_creates_files_spec.rb @@ -14,8 +14,6 @@ RSpec.describe 'Projects > Files > User creates files', :js do let(:user) { create(:user) } before do - stub_feature_flags(web_ide_default: false) - project.add_maintainer(user) sign_in(user) end @@ -67,7 +65,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do file_name = find('#file_name') file_name.set options[:file_name] || 'README.md' - find('.ace_text-input', visible: false).send_keys.native.send_keys options[:file_content] || 'Some content' + find('.monaco-editor textarea').send_keys.native.send_keys options[:file_content] || 'Some content' click_button 'Commit changes' end @@ -89,7 +87,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do it 'creates and commit a new file' do find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -105,7 +103,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do it 'creates and commit a new file with new lines at the end of file' do find('#editor') - execute_script('ace.edit("editor").setValue("Sample\n\n\n")') + execute_script('monaco.editor.getModels()[0].setValue("Sample\n\n\n")') fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -117,7 +115,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do find('.js-edit-blob').click find('#editor') - expect(evaluate_script('ace.edit("editor").getValue()')).to eq("Sample\n\n\n") + expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq("Sample\n\n\n") end it 'creates and commit a new file with a directory name' do @@ -126,7 +124,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do expect(page).to have_selector('.file-editor') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -141,7 +139,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do expect(page).to have_selector('.file-editor') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) fill_in(:branch_name, with: 'new_branch_name', visible: true) @@ -176,7 +174,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do expect(page).to have_selector('.file-editor') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:file_name, with: 'not_a_file.md') fill_in(:commit_message, with: 'New commit message', visible: true) diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb index 1bb931e35ec..d3e075001c8 100644 --- a/spec/features/projects/files/user_edits_files_spec.rb +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -11,8 +11,6 @@ RSpec.describe 'Projects > Files > User edits files', :js do let(:user) { create(:user) } before do - stub_feature_flags(web_ide_default: false) - sign_in(user) end @@ -46,9 +44,9 @@ RSpec.describe 'Projects > Files > User edits files', :js do find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") - expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') + expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq('*.rbca') end it 'does not show the edit link if a file is binary' do @@ -67,7 +65,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -85,7 +83,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) fill_in(:branch_name, with: 'new_branch_name', visible: true) click_button('Commit changes') @@ -103,7 +101,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") click_link('Preview changes') expect(page).to have_css('.line_holder.new') @@ -148,9 +146,9 @@ RSpec.describe 'Projects > Files > User edits files', :js do find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") - expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca') + expect(evaluate_script('monaco.editor.getModels()[0].getValue()')).to eq('*.rbca') end it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do @@ -178,7 +176,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do find('.file-editor', match: :first) find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Commit changes') @@ -207,7 +205,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do expect(page).not_to have_button('Cancel') find('#editor') - execute_script("ace.edit('editor').setValue('*.rbca')") + execute_script("monaco.editor.getModels()[0].setValue('*.rbca')") fill_in(:commit_message, with: 'Another commit', visible: true) click_button('Commit changes') diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz Binary files differindex 730e586b278..b93da033aea 100644 --- a/spec/features/projects/import_export/test_project_export.tar.gz +++ b/spec/features/projects/import_export/test_project_export.tar.gz diff --git a/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb b/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb index f871ca60596..aff8951d9de 100644 --- a/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb +++ b/spec/features/projects/issues/design_management/user_paginates_designs_spec.rb @@ -8,33 +8,57 @@ RSpec.describe 'User paginates issue designs', :js do let(:project) { create(:project_empty_repo, :public) } let(:issue) { create(:issue, project: project) } - before do - enable_design_management + context 'design_management_moved flag disabled' do + before do + stub_feature_flags(design_management_moved: false) + enable_design_management - create_list(:design, 2, :with_file, issue: issue) + create_list(:design, 2, :with_file, issue: issue) + visit project_issue_path(project, issue) + click_link 'Designs' + wait_for_requests + find('.js-design-list-item', match: :first).click + end - visit project_issue_path(project, issue) + it 'paginates to next design' do + expect(find('.js-previous-design')[:disabled]).to eq('true') - click_link 'Designs' + page.within(find('.js-design-header')) do + expect(page).to have_content('1 of 2') + end - wait_for_requests + find('.js-next-design').click - find('.js-design-list-item', match: :first).click - end + expect(find('.js-previous-design')[:disabled]).not_to eq('true') - it 'paginates to next design' do - expect(find('.js-previous-design')[:disabled]).to eq('true') + page.within(find('.js-design-header')) do + expect(page).to have_content('2 of 2') + end + end + end - page.within(find('.js-design-header')) do - expect(page).to have_content('1 of 2') + context 'design_management_moved flag enabled' do + before do + enable_design_management + create_list(:design, 2, :with_file, issue: issue) + visit project_issue_path(project, issue) + find('.js-design-list-item', match: :first).click end - find('.js-next-design').click + it 'paginates to next design' do + expect(find('.js-previous-design')[:disabled]).to eq('true') + + page.within(find('.js-design-header')) do + expect(page).to have_content('1 of 2') + end + + find('.js-next-design').click - expect(find('.js-previous-design')[:disabled]).not_to eq('true') + expect(find('.js-previous-design')[:disabled]).not_to eq('true') - page.within(find('.js-design-header')) do - expect(page).to have_content('2 of 2') + page.within(find('.js-design-header')) do + expect(page).to have_content('2 of 2') + end end end end diff --git a/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb b/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb index 902a84afc83..4e45312eac3 100644 --- a/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb +++ b/spec/features/projects/issues/design_management/user_permissions_upload_spec.rb @@ -8,17 +8,32 @@ RSpec.describe 'User design permissions', :js do let(:project) { create(:project_empty_repo, :public) } let(:issue) { create(:issue, project: project) } - before do - enable_design_management + context 'design_management_moved flag disabled' do + before do + enable_design_management + stub_feature_flags(design_management_moved: false) - visit project_issue_path(project, issue) + visit project_issue_path(project, issue) - click_link 'Designs' + click_link 'Designs' - wait_for_requests + wait_for_requests + end + + it 'user does not have permissions to upload design' do + expect(page).not_to have_field('design_file') + end end - it 'user does not have permissions to upload design' do - expect(page).not_to have_field('design_file') + context 'design_management_moved flag enabled' do + before do + enable_design_management + + visit project_issue_path(project, issue) + end + + it 'user does not have permissions to upload design' do + expect(page).not_to have_field('design_file') + end end end diff --git a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb index 66b449a9de5..2381e00972f 100644 --- a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb +++ b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb @@ -13,10 +13,10 @@ RSpec.describe 'User uploads new design', :js do sign_in(user) end - context "when the feature is available" do + context 'design_management_moved flag disabled' do before do - enable_design_management - + enable_design_management(feature_enabled) + stub_feature_flags(design_management_moved: false) visit project_issue_path(project, issue) click_link 'Designs' @@ -24,32 +24,64 @@ RSpec.describe 'User uploads new design', :js do wait_for_requests end - it 'uploads designs' do - attach_file(:design_file, logo_fixture, make_visible: true) + context "when the feature is available" do + let(:feature_enabled) { true } + + it 'uploads designs' do + attach_file(:design_file, logo_fixture, make_visible: true) + + expect(page).to have_selector('.js-design-list-item', count: 1) + + within first('#designs-tab .js-design-list-item') do + expect(page).to have_content('dk.png') + end - expect(page).to have_selector('.js-design-list-item', count: 1) + attach_file(:design_file, gif_fixture, make_visible: true) - within first('#designs-tab .js-design-list-item') do - expect(page).to have_content('dk.png') + expect(page).to have_selector('.js-design-list-item', count: 2) end + end - attach_file(:design_file, gif_fixture, make_visible: true) + context 'when the feature is not available' do + let(:feature_enabled) { false } - expect(page).to have_selector('.js-design-list-item', count: 2) + it 'shows the message about requirements' do + expect(page).to have_content("To enable design management, you'll need to meet the requirements.") + end end end - context 'when the feature is not available' do + context 'design_management_moved flag enabled' do before do + enable_design_management(feature_enabled) + stub_feature_flags(design_management_moved: true) visit project_issue_path(project, issue) + end - click_link 'Designs' + context "when the feature is available" do + let(:feature_enabled) { true } - wait_for_requests + it 'uploads designs', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/225616' do + attach_file(:design_file, logo_fixture, make_visible: true) + + expect(page).to have_selector('.js-design-list-item', count: 1) + + within first('[data-testid="designs-root"] .js-design-list-item') do + expect(page).to have_content('dk.png') + end + + attach_file(:design_file, gif_fixture, make_visible: true) + + expect(page).to have_selector('.js-design-list-item', count: 2) + end end - it 'shows the message about requirements' do - expect(page).to have_content("To enable design management, you'll need to meet the requirements.") + context 'when the feature is not available' do + let(:feature_enabled) { false } + + it 'shows the message about requirements' do + expect(page).to have_content("To enable design management, you'll need to meet the requirements.") + end end end diff --git a/spec/features/projects/issues/design_management/user_views_design_spec.rb b/spec/features/projects/issues/design_management/user_views_design_spec.rb index 527442d5339..49245218e81 100644 --- a/spec/features/projects/issues/design_management/user_views_design_spec.rb +++ b/spec/features/projects/issues/design_management/user_views_design_spec.rb @@ -9,21 +9,42 @@ RSpec.describe 'User views issue designs', :js do let_it_be(:issue) { create(:issue, project: project) } let_it_be(:design) { create(:design, :with_file, issue: issue) } - before do - enable_design_management + context 'design_management_moved flag disabled' do + before do + enable_design_management + stub_feature_flags(design_management_moved: false) - visit project_issue_path(project, issue) + visit project_issue_path(project, issue) - click_link 'Designs' + click_link 'Designs' + end + + it 'opens design detail' do + click_link design.filename + + page.within(find('.js-design-header')) do + expect(page).to have_content(design.filename) + end + + expect(page).to have_selector('.js-design-image') + end end - it 'opens design detail' do - click_link design.filename + context 'design_management_moved flag enabled' do + before do + enable_design_management - page.within(find('.js-design-header')) do - expect(page).to have_content(design.filename) + visit project_issue_path(project, issue) end - expect(page).to have_selector('.js-design-image') + it 'opens design detail' do + click_link design.filename + + page.within(find('.js-design-header')) do + expect(page).to have_content(design.filename) + end + + expect(page).to have_selector('.js-design-image') + end end end diff --git a/spec/features/projects/issues/design_management/user_views_designs_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_spec.rb index d371ae1aad7..772a9ffbe6f 100644 --- a/spec/features/projects/issues/design_management/user_views_designs_spec.rb +++ b/spec/features/projects/issues/design_management/user_views_designs_spec.rb @@ -9,39 +9,78 @@ RSpec.describe 'User views issue designs', :js do let_it_be(:issue) { create(:issue, project: project) } let_it_be(:design) { create(:design, :with_file, issue: issue) } - before do - enable_design_management - end - - context 'navigates from the issue view' do + context 'design_management_moved flag disabled' do before do - visit project_issue_path(project, issue) - click_link 'Designs' - wait_for_requests + enable_design_management + stub_feature_flags(design_management_moved: false) end - it 'fetches list of designs' do - expect(page).to have_selector('.js-design-list-item', count: 1) + context 'navigates from the issue view' do + before do + visit project_issue_path(project, issue) + click_link 'Designs' + wait_for_requests + end + + it 'fetches list of designs' do + expect(page).to have_selector('.js-design-list-item', count: 1) + end end - end - context 'navigates directly to the design collection view' do - before do - visit designs_project_issue_path(project, issue) + context 'navigates directly to the design collection view' do + before do + visit designs_project_issue_path(project, issue) + end + + it 'expands the sidebar' do + expect(page).to have_selector('.layout-page.right-sidebar-expanded') + end end - it 'expands the sidebar' do - expect(page).to have_selector('.layout-page.right-sidebar-expanded') + context 'navigates directly to the individual design view' do + before do + visit designs_project_issue_path(project, issue, vueroute: design.filename) + end + + it 'sees the design' do + expect(page).to have_selector('.js-design-detail') + end end end - context 'navigates directly to the individual design view' do + context 'design_management_moved flag enabled' do before do - visit designs_project_issue_path(project, issue, vueroute: design.filename) + enable_design_management end - it 'sees the design' do - expect(page).to have_selector('.js-design-detail') + context 'navigates from the issue view' do + before do + visit project_issue_path(project, issue) + end + + it 'fetches list of designs' do + expect(page).to have_selector('.js-design-list-item', count: 1) + end + end + + context 'navigates directly to the design collection view' do + before do + visit designs_project_issue_path(project, issue) + end + + it 'expands the sidebar' do + expect(page).to have_selector('.layout-page.right-sidebar-expanded') + end + end + + context 'navigates directly to the individual design view' do + before do + visit designs_project_issue_path(project, issue, vueroute: design.filename) + end + + it 'sees the design' do + expect(page).to have_selector('.js-design-detail') + end end end end diff --git a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb index 5bc1271309c..0fe84ab47ed 100644 --- a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb +++ b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb @@ -29,6 +29,7 @@ RSpec.describe 'User views an SVG design that contains XSS', :js do end it 'displays the SVG' do + find("[data-testid='close-design']").click expect(page).to have_selector("img.design-img[alt='xss.svg']", count: 1, visible: false) end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index e78e8989575..62e8997f6cb 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -837,7 +837,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do it 'renders empty state' do expect(page).to have_content(job.detailed_status(user).illustration[:title]) - expect(page).not_to have_selector('.js-build-trace') + expect(page).not_to have_selector('.job-log') expect(page).to have_content('This job has been canceled') end end @@ -852,7 +852,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do it 'renders empty state' do expect(page).to have_content(job.detailed_status(user).illustration[:title]) - expect(page).not_to have_selector('.js-build-trace') + expect(page).not_to have_selector('.job-log') expect(page).to have_content('This job has been skipped') end end diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb index 66d61e629df..85a08c441ca 100644 --- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb +++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb @@ -14,7 +14,7 @@ RSpec.describe 'Issue prioritization' do let(:label_5) { create(:label, title: 'label_5', project: project) } # no priority # According to https://gitlab.com/gitlab-org/gitlab-foss/issues/14189#note_4360653 - context 'when issues have one label' do + context 'when issues have one label', :js do it 'Are sorted properly' do # Issues issue_1 = create(:issue, title: 'issue_1', project: project) @@ -44,7 +44,7 @@ RSpec.describe 'Issue prioritization' do end end - context 'when issues have multiple labels' do + context 'when issues have multiple labels', :js do it 'Are sorted properly' do # Issues issue_1 = create(:issue, title: 'issue_1', project: project) diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb index f51ebde8f80..56b807e08d7 100644 --- a/spec/features/projects/members/list_spec.rb +++ b/spec/features/projects/members/list_spec.rb @@ -64,9 +64,12 @@ RSpec.describe 'Project members list' do visit_members_page - accept_confirm do - find(:css, 'li.project_member', text: other_user.name).find(:css, 'a.btn-remove').click - end + # Open modal + find(:css, 'li.project_member', text: other_user.name).find(:css, 'button.btn-remove').click + + expect(page).to have_unchecked_field 'Also unassign this user from related issues and merge requests' + + click_on('Remove member') wait_for_requests diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index aa7633c3b28..c4bd0b81dc0 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -20,7 +20,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do expect(project.users.exists?(user.id)).to be_falsey end - it 'user leaves project by url param', :js, :quarantine do + it 'user leaves project by url param', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/35925' do visit project_path(project, leave: 1) page.accept_confirm diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb index 94d79d60aeb..22cd832ff06 100644 --- a/spec/features/projects/navbar_spec.rb +++ b/spec/features/projects/navbar_spec.rb @@ -12,8 +12,6 @@ RSpec.describe 'Project navbar' do let_it_be(:project) { create(:project, :repository) } before do - stub_licensed_features(service_desk: false) - project.add_maintainer(user) sign_in(user) end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 921bbbfbe7d..1e2cd3c0a69 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -3,8 +3,6 @@ require 'spec_helper' RSpec.describe 'Pipeline Schedules', :js do - include PipelineSchedulesHelper - let!(:project) { create(:project, :repository) } let!(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) } let!(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) } diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index c6a002ad18b..2ca584ab8f6 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -111,7 +111,7 @@ RSpec.describe 'Pipeline', :js do end context 'when there is one related merge request' do - before do + let!(:merge_request) do create(:merge_request, source_project: project, source_branch: pipeline.ref) @@ -123,7 +123,7 @@ RSpec.describe 'Pipeline', :js do within '.related-merge-requests' do expect(page).to have_content('1 related merge request: ') expect(page).to have_selector('.js-truncated-mr-list') - expect(page).to have_link('!1 My title 1') + expect(page).to have_link("#{merge_request.to_reference} #{merge_request.title}") expect(page).not_to have_selector('.js-full-mr-list') expect(page).not_to have_selector('.text-expander') @@ -132,9 +132,16 @@ RSpec.describe 'Pipeline', :js do end context 'when there are two related merge requests' do - before do - create(:merge_request, source_project: project, source_branch: pipeline.ref) - create(:merge_request, source_project: project, source_branch: pipeline.ref, target_branch: 'fix') + let!(:merge_request1) do + create(:merge_request, + source_project: project, + source_branch: pipeline.ref) + end + let!(:merge_request2) do + create(:merge_request, + source_project: project, + source_branch: pipeline.ref, + target_branch: 'fix') end it 'links to the most recent related merge request' do @@ -142,7 +149,7 @@ RSpec.describe 'Pipeline', :js do within '.related-merge-requests' do expect(page).to have_content('2 related merge requests: ') - expect(page).to have_link('!2 My title 3') + expect(page).to have_link("#{merge_request2.to_reference} #{merge_request2.title}") expect(page).to have_selector('.text-expander') expect(page).to have_selector('.js-full-mr-list', visible: false) end @@ -354,37 +361,68 @@ RSpec.describe 'Pipeline', :js do end describe 'test tabs' do - let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) } + let(:pipeline) { create(:ci_pipeline, :with_test_reports, :with_report_results, project: project) } - before do - visit_pipeline - wait_for_requests - end + context 'with build_report_summary feature flag disabled' do + before do + stub_feature_flags(build_report_summary: false) + visit_pipeline + wait_for_requests + end + + context 'with test reports' do + it 'shows badge counter in Tests tab' do + expect(pipeline.test_reports.total_count).to eq(4) + expect(page.find('.js-test-report-badge-counter').text).to eq(pipeline.test_reports.total_count.to_s) + end - context 'with test reports' do - it 'shows badge counter in Tests tab' do - expect(pipeline.test_reports.total_count).to eq(4) - expect(page.find('.js-test-report-badge-counter').text).to eq(pipeline.test_reports.total_count.to_s) + it 'does not call test_report.json endpoint by default', :js do + expect(page).to have_selector('.js-no-tests-to-show', visible: :all) + end + + it 'does call test_report.json endpoint when tab is selected', :js do + find('.js-tests-tab-link').click + wait_for_requests + + expect(page).to have_content('Jobs') + expect(page).to have_selector('.js-tests-detail', visible: :all) + end end - it 'does not call test_report.json endpoint by default', :js do - expect(page).to have_selector('.js-no-tests-to-show', visible: :all) + context 'without test reports' do + let(:pipeline) { create(:ci_pipeline, project: project) } + + it 'shows zero' do + expect(page.find('.js-test-report-badge-counter', visible: :all).text).to eq("0") + end end + end - it 'does call test_report.json endpoint when tab is selected', :js do - find('.js-tests-tab-link').click + context 'with build_report_summary feature flag enabled' do + before do + visit_pipeline wait_for_requests + end + + context 'with test reports' do + it 'shows badge counter in Tests tab' do + expect(page.find('.js-test-report-badge-counter').text).to eq(pipeline.test_report_summary.total_count.to_s) + end - expect(page).to have_content('Test suites') - expect(page).to have_selector('.js-tests-detail', visible: :all) + it 'calls summary.json endpoint', :js do + find('.js-tests-tab-link').click + + expect(page).to have_content('Jobs') + expect(page).to have_selector('.js-tests-detail', visible: :all) + end end - end - context 'without test reports' do - let(:pipeline) { create(:ci_pipeline, project: project) } + context 'without test reports' do + let(:pipeline) { create(:ci_pipeline, project: project) } - it 'shows nothing' do - expect(page.find('.js-test-report-badge-counter', visible: :all).text).to eq("") + it 'shows zero' do + expect(page.find('.js-test-report-badge-counter', visible: :all).text).to eq("0") + end end end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 0e33204f851..0eb92f3e679 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -65,19 +65,8 @@ RSpec.describe 'Pipelines', :js do expect(page.find('.js-pipelines-tab-all .badge').text).to include('1') end - it 'shows a tab for Pending pipelines and count' do - expect(page.find('.js-pipelines-tab-pending').text).to include('Pending') - expect(page.find('.js-pipelines-tab-pending .badge').text).to include('0') - end - - it 'shows a tab for Running pipelines and count' do - expect(page.find('.js-pipelines-tab-running').text).to include('Running') - expect(page.find('.js-pipelines-tab-running .badge').text).to include('1') - end - it 'shows a tab for Finished pipelines and count' do expect(page.find('.js-pipelines-tab-finished').text).to include('Finished') - expect(page.find('.js-pipelines-tab-finished .badge').text).to include('0') end it 'shows a tab for Branches' do @@ -89,9 +78,9 @@ RSpec.describe 'Pipelines', :js do end it 'updates content when tab is clicked' do - page.find('.js-pipelines-tab-pending').click + page.find('.js-pipelines-tab-finished').click wait_for_requests - expect(page).to have_content('There are currently no pending pipelines.') + expect(page).to have_content('There are currently no finished pipelines.') end end @@ -539,7 +528,7 @@ RSpec.describe 'Pipelines', :js do end it 'renders a mini pipeline graph' do - expect(page).to have_selector('.js-mini-pipeline-graph') + expect(page).to have_selector('[data-testid="widget-mini-pipeline-graph"]') expect(page).to have_selector('.js-builds-dropdown-button') end diff --git a/spec/features/projects/services/disable_triggers_spec.rb b/spec/features/projects/services/disable_triggers_spec.rb index 8f87d0e7ff1..b3a3d7f0622 100644 --- a/spec/features/projects/services/disable_triggers_spec.rb +++ b/spec/features/projects/services/disable_triggers_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Disable individual triggers', :js do include_context 'project service activation' - let(:checkbox_selector) { 'input[type=checkbox][name$="_events]"]' } + let(:checkbox_selector) { 'input[name$="_events]"]' } before do visit_project_integration(service_name) @@ -18,7 +18,7 @@ RSpec.describe 'Disable individual triggers', :js do event_count = HipchatService.supported_events.count expect(page).to have_content "Trigger" - expect(page).to have_css(checkbox_selector, count: event_count) + expect(page).to have_css(checkbox_selector, visible: :all, count: event_count) end end @@ -27,7 +27,7 @@ RSpec.describe 'Disable individual triggers', :js do it "doesn't show unnecessary Trigger checkboxes" do expect(page).not_to have_content "Trigger" - expect(page).not_to have_css(checkbox_selector) + expect(page).not_to have_css(checkbox_selector, visible: :all) end end end diff --git a/spec/features/projects/services/user_activates_alerts_spec.rb b/spec/features/projects/services/user_activates_alerts_spec.rb index 95642f49d61..8b0acdf3618 100644 --- a/spec/features/projects/services/user_activates_alerts_spec.rb +++ b/spec/features/projects/services/user_activates_alerts_spec.rb @@ -15,35 +15,32 @@ RSpec.describe 'User activates Alerts', :js do end context 'when service is deactivated' do - it 'activates service' do + it 'user cannot activate service' do visit_project_services expect(page).to have_link(service_title) click_link(service_title) + expect(page).to have_callout_message expect(page).not_to have_active_service - - click_activate_service - wait_for_requests - - expect(page).to have_active_service + expect(page).to have_toggle_active_disabled end end context 'when service is activated' do + let_it_be(:activated_alerts_service) do + create(:alerts_service, :active, project: project) + end + before do visit_alerts_service - click_activate_service end - it 're-generates key' do - expect(reset_key.value).to be_blank - - click_reset_key - click_confirm_reset_key - wait_for_requests - - expect(reset_key.value).to be_present + it 'user cannot change settings' do + expect(page).to have_callout_message + expect(page).to have_active_service + expect(page).to have_toggle_active_disabled + expect(page).to have_button_reset_key_disabled end end @@ -57,25 +54,21 @@ RSpec.describe 'User activates Alerts', :js do visit(edit_project_service_path(project, service_name)) end - def click_activate_service - find('#activated').click - end - - def click_reset_key - click_button('Reset key') + def have_callout_message + within('.gl-alert') do + have_content('You can now manage alert endpoint configuration in the Alerts section on the Operations settings page.') + end end - def click_confirm_reset_key - within '.modal-content' do - click_reset_key - end + def have_active_service + have_selector('.js-service-active-status[data-value="true"]') end - def reset_key - find_field('Authorization key') + def have_toggle_active_disabled + have_selector('#activated .project-feature-toggle.is-disabled') end - def have_active_service - have_selector('.js-service-active-status[data-value="true"]') + def have_button_reset_key_disabled + have_button('Reset key', disabled: true) end end diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb index a2a2604c610..4f25794d058 100644 --- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb +++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb @@ -30,7 +30,7 @@ RSpec.describe 'User activates issue tracker', :js do it 'activates the service' do expect(page).to have_content("#{tracker} activated.") - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) end it 'shows the link in the menu' do @@ -50,7 +50,7 @@ RSpec.describe 'User activates issue tracker', :js do click_test_then_save_integration expect(page).to have_content("#{tracker} activated.") - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) end end end @@ -65,7 +65,7 @@ RSpec.describe 'User activates issue tracker', :js do it 'saves but does not activate the service' do expect(page).to have_content("#{tracker} settings saved, but not activated.") - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) end it 'does not show the external tracker link in the menu' do diff --git a/spec/features/projects/services/user_activates_jira_spec.rb b/spec/features/projects/services/user_activates_jira_spec.rb index 1da8a49699b..483671c4b5b 100644 --- a/spec/features/projects/services/user_activates_jira_spec.rb +++ b/spec/features/projects/services/user_activates_jira_spec.rb @@ -4,18 +4,7 @@ require 'spec_helper' RSpec.describe 'User activates Jira', :js do include_context 'project service activation' - - let(:url) { 'http://jira.example.com' } - let(:test_url) { 'http://jira.example.com/rest/api/2/serverInfo' } - - def fill_form(disable: false) - click_active_toggle if disable - - fill_in 'service_url', with: url - fill_in 'service_username', with: 'username' - fill_in 'service_password', with: 'password' - fill_in 'service_jira_issue_transition_id', with: '25' - end + include_context 'project service Jira context' describe 'user sets and activates Jira Service' do context 'when Jira connection test succeeds' do @@ -30,12 +19,17 @@ RSpec.describe 'User activates Jira', :js do it 'activates the Jira service' do expect(page).to have_content('Jira activated.') - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :jira)) end - it 'shows the Jira link in the menu' do - page.within('.nav-sidebar') do - expect(page).to have_link('Jira', href: url) + unless Gitlab.ee? + it 'adds Jira link to sidebar menu' do + page.within('.nav-sidebar') do + expect(page).not_to have_link('Jira Issues') + expect(page).not_to have_link('Issue List', visible: false) + expect(page).not_to have_link('Open Jira', href: url, visible: false) + expect(page).to have_link('Jira', href: url) + end end end end @@ -61,7 +55,7 @@ RSpec.describe 'User activates Jira', :js do click_test_then_save_integration expect(page).to have_content('Jira activated.') - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :jira)) end end end @@ -75,7 +69,7 @@ RSpec.describe 'User activates Jira', :js do it 'saves but does not activate the Jira service' do expect(page).to have_content('Jira settings saved, but not activated.') - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :jira)) end it 'does not show the Jira link in the menu' do diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb index a6b4aaccfb5..6ddffb710a8 100644 --- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb @@ -31,7 +31,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do click_active_toggle click_on 'Save changes' - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :mattermost_slash_commands)) expect(page).to have_content('Mattermost slash commands settings saved, but not activated.') end @@ -41,7 +41,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do fill_in 'service_token', with: token click_on 'Save changes' - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :mattermost_slash_commands)) expect(page).to have_content('Mattermost slash commands activated.') end diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb index 360e462b935..afe6855d6ad 100644 --- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Slack slash commands', :js do click_active_toggle click_on 'Save' - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :slack_slash_commands)) expect(page).to have_content('Slack slash commands settings saved, but not activated.') end @@ -32,7 +32,7 @@ RSpec.describe 'Slack slash commands', :js do fill_in 'Token', with: 'token' click_on 'Save' - expect(current_path).to eq(project_settings_integrations_path(project)) + expect(current_path).to eq(edit_project_service_path(project, :slack_slash_commands)) expect(page).to have_content('Slack slash commands activated.') end diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb index dfbb6342173..878794bd897 100644 --- a/spec/features/projects/settings/operations_settings_spec.rb +++ b/spec/features/projects/settings/operations_settings_spec.rb @@ -45,15 +45,12 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do it 'updates form values' do check(create_issue) - template_select = find_field('Issue template') - template_select.find(:xpath, 'option[2]').select_option uncheck(send_email) save_form click_expand_incident_management_button expect(find_field(create_issue)).to be_checked - expect(page).to have_select('Issue template', selected: 'bug') expect(find_field(send_email)).not_to be_checked end @@ -64,7 +61,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do end def save_form - page.within "#edit_project_#{project.id}" do + page.within ".qa-incident-management-settings" do click_on 'Save changes' end end diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb index 3dcb7ca54a1..8e2f97fd6a0 100644 --- a/spec/features/projects/settings/registry_settings_spec.rb +++ b/spec/features/projects/settings/registry_settings_spec.rb @@ -20,10 +20,10 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p it 'shows available section' do settings_block = find('#js-registry-policies') - expect(settings_block).to have_text 'Container Registry tag expiration policy' + expect(settings_block).to have_text 'Cleanup policy for tags' end - it 'saves expiration policy submit the form' do + it 'saves cleanup policy submit the form' do within '#js-registry-policies' do within '.card-body' do select('7 days until tags are automatically removed', from: 'Expiration interval:') @@ -36,10 +36,10 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p submit_button.click end toast = find('.gl-toast') - expect(toast).to have_content('Expiration policy successfully saved.') + expect(toast).to have_content('Cleanup policy successfully saved.') end - it 'does not save expiration policy submit form with invalid regex' do + it 'does not save cleanup policy submit form with invalid regex' do within '#js-registry-policies' do within '.card-body' do fill_in('Tags with names matching this regex pattern will expire:', with: '*-production') @@ -49,7 +49,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p submit_button.click end toast = find('.gl-toast') - expect(toast).to have_content('Something went wrong while updating the expiration policy.') + expect(toast).to have_content('Something went wrong while updating the cleanup policy.') end end diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb new file mode 100644 index 00000000000..7856ab1fb4e --- /dev/null +++ b/spec/features/projects/settings/service_desk_setting_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Service Desk Setting', :js do + let(:project) { create(:project_empty_repo, :private, service_desk_enabled: false) } + let(:presenter) { project.present(current_user: user) } + let(:user) { create(:user) } + + before do + project.add_maintainer(user) + sign_in(user) + + allow_any_instance_of(Project).to receive(:present).with(current_user: user).and_return(presenter) + allow(::Gitlab::IncomingEmail).to receive(:enabled?) { true } + allow(::Gitlab::IncomingEmail).to receive(:supports_wildcard?) { true } + + visit edit_project_path(project) + end + + it 'shows activation checkbox' do + expect(page).to have_selector("#service-desk-checkbox") + end + + it 'shows incoming email after activating' do + find("#service-desk-checkbox").click + wait_for_requests + project.reload + expect(project.service_desk_enabled).to be_truthy + expect(project.service_desk_address).to be_present + expect(find('.incoming-email').value).to eq(project.service_desk_address) + end +end diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb index 3fc1f47d98a..e97e4a2030a 100644 --- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb +++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb @@ -28,6 +28,22 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do end end + it 'shows Squash commit options', :aggregate_failures do + page.within '#js-merge-request-settings' do + expect(page).to have_content 'Do not allow' + expect(page).to have_content 'Squashing is never performed and the checkbox is hidden.' + + expect(page).to have_content 'Allow' + expect(page).to have_content 'Checkbox is visible and unselected by default.' + + expect(page).to have_content 'Encourage' + expect(page).to have_content 'Checkbox is visible and selected by default.' + + expect(page).to have_content 'Require' + expect(page).to have_content 'Squashing is always performed. Checkbox is visible and selected, and users cannot change it.' + end + end + context 'when Merge Request and Pipelines are initially enabled', :js do context 'when Pipelines are initially enabled' do it 'shows the Merge Requests settings' do @@ -130,4 +146,56 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do expect(project.remove_source_branch_after_merge).to be(false) end end + + describe 'Squash commits when merging', :js do + it 'initially has :squash_option set to :default_off' do + radio = find_field('project_project_setting_attributes_squash_option_default_off') + expect(radio).to be_checked + end + + it 'allows :squash_option to be set to :default_on' do + choose('project_project_setting_attributes_squash_option_default_on') + + within('.merge-request-settings-form') do + find('.qa-save-merge-request-changes') + click_on('Save changes') + end + + find('.flash-notice') + radio = find_field('project_project_setting_attributes_squash_option_default_on') + + expect(radio).to be_checked + expect(project.reload.project_setting.squash_option).to eq('default_on') + end + + it 'allows :squash_option to be set to :always' do + choose('project_project_setting_attributes_squash_option_always') + + within('.merge-request-settings-form') do + find('.qa-save-merge-request-changes') + click_on('Save changes') + end + + find('.flash-notice') + radio = find_field('project_project_setting_attributes_squash_option_always') + + expect(radio).to be_checked + expect(project.reload.project_setting.squash_option).to eq('always') + end + + it 'allows :squash_option to be set to :never' do + choose('project_project_setting_attributes_squash_option_never') + + within('.merge-request-settings-form') do + find('.qa-save-merge-request-changes') + click_on('Save changes') + end + + find('.flash-notice') + radio = find_field('project_project_setting_attributes_squash_option_never') + + expect(radio).to be_checked + expect(project.reload.project_setting.squash_option).to eq('never') + end + end end diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb index d32f4cb8ec7..3836b95a28a 100644 --- a/spec/features/projects/settings/user_manages_project_members_spec.rb +++ b/spec/features/projects/settings/user_manages_project_members_spec.rb @@ -16,15 +16,20 @@ RSpec.describe 'Projects > Settings > User manages project members' do sign_in(user) end - it 'cancels a team member' do + it 'cancels a team member', :js do visit(project_project_members_path(project)) project_member = project.project_members.find_by(user_id: user_dmitriy.id) page.within("#project_member_#{project_member.id}") do - click_link('Remove user from project') + # Open modal + click_on('Remove user from project') end + expect(page).to have_unchecked_field 'Also unassign this user from related issues and merge requests' + + click_on('Remove member') + visit(project_project_members_path(project)) expect(page).not_to have_content(user_dmitriy.name) diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb index a35f6420bdc..3b77fd7eebf 100644 --- a/spec/features/projects/show/user_sees_git_instructions_spec.rb +++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb @@ -18,6 +18,8 @@ RSpec.describe 'Projects > Show > User sees Git instructions' do page.within '.empty-wrapper' do expect(page).to have_content('Command line instructions') end + + expect(page).to have_content("git push -u origin master") end end @@ -59,6 +61,26 @@ RSpec.describe 'Projects > Show > User sees Git instructions' do include_examples 'shows details of empty project with no repo' end + context ":default_branch_name is specified" do + let_it_be(:project) { create(:project, :public) } + + before do + expect(Gitlab::CurrentSettings) + .to receive(:default_branch_name) + .at_least(:once) + .and_return('example_branch') + + sign_in(project.owner) + visit project_path(project) + end + + it "recommends default_branch_name instead of master" do + click_link 'Create empty repository' + + expect(page).to have_content("git push -u origin example_branch") + end + end + context 'when project is empty' do let_it_be(:project) { create(:project_empty_repo, :public) } 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 0f10b0a4010..afa9de5ce86 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 @@ -63,6 +63,23 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do expect(page).to have_link('Add LICENSE', href: presenter.add_license_path) end end + + context 'Gitlab::CurrentSettings.default_branch_name is available' do + before do + expect(Gitlab::CurrentSettings) + .to receive(:default_branch_name) + .at_least(:once) + .and_return('example_branch') + + visit project_path(project) + end + + it '"New file" button linked to new file page' do + page.within('.project-buttons') do + expect(page).to have_link('New file', href: project_new_blob_path(project, 'example_branch')) + end + end + end end end diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb index 388fa39874d..bd2af66710a 100644 --- a/spec/features/projects/tree/tree_show_spec.rb +++ b/spec/features/projects/tree/tree_show_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Projects tree', :js do + include RepoHelpers + let(:user) { create(:user) } let(:project) { create(:project, :repository) } let(:gravatar_enabled) { true } @@ -47,6 +49,30 @@ RSpec.describe 'Projects tree', :js do expect(page).not_to have_selector('.flash-alert') end + context "with a tree that contains pathspec characters" do + let(:path) { ':wq' } + let(:filename) { File.join(path, 'test.txt') } + let(:newrev) { project.repository.commit('master').sha } + let(:short_newrev) { project.repository.commit('master').short_id } + let(:message) { 'Glob characters'} + + before do + create_file_in_repo(project, 'master', 'master', filename, 'Test file', commit_message: message) + visit project_tree_path(project, File.join('master', path)) + wait_for_requests + end + + it "renders tree table without errors" do + expect(page).to have_selector('.tree-item') + expect(page).to have_content('test.txt') + expect(page).to have_content(message) + + # Check last commit + expect(find('.commit-content').text).to include(message) + expect(find('.commit-sha-group').text).to eq(short_newrev) + end + end + context 'gravatar disabled' do let(:gravatar_enabled) { false } diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb index cc2a9eacbad..1d443e0b339 100644 --- a/spec/features/projects/user_sees_sidebar_spec.rb +++ b/spec/features/projects/user_sees_sidebar_spec.rb @@ -6,6 +6,10 @@ RSpec.describe 'Projects > User sees sidebar' do let(:user) { create(:user) } let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) } + before do + stub_feature_flags(vue_issuables_list: false) + end + # NOTE: See documented behaviour https://design.gitlab.com/regions/navigation#contextual-navigation context 'on different viewports', :js do include MobileHelpers diff --git a/spec/features/projects/user_sees_user_popover_spec.rb b/spec/features/projects/user_sees_user_popover_spec.rb index 851ce79e1c6..9cfc6234969 100644 --- a/spec/features/projects/user_sees_user_popover_spec.rb +++ b/spec/features/projects/user_sees_user_popover_spec.rb @@ -19,7 +19,7 @@ RSpec.describe 'User sees user popover', :js do subject { page } describe 'hovering over a user link in a merge request' do - let(:popover_selector) { '.user-popover' } + let(:popover_selector) { '[data-testid="user-popover"]' } before do visit project_merge_request_path(project, merge_request) diff --git a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb index d9f79162c19..0af40a2d760 100644 --- a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb @@ -4,18 +4,19 @@ require 'spec_helper' RSpec.describe 'User views empty wiki' do let(:user) { create(:user) } + let(:confluence_link) { 'Enable the Confluence Wiki integration' } + let(:element) { page.find('.row.empty-state') } shared_examples 'empty wiki and accessible issues' do it 'show "issue tracker" message' do visit(project_wikis_path(project)) - element = page.find('.row.empty-state') - expect(element).to have_content('This project has no wiki pages') expect(element).to have_content('You must be a project member') expect(element).to have_content('improve the wiki for this project') expect(element).to have_link("issue tracker", href: project_issues_path(project)) expect(element).to have_link("Suggest wiki improvement", href: new_project_issue_path(project)) + expect(element).to have_no_link(confluence_link) end end @@ -23,11 +24,10 @@ RSpec.describe 'User views empty wiki' do it 'does not show "issue tracker" message' do visit(project_wikis_path(project)) - element = page.find('.row.empty-state') - expect(element).to have_content('This project has no wiki pages') expect(element).to have_content('You must be a project member') expect(element).to have_no_link('Suggest wiki improvement') + expect(element).to have_no_link(confluence_link) end end @@ -60,16 +60,15 @@ RSpec.describe 'User views empty wiki' do end context 'when user is logged in and a member' do - let(:project) { create(:project, :public, :wiki_repo) } + let(:project) { create(:project, :public) } before do sign_in(user) project.add_developer(user) end - it 'show "create first page" message' do + it 'shows "create first page" message' do visit(project_wikis_path(project)) - element = page.find('.row.empty-state') expect(element).to have_content('your project', count: 2) @@ -77,5 +76,34 @@ RSpec.describe 'User views empty wiki' do expect(page).to have_button('Create page') end + + it 'does not show the "enable confluence" button' do + visit(project_wikis_path(project)) + + expect(element).to have_no_link(confluence_link) + end + end + + context 'when user is logged in and an admin' do + let(:project) { create(:project, :public, :wiki_repo) } + + before do + sign_in(user) + project.add_maintainer(user) + end + + it 'shows the "enable confluence" button' do + visit(project_wikis_path(project)) + + expect(element).to have_link(confluence_link) + end + + it 'does not show "enable confluence" button if confluence is already enabled' do + create(:confluence_service, project: project) + + visit(project_wikis_path(project)) + + expect(element).to have_no_link(confluence_link) + end end end diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb index 59ccb83a9bb..e93689af0aa 100644 --- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb @@ -8,9 +8,10 @@ RSpec.describe 'User views a wiki page' do let(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } let(:path) { 'image.png' } + let(:wiki) { project.wiki } let(:wiki_page) do create(:wiki_page, - wiki: project.wiki, + wiki: wiki, title: 'home', content: "Look at this [image](#{path})\n\n ![alt text](#{path})") end @@ -70,11 +71,13 @@ RSpec.describe 'User views a wiki page' do click_on('Page history') - page.within(:css, '.nav-text') do + within('.nav-text') do expect(page).to have_content('History') end - find('a[href*="?version_id"]') + within('.wiki-history') do + expect(page).to have_css('a[href*="?version_id"]', count: 4) + end end end @@ -92,8 +95,8 @@ RSpec.describe 'User views a wiki page' do let(:path) { upload_file_to_wiki(project, user, 'dk.png') } it do - expect(page).to have_xpath("//img[@data-src='#{project.wiki.wiki_base_path}/#{path}']") - expect(page).to have_link('image', href: "#{project.wiki.wiki_base_path}/#{path}") + expect(page).to have_xpath("//img[@data-src='#{wiki.wiki_base_path}/#{path}']") + expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/#{path}") click_on('image') @@ -103,7 +106,7 @@ RSpec.describe 'User views a wiki page' do end it 'shows the creation page if file does not exist' do - expect(page).to have_link('image', href: "#{project.wiki.wiki_base_path}/#{path}") + expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/#{path}") click_on('image') @@ -114,7 +117,7 @@ RSpec.describe 'User views a wiki page' do context 'when a page has history' do before do - wiki_page.update(message: 'updated home', content: 'updated [some link](other-page)') + wiki_page.update(message: 'updated home', content: 'updated [some link](other-page)') # rubocop:disable Rails/SaveBang end it 'shows the page history' do @@ -134,13 +137,74 @@ RSpec.describe 'User views a wiki page' do expect(page).not_to have_selector('a.btn', text: 'Edit') end + + context 'show the diff' do + def expect_diff_links(commit) + diff_path = wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff) + + expect(page).to have_link('Hide whitespace changes', href: "#{diff_path}&w=1") + expect(page).to have_link('Inline', href: "#{diff_path}&view=inline") + expect(page).to have_link('Side-by-side', href: "#{diff_path}&view=parallel") + expect(page).to have_link("View page @ #{commit.short_id}", href: wiki_page_path(wiki, wiki_page, version_id: commit)) + expect(page).to have_css('.diff-file[data-blob-diff-path="%s"]' % diff_path) + end + + it 'links to the correct diffs' do + visit project_wiki_history_path(project, wiki_page) + + commit1 = wiki.commit('HEAD^') + commit2 = wiki.commit + + expect(page).to have_link('created page: home', href: wiki_page_path(wiki, wiki_page, version_id: commit1, action: :diff)) + expect(page).to have_link('updated home', href: wiki_page_path(wiki, wiki_page, version_id: commit2, action: :diff)) + end + + it 'between the current and the previous version of a page' do + commit = wiki.commit + visit wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff) + + expect(page).to have_content('by John Doe') + expect(page).to have_content('updated home') + expect(page).to have_content('Showing 1 changed file with 1 addition and 3 deletions') + expect(page).to have_content('some link') + + expect_diff_links(commit) + end + + it 'between two old versions of a page' do + wiki_page.update(message: 'latest home change', content: 'updated [another link](other-page)') # rubocop:disable Rails/SaveBang: + commit = wiki.commit('HEAD^') + visit wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff) + + expect(page).to have_content('by John Doe') + expect(page).to have_content('updated home') + expect(page).to have_content('Showing 1 changed file with 1 addition and 3 deletions') + expect(page).to have_content('some link') + expect(page).not_to have_content('latest home change') + expect(page).not_to have_content('another link') + + expect_diff_links(commit) + end + + it 'for the oldest version of a page' do + commit = wiki.commit('HEAD^') + visit wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff) + + expect(page).to have_content('by John Doe') + expect(page).to have_content('created page: home') + expect(page).to have_content('Showing 1 changed file with 4 additions and 0 deletions') + expect(page).to have_content('Look at this') + + expect_diff_links(commit) + end + end end context 'when a page has special characters in its title' do let(:title) { '<foo> !@#$%^&*()[]{}=_+\'"\\|<>? <bar>' } before do - wiki_page.update(title: title ) + wiki_page.update(title: title ) # rubocop:disable Rails/SaveBang end it 'preserves the special characters' do @@ -155,7 +219,7 @@ RSpec.describe 'User views a wiki page' do let(:title) { '<script>alert("title")<script>' } before do - wiki_page.update(title: title, content: 'foo <script>alert("content")</script> bar') + wiki_page.update(title: title, content: 'foo <script>alert("content")</script> bar') # rubocop:disable Rails/SaveBang end it 'safely displays the page' do @@ -168,7 +232,7 @@ RSpec.describe 'User views a wiki page' do context 'when a page has XSS in its message' do before do - wiki_page.update(message: '<script>alert(true)<script>', content: 'XSS update') + wiki_page.update(message: '<script>alert(true)<script>', content: 'XSS update') # rubocop:disable Rails/SaveBang end it 'safely displays the message' do |