diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 11:43:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 11:43:02 +0300 |
commit | d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb (patch) | |
tree | 2341ef426af70ad1e289c38036737e04b0aa5007 /spec/features/projects | |
parent | d6e514dd13db8947884cd58fe2a9c2a063400a9b (diff) |
Add latest changes from gitlab-org/gitlab@14-4-stable-eev14.4.0-rc42
Diffstat (limited to 'spec/features/projects')
20 files changed, 517 insertions, 78 deletions
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb index 1760ec880bc..5c1bc1ad239 100644 --- a/spec/features/projects/badges/coverage_spec.rb +++ b/spec/features/projects/badges/coverage_spec.rb @@ -12,6 +12,120 @@ RSpec.describe 'test coverage badge' do sign_in(user) end + it 'user requests coverage badge image for pipeline with custom limits - 80% good' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 80, name: 'test:1') + end + + show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25) + + expect_coverage_badge_color(:good) + expect_coverage_badge('80.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 74% - bad config' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 74, name: 'test:1') + end + # User sets a minimum good value that is lower than min acceptable and min medium, + # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1 + show_test_coverage_badge(min_good: 75, min_acceptable: 76, min_medium: 77) + + expect_coverage_badge_color(:acceptable) + expect_coverage_badge('74.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 73% - bad config' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 73, name: 'test:1') + end + # User sets a minimum good value that is lower than min acceptable and min medium, + # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1 + show_test_coverage_badge(min_good: 75, min_acceptable: 76, min_medium: 77) + + expect_coverage_badge_color(:medium) + expect_coverage_badge('73.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 72% - partial config - low' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 72, name: 'test:1') + end + # User only sets good to 75 and leaves the others on the default settings, + # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1 + show_test_coverage_badge(min_good: 75) + + expect_coverage_badge_color(:low) + expect_coverage_badge('72.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 72% - partial config - medium' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 72, name: 'test:1') + end + # User only sets good to 74 and leaves the others on the default settings, + # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1 + show_test_coverage_badge(min_good: 74) + + expect_coverage_badge_color(:medium) + expect_coverage_badge('72.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 72% - partial config - medium v2' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 72, name: 'test:1') + end + # User only sets medium to 72 and leaves the others on the defaults good as 95 and acceptable as 90 + show_test_coverage_badge(min_medium: 72) + + expect_coverage_badge_color(:medium) + expect_coverage_badge('72.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 70% acceptable' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 70, name: 'test:1') + end + + show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25) + + expect_coverage_badge_color(:acceptable) + expect_coverage_badge('70.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 30% medium' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 30, name: 'test:1') + end + + show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25) + + expect_coverage_badge_color(:medium) + expect_coverage_badge('30.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - 20% low' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 20, name: 'test:1') + end + + show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25) + + expect_coverage_badge_color(:low) + expect_coverage_badge('20.00%') + end + + it 'user requests coverage badge image for pipeline with custom limits - nonsense values which use the defaults' do + create_pipeline do |pipeline| + create_build(pipeline, coverage: 92, name: 'test:1') + end + + show_test_coverage_badge(min_good: "nonsense", min_acceptable: "rubbish", min_medium: "NaN") + + expect_coverage_badge_color(:acceptable) + expect_coverage_badge('92.00%') + end + it 'user requests coverage badge image for pipeline' do create_pipeline do |pipeline| create_build(pipeline, coverage: 100, name: 'test:1') @@ -20,6 +134,7 @@ RSpec.describe 'test coverage badge' do show_test_coverage_badge + expect_coverage_badge_color(:good) expect_coverage_badge('95.00%') end @@ -32,6 +147,7 @@ RSpec.describe 'test coverage badge' do show_test_coverage_badge(job: 'coverage') + expect_coverage_badge_color(:medium) expect_coverage_badge('85.00%') end @@ -73,8 +189,9 @@ RSpec.describe 'test coverage badge' do create(:ci_build, :success, opts) end - def show_test_coverage_badge(job: nil) - visit coverage_project_badges_path(project, ref: :master, job: job, format: :svg) + def show_test_coverage_badge(job: nil, min_good: nil, min_acceptable: nil, min_medium: nil) + visit coverage_project_badges_path(project, ref: :master, job: job, min_good: min_good, + min_acceptable: min_acceptable, min_medium: min_medium, format: :svg) end def expect_coverage_badge(coverage) @@ -82,4 +199,12 @@ RSpec.describe 'test coverage badge' do expect(page.response_headers['Content-Type']).to include('image/svg+xml') expect(svg.at(%Q{text:contains("#{coverage}")})).to be_truthy end + + def expect_coverage_badge_color(color) + svg = Nokogiri::HTML(page.body) + expect(page.response_headers['Content-Type']).to include('image/svg+xml') + badge_color = svg.xpath("//path[starts-with(@d, 'M62')]")[0].attributes['fill'].to_s + expected_badge_color = Gitlab::Ci::Badge::Coverage::Template::STATUS_COLOR[color] + expect(badge_color).to eq(expected_badge_color) + end end diff --git a/spec/features/projects/badges/pipeline_badge_spec.rb b/spec/features/projects/badges/pipeline_badge_spec.rb index 9d8f9872a1a..e3a01ab6fa2 100644 --- a/spec/features/projects/badges/pipeline_badge_spec.rb +++ b/spec/features/projects/badges/pipeline_badge_spec.rb @@ -68,7 +68,7 @@ RSpec.describe 'Pipeline Badge' do visit pipeline_project_badges_path(project, ref: ref, format: :svg) expect(page.status_code).to eq(200) - expect(page.response_headers['Cache-Control']).to eq('no-store') + expect(page.response_headers['Cache-Control']).to eq('private, no-store') end end diff --git a/spec/features/projects/ci/lint_spec.rb b/spec/features/projects/ci/lint_spec.rb index 0d9ea6331a7..7f10c6afcd5 100644 --- a/spec/features/projects/ci/lint_spec.rb +++ b/spec/features/projects/ci/lint_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'CI Lint', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297782' do +RSpec.describe 'CI Lint', :js do include Spec::Support::Helpers::Features::SourceEditorSpecHelpers let(:project) { create(:project, :repository) } diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb index 40d0260eafd..eec50c3a66a 100644 --- a/spec/features/projects/container_registry_spec.rb +++ b/spec/features/projects/container_registry_spec.rb @@ -20,6 +20,7 @@ RSpec.describe 'Container Registry', :js do sign_in(user) project.add_developer(user) stub_container_registry_config(enabled: true) + stub_container_registry_info stub_container_registry_tags(repository: :any, tags: []) end @@ -96,6 +97,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="additional-actions"]').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 @@ -121,6 +123,16 @@ RSpec.describe 'Container Registry', :js do expect(page).to have_content('Digest: N/A') end end + + [ContainerRegistry::Path::InvalidRegistryPathError, Faraday::Error].each do |error_class| + context "when there is a #{error_class}" do + before do + expect(::ContainerRegistry::Client).to receive(:registry_info).and_raise(error_class, nil, nil) + end + + it_behaves_like 'handling feature network errors with the container registry' + end + end end describe 'image repo details when image has no name' do diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 9413fae02e0..34e2ca7c8a7 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -226,6 +226,7 @@ RSpec.describe 'Environments page', :js do end it 'does not show terminal button' do + expect(page).not_to have_button(_('More actions')) expect(page).not_to have_terminal_button end @@ -273,6 +274,7 @@ RSpec.describe 'Environments page', :js do let(:role) { :maintainer } it 'shows the terminal button' do + click_button(_('More actions')) expect(page).to have_terminal_button end end @@ -281,6 +283,7 @@ RSpec.describe 'Environments page', :js do let(:role) { :developer } it 'does not show terminal button' do + expect(page).not_to have_button(_('More actions')) expect(page).not_to have_terminal_button end end @@ -515,7 +518,7 @@ RSpec.describe 'Environments page', :js do end def have_terminal_button - have_link(nil, href: terminal_project_environment_path(project, environment)) + have_link(_('Terminal'), href: terminal_project_environment_path(project, environment)) end def visit_environments(project, **opts) diff --git a/spec/features/projects/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb index 46b93d738e1..5ad7641a5be 100644 --- a/spec/features/projects/files/user_creates_directory_spec.rb +++ b/spec/features/projects/files/user_creates_directory_spec.rb @@ -98,12 +98,14 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do expect(page).to have_content(fork_message) find('.add-to-tree').click + wait_for_requests click_link('New directory') fill_in(:dir_name, with: 'new_directory') fill_in(:commit_message, with: 'New commit message', visible: true) click_button('Create directory') fork = user.fork_of(project2.reload) + wait_for_requests expect(current_path).to eq(project_new_merge_request_path(fork)) end diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb index 54e816d3d13..cc621dfd9f8 100644 --- a/spec/features/projects/files/user_uploads_files_spec.rb +++ b/spec/features/projects/files/user_uploads_files_spec.rb @@ -19,13 +19,15 @@ RSpec.describe 'Projects > Files > User uploads files' do wait_for_requests end - include_examples 'it uploads and commits a new text file' + [true, false].each do |value| + include_examples 'it uploads and commits a new text file', drop: value - include_examples 'it uploads and commits a new image file' + include_examples 'it uploads and commits a new image file', drop: value - include_examples 'it uploads and commits a new pdf file' + include_examples 'it uploads and commits a new pdf file', drop: value - include_examples 'it uploads a file to a sub-directory' + include_examples 'it uploads a file to a sub-directory', drop: value + end end context 'when a user does not have write access' do @@ -35,6 +37,8 @@ RSpec.describe 'Projects > Files > User uploads files' do visit(project_tree_path(project2)) end - include_examples 'it uploads and commits a new file to a forked project' + [true, false].each do |value| + include_examples 'it uploads and commits a new file to a forked project', drop: value + end end end diff --git a/spec/features/projects/infrastructure_registry_spec.rb b/spec/features/projects/infrastructure_registry_spec.rb index 16dd96e6c02..ee35e02b5e8 100644 --- a/spec/features/projects/infrastructure_registry_spec.rb +++ b/spec/features/projects/infrastructure_registry_spec.rb @@ -45,10 +45,8 @@ RSpec.describe 'Infrastructure Registry' do expect(page).to have_css('.packages-app h1[data-testid="title"]', text: terraform_module.name) - page.within(%Q([name="#{terraform_module.name}"])) do - expect(page).to have_content('Provision instructions') - expect(page).to have_content('Registry setup') - end + expect(page).to have_content('Provision instructions') + expect(page).to have_content('Registry setup') end end diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb index dbcd7b5caf5..8538b894869 100644 --- a/spec/features/projects/jobs/user_browses_jobs_spec.rb +++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb @@ -2,36 +2,276 @@ require 'spec_helper' +def visit_jobs_page + visit(project_jobs_path(project)) + + wait_for_requests +end + RSpec.describe 'User browses jobs' do - let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) } - let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') } - let(:project) { create(:project, :repository, namespace: user.namespace) } - let(:user) { create(:user) } + describe 'with jobs_table_vue feature flag turned off' do + let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) } + let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') } + let(:project) { create(:project, :repository, namespace: user.namespace) } + let(:user) { create(:user) } - before do - stub_feature_flags(jobs_table_vue: false) - project.add_maintainer(user) - project.enable_ci - project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/) + before do + stub_feature_flags(jobs_table_vue: false) + project.add_maintainer(user) + project.enable_ci + project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/) - sign_in(user) + sign_in(user) - visit(project_jobs_path(project)) - end + visit(project_jobs_path(project)) + end - it 'shows the coverage' do - page.within('td.coverage') do - expect(page).to have_content('99.9%') + it 'shows the coverage' do + page.within('td.coverage') do + expect(page).to have_content('99.9%') + end + end + + context 'with a failed job' do + let!(:build) { create(:ci_build, :coverage, :failed, pipeline: pipeline) } + + it 'displays a tooltip with the failure reason' do + page.within('.ci-table') do + failed_job_link = page.find('.ci-failed') + expect(failed_job_link[:title]).to eq('Failed - (unknown failure)') + end + end end end - context 'with a failed job' do - let!(:build) { create(:ci_build, :coverage, :failed, pipeline: pipeline) } + describe 'with jobs_table_vue feature flag turned on', :js do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + + before do + stub_feature_flags(jobs_table_vue: true) + + project.add_maintainer(user) + project.enable_ci + + sign_in(user) + end + + describe 'header tabs' do + before do + visit_jobs_page + end + + it 'shows a tab for All jobs and count' do + expect(page.find('[data-testid="jobs-all-tab"]').text).to include('All') + expect(page.find('[data-testid="jobs-all-tab"] .badge').text).to include('0') + end + + it 'shows a tab for Pending jobs and count' do + expect(page.find('[data-testid="jobs-pending-tab"]').text).to include('Pending') + expect(page.find('[data-testid="jobs-pending-tab"] .badge').text).to include('0') + end + + it 'shows a tab for Running jobs and count' do + expect(page.find('[data-testid="jobs-running-tab"]').text).to include('Running') + expect(page.find('[data-testid="jobs-running-tab"] .badge').text).to include('0') + end + + it 'shows a tab for Finished jobs and count' do + expect(page.find('[data-testid="jobs-finished-tab"]').text).to include('Finished') + expect(page.find('[data-testid="jobs-finished-tab"] .badge').text).to include('0') + end + + it 'updates the content when tab is clicked' do + page.find('[data-testid="jobs-finished-tab"]').click + wait_for_requests + + expect(page).to have_content('No jobs to show') + end + end + + describe 'Empty state' do + before do + visit_jobs_page + end + + it 'renders an empty state' do + expect(page).to have_content 'Use jobs to automate your tasks' + expect(page).to have_content 'Create CI/CD configuration file' + end + end + + describe 'Job actions' do + let!(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: 'master') } + + context 'when a job can be canceled' do + let!(:job) do + create(:ci_build, pipeline: pipeline, + stage: 'test') + end + + before do + job.run + + visit_jobs_page + end + + it 'cancels a job successfully' do + page.find('[data-testid="cancel-button"]').click + + wait_for_requests + + expect(page).to have_selector('.ci-canceled') + end + end + + context 'when a job can be retried' do + let!(:job) do + create(:ci_build, pipeline: pipeline, + stage: 'test') + end + + before do + job.drop + + visit_jobs_page + end + + it 'retries a job successfully' do + page.find('[data-testid="retry"]').click + + wait_for_requests + + expect(page).to have_selector('.ci-pending') + end + end + + context 'with a scheduled job' do + let!(:scheduled_job) { create(:ci_build, :scheduled, pipeline: pipeline, name: 'build') } + + before do + visit_jobs_page + end + + it 'plays a job successfully' do + page.find('[data-testid="play-scheduled"]').click + + page.within '#play-job-modal' do + page.find_button('OK').click + end + + wait_for_requests + + expect(page).to have_selector('.ci-pending') + end + + it 'unschedules a job successfully' do + page.find('[data-testid="unschedule"]').click + + wait_for_requests + + expect(page).to have_selector('.ci-manual') + end + end + + context 'with downloadable artifacts' do + let!(:with_artifacts) do + build = create(:ci_build, :success, + pipeline: pipeline, + name: 'rspec tests', + stage: 'test') + + create(:ci_job_artifact, :codequality, job: build) + end + + before do + visit_jobs_page + end + + it 'shows the download artifacts button' do + expect(page).to have_selector('[data-testid="download-artifacts"]') + end + end + + context 'with artifacts expired' do + let!(:with_artifacts_expired) do + create(:ci_build, :expired, :success, + pipeline: pipeline, + name: 'rspec', + stage: 'test') + end + + before do + visit_jobs_page + end + + it 'does not show the download artifacts button' do + expect(page).not_to have_selector('[data-testid="download-artifacts"]') + end + end + end + + describe 'Jobs table' do + let!(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: 'master') } + + context 'column links' do + let!(:job) do + create(:ci_build, pipeline: pipeline, + stage: 'test') + end + + before do + job.run + + visit_jobs_page + end + + it 'contains a link to the pipeline' do + expect(page.find('[data-testid="pipeline-id"]')).to have_content "##{pipeline.id}" + end + + it 'contains a link to the job sha' do + expect(page.find('[data-testid="job-sha"]')).to have_content "#{job.sha[0..7]}" + end + + it 'contains a link to the job id' do + expect(page.find('[data-testid="job-id-link"]')).to have_content "#{job.id}" + end + + it 'contains a link to the job ref' do + expect(page.find('[data-testid="job-ref"]')).to have_content "#{job.ref}" + end + end + end + + describe 'when user is not logged in' do + before do + sign_out(user) + end + + context 'when project is public' do + let(:public_project) { create(:project, :public, :repository) } + + context 'without jobs' do + it 'shows an empty state' do + visit project_jobs_path(public_project) + wait_for_requests + + expect(page).to have_content 'Use jobs to automate your tasks' + end + end + end + + context 'when project is private' do + let(:private_project) { create(:project, :private, :repository) } + + it 'redirects the user to sign_in and displays the flash alert' do + visit project_jobs_path(private_project) + wait_for_requests - it 'displays a tooltip with the failure reason' do - page.within('.ci-table') do - failed_job_link = page.find('.ci-failed') - expect(failed_job_link[:title]).to eq('Failed - (unknown failure)') + expect(page).to have_content 'You need to sign in' + expect(page.current_path).to eq("/users/sign_in") + end end end end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index a1416f3f563..7ccd5c51493 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -46,7 +46,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do end it "shows Pending tab jobs" do - expect(page).to have_selector('.nav-links li.active', text: 'Pending') + expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Pending') expect(page).to have_content job.short_sha expect(page).to have_content job.ref expect(page).to have_content job.name @@ -60,7 +60,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do end it "shows Running tab jobs" do - expect(page).to have_selector('.nav-links li.active', text: 'Running') + expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Running') expect(page).to have_content job.short_sha expect(page).to have_content job.ref expect(page).to have_content job.name @@ -74,7 +74,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do end it "shows Finished tab jobs" do - expect(page).to have_selector('.nav-links li.active', text: 'Finished') + expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Finished') expect(page).to have_content('Use jobs to automate your tasks') end end @@ -86,7 +86,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do end it "shows All tab jobs" do - expect(page).to have_selector('.nav-links li.active', text: 'All') + expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'All') expect(page).to have_content job.short_sha expect(page).to have_content job.ref expect(page).to have_content job.name diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb index 84a972b3027..eb32570448b 100644 --- a/spec/features/projects/members/groups_with_access_list_spec.rb +++ b/spec/features/projects/members/groups_with_access_list_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :public) } let_it_be(:project) { create(:project, :public) } + let_it_be(:expiration_date) { 5.days.from_now.to_date } let(:additional_link_attrs) { {} } let!(:group_link) { create(:project_group_link, project: project, group: group, **additional_link_attrs) } @@ -37,27 +38,27 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do it 'updates expiry date' do page.within find_group_row(group) do - fill_in 'Expiration date', with: 5.days.from_now.to_date + fill_in 'Expiration date', with: expiration_date find_field('Expiration date').native.send_keys :enter wait_for_requests - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) end end context 'when link has expiry date set' do - let(:additional_link_attrs) { { expires_at: 5.days.from_now.to_date } } + let(:additional_link_attrs) { { expires_at: expiration_date } } it 'clears expiry date' do page.within find_group_row(group) do - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) find('[data-testid="clear-button"]').click wait_for_requests - expect(page).to have_content('No expiration set') + expect(page).to have_field('Expiration date', with: '') end end end diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb index 8c3646125a5..b674cad0312 100644 --- a/spec/features/projects/members/invite_group_spec.rb +++ b/spec/features/projects/members/invite_group_spec.rb @@ -165,6 +165,8 @@ RSpec.describe 'Project > Members > Invite group', :js do let(:project) { create(:project) } let!(:group) { create(:group) } + let_it_be(:expiration_date) { 5.days.from_now.to_date } + around do |example| freeze_time { example.run } end @@ -176,15 +178,14 @@ RSpec.describe 'Project > Members > Invite group', :js do visit project_project_members_path(project) - invite_group(group.name, role: 'Guest', expires_at: 5.days.from_now) + invite_group(group.name, role: 'Guest', expires_at: expiration_date) end it 'the group link shows the expiration time with a warning class' do setup click_link 'Groups' - expect(find_group_row(group)).to have_content(/in \d days/) - expect(find_group_row(group)).to have_selector('.gl-text-orange-500') + expect(page).to have_field('Expiration date', with: expiration_date) end end diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb index c1b14cf60e7..830ada29a2e 100644 --- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb @@ -9,6 +9,8 @@ RSpec.describe 'Projects > Members > Maintainer adds member with expiration date let_it_be(:maintainer) { create(:user) } let_it_be(:project) { create(:project) } + let_it_be(:three_days_from_now) { 3.days.from_now.to_date } + let_it_be(:five_days_from_now) { 5.days.from_now.to_date } let(:new_member) { create(:user) } @@ -22,39 +24,39 @@ RSpec.describe 'Projects > Members > Maintainer adds member with expiration date it 'expiration date is displayed in the members list' do visit project_project_members_path(project) - invite_member(new_member.name, role: 'Guest', expires_at: 5.days.from_now.to_date) + invite_member(new_member.name, role: 'Guest', expires_at: five_days_from_now) page.within find_member_row(new_member) do - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: five_days_from_now) end end it 'changes expiration date' do - project.team.add_users([new_member.id], :developer, expires_at: 3.days.from_now.to_date) + project.team.add_users([new_member.id], :developer, expires_at: three_days_from_now) visit project_project_members_path(project) page.within find_member_row(new_member) do - fill_in 'Expiration date', with: 5.days.from_now.to_date + fill_in 'Expiration date', with: five_days_from_now find_field('Expiration date').native.send_keys :enter wait_for_requests - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: five_days_from_now) end end it 'clears expiration date' do - project.team.add_users([new_member.id], :developer, expires_at: 5.days.from_now.to_date) + project.team.add_users([new_member.id], :developer, expires_at: five_days_from_now) visit project_project_members_path(project) page.within find_member_row(new_member) do - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: five_days_from_now) find('[data-testid="clear-button"]').click wait_for_requests - expect(page).to have_content('No expiration set') + expect(page).to have_field('Expiration date', with: '') end end diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb index 876bc82d16c..f61eaccf5b9 100644 --- a/spec/features/projects/navbar_spec.rb +++ b/spec/features/projects/navbar_spec.rb @@ -18,6 +18,7 @@ RSpec.describe 'Project navbar' do stub_config(registry: { enabled: false }) insert_package_nav(_('Infrastructure')) insert_infrastructure_registry_nav + insert_infrastructure_google_cloud_nav end it_behaves_like 'verified navigation bar' do diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 39f9d3b331b..dacbaa826a0 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -296,12 +296,16 @@ RSpec.describe 'New project', :js do expect(git_import_instructions).to have_content 'Git repository URL' end - it 'reports error if repo URL does not end with .git' do + it 'reports error if repo URL is not a valid Git repository' do + stub_request(:get, "http://foo/bar/info/refs?service=git-upload-pack").to_return(status: 200, body: "not-a-git-repo") + fill_in 'project_import_url', with: 'http://foo/bar' # simulate blur event find('body').click - expect(page).to have_text('A repository URL usually ends in a .git suffix') + wait_for_requests + + expect(page).to have_text('There is not a valid Git repository at this URL') end it 'keeps "Import project" tab open after form validation error' do diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb index 7fcc8200b1c..9b1e87192f5 100644 --- a/spec/features/projects/packages_spec.rb +++ b/spec/features/projects/packages_spec.rb @@ -27,6 +27,10 @@ RSpec.describe 'Packages' do context 'when feature is available', :js do before do + # we are simply setting the featrure flag to false because the new UI has nothing to test yet + # when the refactor is complete or almost complete we will turn on the feature tests + # see https://gitlab.com/gitlab-org/gitlab/-/issues/330846 for status of this work + stub_feature_flags(package_list_apollo: false) visit_project_packages end diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb index e3d75c30e5e..3f6c4646f00 100644 --- a/spec/features/projects/settings/monitor_settings_spec.rb +++ b/spec/features/projects/settings/monitor_settings_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Projects > Settings > For a forked project', :js do let_it_be(:project) { create(:project, :repository, create_templates: :issue) } - let(:user) { project.owner} + let(:user) { project.owner } before do sign_in(user) @@ -16,7 +16,8 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do visit project_path(project) wait_for_requests - expect(page).to have_selector('.sidebar-sub-level-items a[aria-label="Monitor"]', text: 'Monitor', visible: false) + expect(page).to have_selector('.sidebar-sub-level-items a[aria-label="Monitor"]', + text: 'Monitor', visible: :hidden) end end @@ -42,7 +43,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do expect(find_field(send_email)).to be_checked end - it 'updates form values', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333665' do + it 'updates form values' do check(create_issue) uncheck(send_email) click_on('No template selected') @@ -52,10 +53,8 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do click_settings_tab expect(find_field(create_issue)).to be_checked - expect(page).to have_selector(:id, 'alert-integration-settings-issue-template', text: 'bug') - - click_settings_tab expect(find_field(send_email)).not_to be_checked + expect(page).to have_selector(:id, 'alert-integration-settings-issue-template', text: 'bug') end def click_settings_tab @@ -68,13 +67,15 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do page.within '[data-testid="alert-integration-settings"]' do click_button 'Save changes' end + + wait_for_all_requests end end - context 'error tracking settings form' do + describe 'error tracking settings form' do let(:sentry_list_projects_url) { 'http://sentry.example.com/api/0/projects/' } - context 'success path' do + context 'when project dropdown is loaded' do let(:projects_sample_response) do Gitlab::Utils.deep_indifferent_access( Gitlab::Json.parse(fixture_file('sentry/list_projects_sample_response.json')) @@ -97,7 +98,9 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do within '.js-error-tracking-settings' do click_button('Expand') + choose('cloud-hosted Sentry') end + expect(page).to have_content('Sentry API URL') expect(page.body).to include('Error Tracking') expect(page).to have_button('Connect') @@ -121,7 +124,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do end end - context 'project dropdown fails to load' do + context 'when project dropdown fails to load' do before do WebMock.stub_request(:get, sentry_list_projects_url) .to_return( @@ -140,8 +143,10 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do within '.js-error-tracking-settings' do click_button('Expand') + choose('cloud-hosted Sentry') + check('Active') end - check('Active') + fill_in('error-tracking-api-host', with: 'http://sentry.example.com') fill_in('error-tracking-token', with: 'token') @@ -151,7 +156,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do end end - context 'integrated error tracking backend' do + context 'with integrated error tracking backend' do it 'successfully fills and submits the form' do visit project_settings_operations_path(project) @@ -175,11 +180,17 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do wait_for_requests assert_text('Your changes have been saved') + + within '.js-error-tracking-settings' do + click_button('Expand') + end + + expect(page).to have_content('Paste this DSN into your Sentry SDK') end end end - context 'grafana integration settings form' do + describe 'grafana integration settings form' do it 'successfully fills and completes the form' do visit project_settings_operations_path(project) diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb index 528fd58cbe6..8d73ffecd46 100644 --- a/spec/features/projects/settings/webhooks_settings_spec.rb +++ b/spec/features/projects/settings/webhooks_settings_spec.rb @@ -115,8 +115,8 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do hook_log visit edit_project_hook_path(project, hook) - expect(page).to have_content('Recent Deliveries') - expect(page).to have_content(hook_log.url) + expect(page).to have_content('Recent events') + expect(page).to have_link('View details', href: hook_log.present.details_path) end it 'show hook log details' do diff --git a/spec/features/projects/show/user_uploads_files_spec.rb b/spec/features/projects/show/user_uploads_files_spec.rb index eb230082bfa..51e41397439 100644 --- a/spec/features/projects/show/user_uploads_files_spec.rb +++ b/spec/features/projects/show/user_uploads_files_spec.rb @@ -21,13 +21,15 @@ RSpec.describe 'Projects > Show > User uploads files' do wait_for_requests end - include_examples 'it uploads and commits a new text file' + [true, false].each do |value| + include_examples 'it uploads and commits a new text file', drop: value - include_examples 'it uploads and commits a new image file' + include_examples 'it uploads and commits a new image file', drop: value - include_examples 'it uploads and commits a new pdf file' + include_examples 'it uploads and commits a new pdf file', drop: value - include_examples 'it uploads a file to a sub-directory' + include_examples 'it uploads a file to a sub-directory', drop: value + end end context 'when a user does not have write access' do @@ -37,7 +39,9 @@ RSpec.describe 'Projects > Show > User uploads files' do visit(project_path(project2)) end - include_examples 'it uploads and commits a new file to a forked project' + [true, false].each do |value| + include_examples 'it uploads and commits a new file to a forked project', drop: value + end end context 'when in the empty_repo_upload experiment' do @@ -50,13 +54,17 @@ RSpec.describe 'Projects > Show > User uploads files' do context 'with an empty repo' do let(:project) { create(:project, :empty_repo, creator: user) } - include_examples 'uploads and commits a new text file via "upload file" button' + [true, false].each do |value| + include_examples 'uploads and commits a new text file via "upload file" button', drop: value + end end context 'with a nonempty repo' do let(:project) { create(:project, :repository, creator: user) } - include_examples 'uploads and commits a new text file via "upload file" button' + [true, false].each do |value| + include_examples 'uploads and commits a new text file via "upload file" button', drop: value + end end end end diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb index 9f08759603e..5d482f9fbd0 100644 --- a/spec/features/projects/user_creates_project_spec.rb +++ b/spec/features/projects/user_creates_project_spec.rb @@ -33,6 +33,29 @@ RSpec.describe 'User creates a project', :js do expect(page).to have_content(project.url_to_repo) end + it 'creates a new project that is not blank' do + stub_experiments(new_project_sast_enabled: 'candidate') + + visit(new_project_path) + + find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + fill_in(:project_name, with: 'With initial commits') + + expect(page).to have_checked_field 'Initialize repository with a README' + expect(page).to have_checked_field 'Enable Static Application Security Testing (SAST)' + + page.within('#content-body') do + click_button('Create project') + end + + project = Project.last + + expect(current_path).to eq(project_path(project)) + expect(page).to have_content('With initial commits') + expect(page).to have_content('Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist') + expect(page).to have_content('README.md Initial commit') + end + context 'in a subgroup they do not own' do let(:parent) { create(:group) } let!(:subgroup) { create(:group, parent: parent) } |