diff options
Diffstat (limited to 'spec/features')
167 files changed, 2137 insertions, 2414 deletions
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb index f934736ced9..f1df5c2d6f0 100644 --- a/spec/features/abuse_report_spec.rb +++ b/spec/features/abuse_report_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do - let_it_be(:abusive_user) { create(:user) } + let_it_be(:abusive_user) { create(:user, :no_super_sidebar) } - let_it_be(:reporter1) { create(:user) } + let_it_be(:reporter1) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, :public, :repository) } let_it_be(:issue) { create(:issue, project: project, author: abusive_user) } @@ -57,7 +57,7 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do describe 'when user_profile_overflow_menu FF turned on' do context 'when reporting a user profile for abuse' do - let_it_be(:reporter2) { create(:user) } + let_it_be(:reporter2) { create(:user, :no_super_sidebar) } before do visit user_path(abusive_user) @@ -108,7 +108,7 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do describe 'when user_profile_overflow_menu FF turned off' do context 'when reporting a user profile for abuse' do - let_it_be(:reporter2) { create(:user) } + let_it_be(:reporter2) { create(:user, :no_super_sidebar) } before do stub_feature_flags(user_profile_overflow_menu_vue: false) diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb index 18bc851558d..973988560b3 100644 --- a/spec/features/admin/admin_abuse_reports_spec.rb +++ b/spec/features/admin/admin_abuse_reports_spec.rb @@ -11,291 +11,195 @@ RSpec.describe "Admin::AbuseReports", :js, feature_category: :insider_threat do let_it_be(:closed_report) { create(:abuse_report, :closed, user: user, category: 'spam') } describe 'as an admin' do + include FilteredSearchHelpers + before do sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) - end - - context 'when abuse_reports_list feature flag is enabled' do - include FilteredSearchHelpers - - before do - visit admin_abuse_reports_path - end - - let(:abuse_report_row_selector) { '[data-testid="abuse-report-row"]' } - - it 'only includes open reports by default' do - expect_displayed_reports_count(2) - - expect_report_shown(open_report, open_report2) - - within '[data-testid="abuse-reports-filtered-search-bar"]' do - expect(page).to have_content 'Status = Open' - end - end - - it 'can be filtered by status, user, reporter, and category', :aggregate_failures do - # filter by status - filter %w[Status Closed] - expect_displayed_reports_count(1) - expect_report_shown(closed_report) - expect_report_not_shown(open_report, open_report2) - - filter %w[Status Open] - expect_displayed_reports_count(2) - expect_report_shown(open_report, open_report2) - expect_report_not_shown(closed_report) - - # filter by user - filter(['User', open_report2.user.username]) - expect_displayed_reports_count(1) - expect_report_shown(open_report2) - expect_report_not_shown(open_report, closed_report) + visit admin_abuse_reports_path + end - # filter by reporter - filter(['Reporter', open_report.reporter.username]) + let(:abuse_report_row_selector) { '[data-testid="abuse-report-row"]' } - expect_displayed_reports_count(1) - expect_report_shown(open_report) - expect_report_not_shown(open_report2, closed_report) + it 'only includes open reports by default' do + expect_displayed_reports_count(2) - # filter by category - filter(['Category', open_report2.category]) + expect_report_shown(open_report, open_report2) - expect_displayed_reports_count(1) - expect_report_shown(open_report2) - expect_report_not_shown(open_report, closed_report) + within_testid('abuse-reports-filtered-search-bar') do + expect(page).to have_content 'Status = Open' end + end - it 'can be sorted by created_at and updated_at in desc and asc order', :aggregate_failures do - sort_by 'Created date' - # created_at desc - expect(report_rows[0].text).to include(report_text(open_report2)) - expect(report_rows[1].text).to include(report_text(open_report)) - - # created_at asc - toggle_sort_direction - - expect(report_rows[0].text).to include(report_text(open_report)) - expect(report_rows[1].text).to include(report_text(open_report2)) + it 'can be filtered by status, user, reporter, and category', :aggregate_failures do + # filter by status + filter %w[Status Closed] + expect_displayed_reports_count(1) + expect_report_shown(closed_report) + expect_report_not_shown(open_report, open_report2) - # updated_at asc - sort_by 'Updated date' + filter %w[Status Open] + expect_displayed_reports_count(2) + expect_report_shown(open_report, open_report2) + expect_report_not_shown(closed_report) - expect(report_rows[0].text).to include(report_text(open_report2)) - expect(report_rows[1].text).to include(report_text(open_report)) + # filter by user + filter(['User', open_report2.user.username]) - # updated_at desc - toggle_sort_direction + expect_displayed_reports_count(1) + expect_report_shown(open_report2) + expect_report_not_shown(open_report, closed_report) - expect(report_rows[0].text).to include(report_text(open_report)) - expect(report_rows[1].text).to include(report_text(open_report2)) - end + # filter by reporter + filter(['Reporter', open_report.reporter.username]) - context 'when multiple reports for the same user are created' do - let_it_be(:open_report3) { create(:abuse_report, category: 'spam', user: user) } - let_it_be(:closed_report2) { create(:abuse_report, :closed, user: user, category: 'spam') } + expect_displayed_reports_count(1) + expect_report_shown(open_report) + expect_report_not_shown(open_report2, closed_report) - it 'aggregates open reports by user & category', :aggregate_failures do - expect_displayed_reports_count(2) + # filter by category + filter(['Category', open_report2.category]) - expect_aggregated_report_shown(open_report, 2) - expect_report_shown(open_report2) - end + expect_displayed_reports_count(1) + expect_report_shown(open_report2) + expect_report_not_shown(open_report, closed_report) + end - it 'can sort aggregated reports by number_of_reports in desc order only', :aggregate_failures do - sort_by 'Number of Reports' + it 'can be sorted by created_at and updated_at in desc and asc order', :aggregate_failures do + sort_by 'Created date' + # created_at desc + expect(report_rows[0].text).to include(report_text(open_report2)) + expect(report_rows[1].text).to include(report_text(open_report)) - expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) - expect(report_rows[1].text).to include(report_text(open_report2)) + # created_at asc + toggle_sort_direction - toggle_sort_direction + expect(report_rows[0].text).to include(report_text(open_report)) + expect(report_rows[1].text).to include(report_text(open_report2)) - expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) - expect(report_rows[1].text).to include(report_text(open_report2)) - end + # updated_at asc + sort_by 'Updated date' - it 'can sort aggregated reports by created_at and updated_at in desc and asc order', :aggregate_failures do - # number_of_reports desc (default) - expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) - expect(report_rows[1].text).to include(report_text(open_report2)) + expect(report_rows[0].text).to include(report_text(open_report2)) + expect(report_rows[1].text).to include(report_text(open_report)) - # created_at desc - sort_by 'Created date' + # updated_at desc + toggle_sort_direction - expect(report_rows[0].text).to include(report_text(open_report2)) - expect(report_rows[1].text).to include(aggregated_report_text(open_report, 2)) - - # created_at asc - toggle_sort_direction + expect(report_rows[0].text).to include(report_text(open_report)) + expect(report_rows[1].text).to include(report_text(open_report2)) + end - expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) - expect(report_rows[1].text).to include(report_text(open_report2)) + context 'when multiple reports for the same user are created' do + let_it_be(:open_report3) { create(:abuse_report, category: 'spam', user: user) } + let_it_be(:closed_report2) { create(:abuse_report, :closed, user: user, category: 'spam') } - sort_by 'Updated date' + it 'aggregates open reports by user & category', :aggregate_failures do + expect_displayed_reports_count(2) - # updated_at asc - expect(report_rows[0].text).to include(report_text(open_report2)) - expect(report_rows[1].text).to include(aggregated_report_text(open_report, 2)) + expect_aggregated_report_shown(open_report, 2) + expect_report_shown(open_report2) + end - # updated_at desc - toggle_sort_direction + it 'can sort aggregated reports by number_of_reports in desc order only', :aggregate_failures do + sort_by 'Number of Reports' - expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) - expect(report_rows[1].text).to include(report_text(open_report2)) - end + expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) + expect(report_rows[1].text).to include(report_text(open_report2)) - it 'does not aggregate closed reports', :aggregate_failures do - filter %w[Status Closed] + toggle_sort_direction - expect_displayed_reports_count(2) - expect_report_shown(closed_report, closed_report2) - end + expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) + expect(report_rows[1].text).to include(report_text(open_report2)) end - def report_rows - page.all(abuse_report_row_selector) - end + it 'can sort aggregated reports by created_at and updated_at in desc and asc order', :aggregate_failures do + # number_of_reports desc (default) + expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) + expect(report_rows[1].text).to include(report_text(open_report2)) - def report_text(report) - "#{report.user.name} reported for #{report.category} by #{report.reporter.name}" - end + # created_at desc + sort_by 'Created date' - def aggregated_report_text(report, count) - "#{report.user.name} reported for #{report.category} by #{count} users" - end + expect(report_rows[0].text).to include(report_text(open_report2)) + expect(report_rows[1].text).to include(aggregated_report_text(open_report, 2)) - def expect_report_shown(*reports) - reports.each do |r| - expect(page).to have_content(report_text(r)) - end - end + # created_at asc + toggle_sort_direction - def expect_report_not_shown(*reports) - reports.each do |r| - expect(page).not_to have_content(report_text(r)) - end - end + expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) + expect(report_rows[1].text).to include(report_text(open_report2)) - def expect_aggregated_report_shown(*reports, count) - reports.each do |r| - expect(page).to have_content(aggregated_report_text(r, count)) - end - end + sort_by 'Updated date' - def expect_displayed_reports_count(count) - expect(page).to have_css(abuse_report_row_selector, count: count) - end + # updated_at asc + expect(report_rows[0].text).to include(report_text(open_report2)) + expect(report_rows[1].text).to include(aggregated_report_text(open_report, 2)) - def filter(tokens) - # remove all existing filters first - page.find_all('.gl-token-close').each(&:click) + # updated_at desc + toggle_sort_direction - select_tokens(*tokens, submit: true, input_text: 'Filter reports') + expect(report_rows[0].text).to include(aggregated_report_text(open_report, 2)) + expect(report_rows[1].text).to include(report_text(open_report2)) end - def sort_by(sort) - page.within('.vue-filtered-search-bar-container .sort-dropdown-container') do - page.find('.gl-dropdown-toggle').click + it 'does not aggregate closed reports', :aggregate_failures do + filter %w[Status Closed] - page.within('.dropdown-menu') do - click_button sort - wait_for_requests - end - end + expect_displayed_reports_count(2) + expect_report_shown(closed_report, closed_report2) end end - context 'when abuse_reports_list feature flag is disabled' do - before do - stub_feature_flags(abuse_reports_list: false) - - visit admin_abuse_reports_path - end + def report_rows + page.all(abuse_report_row_selector) + end - it 'displays all abuse reports', :aggregate_failures do - expect_report_shown(open_report) - expect_report_actions_shown(open_report) + def report_text(report) + "#{report.user.name} reported for #{report.category} by #{report.reporter.name}" + end - expect_report_shown(open_report2) - expect_report_actions_shown(open_report2) + def aggregated_report_text(report, count) + "#{report.user.name} reported for #{report.category} by #{count} users" + end - expect_report_shown(closed_report) - expect_report_actions_shown(closed_report) + def expect_report_shown(*reports) + reports.each do |r| + expect(page).to have_content(report_text(r)) end + end - context 'when an admin has been reported for abuse' do - let_it_be(:admin_abuse_report) { create(:abuse_report, user: admin) } - - it 'displays the abuse report without actions' do - expect_report_shown(admin_abuse_report) - expect_report_actions_not_shown(admin_abuse_report) - end + def expect_report_not_shown(*reports) + reports.each do |r| + expect(page).not_to have_content(report_text(r)) end + end - context 'when multiple users have been reported for abuse' do - let(:report_count) { AbuseReport.default_per_page + 3 } - - before do - report_count.times do - create(:abuse_report, user: create(:user)) - end - end - - context 'in the abuse report view', :aggregate_failures do - it 'adds pagination' do - visit admin_abuse_reports_path - - expect(page).to have_selector('.pagination') - expect(page).to have_selector('.pagination .js-pagination-page', count: (report_count.to_f / AbuseReport.default_per_page).ceil) - end - end + def expect_aggregated_report_shown(*reports, count) + reports.each do |r| + expect(page).to have_content(aggregated_report_text(r, count)) end + end - context 'when filtering reports' do - it 'can be filtered by reported-user', :aggregate_failures do - visit admin_abuse_reports_path - - page.within '.filter-form' do - click_button 'User' - wait_for_requests - - page.within '.dropdown-menu-user' do - click_link user.name - end - - wait_for_requests - end + def expect_displayed_reports_count(count) + expect(page).to have_css(abuse_report_row_selector, count: count) + end - expect_report_shown(open_report) - expect_report_shown(closed_report) - end - end + def filter(tokens) + # remove all existing filters first + page.find_all('.gl-token-close').each(&:click) - def expect_report_shown(report) - page.within(:table_row, { "User" => report.user.name, "Reported by" => report.reporter.name }) do - expect(page).to have_content(report.user.name) - expect(page).to have_content(report.reporter.name) - expect(page).to have_content(report.message) - expect(page).to have_link(report.user.name, href: user_path(report.user)) - end - end + select_tokens(*tokens, submit: true, input_text: 'Filter reports') + end - def expect_report_actions_shown(report) - page.within(:table_row, { "User" => report.user.name, "Reported by" => report.reporter.name }) do - expect(page).to have_link('Remove user & report') - expect(page).to have_link('Block user') - expect(page).to have_link('Remove user') - end - end + def sort_by(sort) + page.within('.vue-filtered-search-bar-container .sort-dropdown-container') do + page.find('.gl-dropdown-toggle').click - def expect_report_actions_not_shown(report) - page.within(:table_row, { "User" => report.user.name, "Reported by" => report.reporter.name }) do - expect(page).not_to have_link('Remove user & report') - expect(page).not_to have_link('Block user') - expect(page).not_to have_link('Remove user') + page.within('.dropdown-menu') do + click_button sort + wait_for_requests end end end diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index b4f64cbfa7b..a5acba1fe4a 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Admin::Hooks', feature_category: :webhooks do include Spec::Support::Helpers::ModalHelpers - let_it_be(:user) { create(:admin) } + let_it_be(:user) { create(:admin, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/admin/admin_jobs_spec.rb b/spec/features/admin/admin_jobs_spec.rb index d46b314c144..b305bec6493 100644 --- a/spec/features/admin/admin_jobs_spec.rb +++ b/spec/features/admin/admin_jobs_spec.rb @@ -2,9 +2,8 @@ require 'spec_helper' -RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do +RSpec.describe 'Admin Jobs', :js, feature_category: :continuous_integration do before do - stub_feature_flags(admin_jobs_vue: false) admin = create(:admin) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) @@ -23,12 +22,13 @@ RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do visit admin_jobs_path - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'All') - expect(page).to have_selector('.row-content-block', text: 'All jobs') - expect(page.all('.build-link').size).to eq(4) - expect(page).to have_button 'Stop all jobs' + wait_for_requests - click_button 'Stop all jobs' + expect(page).to have_selector('[data-testid="jobs-all-tab"]') + expect(page.all('[data-testid="jobs-table-row"]').size).to eq(4) + expect(page).to have_button 'Cancel all jobs' + + click_button 'Cancel all jobs' expect(page).to have_button 'Yes, proceed' expect(page).to have_content 'Are you sure?' end @@ -38,73 +38,11 @@ RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do it 'shows a message' do visit admin_jobs_path - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'All') - expect(page).to have_content 'No jobs to show' - expect(page).not_to have_button 'Stop all jobs' - end - end - end - - context 'Pending tab' do - context 'when have pending jobs' do - it 'shows pending jobs' do - build1 = create(:ci_build, pipeline: pipeline, status: :pending) - build2 = create(:ci_build, pipeline: pipeline, status: :running) - build3 = create(:ci_build, pipeline: pipeline, status: :success) - build4 = create(:ci_build, pipeline: pipeline, status: :failed) - - visit admin_jobs_path(scope: :pending) - - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Pending') - expect(page.find('.build-link')).to have_content(build1.id) - expect(page.find('.build-link')).not_to have_content(build2.id) - expect(page.find('.build-link')).not_to have_content(build3.id) - expect(page.find('.build-link')).not_to have_content(build4.id) - expect(page).to have_button 'Stop all jobs' - end - end - - context 'when have no jobs pending' do - it 'shows a message' do - create(:ci_build, pipeline: pipeline, status: :success) - - visit admin_jobs_path(scope: :pending) - - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Pending') - expect(page).to have_content 'No jobs to show' - expect(page).not_to have_button 'Stop all jobs' - end - end - end - - context 'Running tab' do - context 'when have running jobs' do - it 'shows running jobs' do - build1 = create(:ci_build, pipeline: pipeline, status: :running) - build2 = create(:ci_build, pipeline: pipeline, status: :success) - build3 = create(:ci_build, pipeline: pipeline, status: :failed) - build4 = create(:ci_build, pipeline: pipeline, status: :pending) - - visit admin_jobs_path(scope: :running) - - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Running') - expect(page.find('.build-link')).to have_content(build1.id) - expect(page.find('.build-link')).not_to have_content(build2.id) - expect(page.find('.build-link')).not_to have_content(build3.id) - expect(page.find('.build-link')).not_to have_content(build4.id) - expect(page).to have_button 'Stop all jobs' - end - end - - context 'when have no jobs running' do - it 'shows a message' do - create(:ci_build, pipeline: pipeline, status: :success) - - visit admin_jobs_path(scope: :running) + wait_for_requests - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Running') - expect(page).to have_content 'No jobs to show' - expect(page).not_to have_button 'Stop all jobs' + expect(page).to have_selector('[data-testid="jobs-all-tab"]') + expect(page).to have_selector('[data-testid="jobs-empty-state"]') + expect(page).not_to have_button 'Cancel all jobs' end end end @@ -116,13 +54,19 @@ RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do build2 = create(:ci_build, pipeline: pipeline, status: :running) build3 = create(:ci_build, pipeline: pipeline, status: :success) - visit admin_jobs_path(scope: :finished) + visit admin_jobs_path + + wait_for_requests + + find_by_testid('jobs-finished-tab').click + + wait_for_requests - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Finished') - expect(page.find('.build-link')).not_to have_content(build1.id) - expect(page.find('.build-link')).not_to have_content(build2.id) - expect(page.find('.build-link')).to have_content(build3.id) - expect(page).to have_button 'Stop all jobs' + expect(page).to have_selector('[data-testid="jobs-finished-tab"]') + expect(find_by_testid('job-id-link')).not_to have_content(build1.id) + expect(find_by_testid('job-id-link')).not_to have_content(build2.id) + expect(find_by_testid('job-id-link')).to have_content(build3.id) + expect(page).to have_button 'Cancel all jobs' end end @@ -130,11 +74,17 @@ RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do it 'shows a message' do create(:ci_build, pipeline: pipeline, status: :running) - visit admin_jobs_path(scope: :finished) + visit admin_jobs_path + + wait_for_requests + + find_by_testid('jobs-finished-tab').click + + wait_for_requests - expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Finished') + expect(page).to have_selector('[data-testid="jobs-finished-tab"]') expect(page).to have_content 'No jobs to show' - expect(page).to have_button 'Stop all jobs' + expect(page).to have_button 'Cancel all jobs' end end end diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb index a64d3f241f6..5d9106fea02 100644 --- a/spec/features/admin/admin_mode/logout_spec.rb +++ b/spec/features/admin/admin_mode/logout_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Admin Mode Logout', :js, feature_category: :system_access do include UserLoginHelper include Features::TopNavSpecHelpers - let(:user) { create(:admin) } + let(:user) { create(:admin, :no_super_sidebar) } before do # TODO: This used to use gitlab_sign_in, instead of sign_in, but that is buggy. See diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb index 124c43eef9d..2a862c750d7 100644 --- a/spec/features/admin/admin_mode/workers_spec.rb +++ b/spec/features/admin/admin_mode/workers_spec.rb @@ -6,8 +6,8 @@ require 'spec_helper' RSpec.describe 'Admin mode for workers', :request_store, feature_category: :system_access do include Features::AdminUsersHelpers - let(:user) { create(:user) } - let(:user_to_delete) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } + let(:user_to_delete) { create(:user, :no_super_sidebar) } before do sign_in(user) @@ -22,7 +22,7 @@ RSpec.describe 'Admin mode for workers', :request_store, feature_category: :syst end context 'as an admin user' do - let(:user) { create(:admin) } + let(:user) { create(:admin, :no_super_sidebar) } context 'when admin mode disabled' do it 'cannot delete user', :js do diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb index 65249fa0235..edfa58567ad 100644 --- a/spec/features/admin/admin_mode_spec.rb +++ b/spec/features/admin/admin_mode_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Admin mode', :js, feature_category: :shared do include Features::TopNavSpecHelpers include StubENV - let(:admin) { create(:admin) } + let(:admin) { create(:admin, :no_super_sidebar) } before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index af6ba318ac6..e0f4473c80c 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -54,6 +54,11 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do let(:runner) { instance_runner } end + it_behaves_like 'shows runner details from list' do + let(:runner) { instance_runner } + let(:runner_page_path) { admin_runner_path(instance_runner) } + end + it_behaves_like 'pauses, resumes and deletes a runner' do let(:runner) { instance_runner } end @@ -575,6 +580,8 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do let(:runner_page_path) { admin_runner_path(project_runner) } end + it_behaves_like 'shows locked field' + describe 'breadcrumbs' do it 'contains the current runner id and token' do page.within '[data-testid="breadcrumb-links"]' do diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb index 7d4d3deb6d8..7423e74bf3a 100644 --- a/spec/features/admin/admin_sees_background_migrations_spec.rb +++ b/spec/features/admin/admin_sees_background_migrations_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe "Admin > Admin sees background migrations", feature_category: :database do include ListboxHelpers - let_it_be(:admin) { create(:admin) } + let_it_be(:admin) { create(:admin, :no_super_sidebar) } let(:job_class) { Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob } let_it_be(:active_migration) { create(:batched_background_migration, :active, table_name: 'active') } diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index b78d6777a1a..e87f47e5234 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do include TermsHelper include UsageDataHelpers - let_it_be(:admin) { create(:admin) } + let_it_be(:admin) { create(:admin, :no_super_sidebar) } context 'application setting :admin_mode is enabled', :request_store do before do @@ -53,7 +53,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do it 'modify import sources' do expect(current_settings.import_sources).to be_empty - page.within('[data-testid="admin-visibility-access-settings"]') do + page.within('[data-testid="admin-import-export-settings"]') do check "Repository by URL" click_button 'Save changes' end @@ -63,7 +63,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do end it 'change Visibility and Access Controls' do - page.within('[data-testid="admin-visibility-access-settings"]') do + page.within('[data-testid="admin-import-export-settings"]') do page.within('[data-testid="project-export"]') do uncheck 'Enabled' end @@ -113,7 +113,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do end it 'change Maximum export size' do - page.within(find('[data-testid="account-limit"]')) do + page.within(find('[data-testid="admin-import-export-settings"]')) do fill_in 'Maximum export size (MiB)', with: 25 click_button 'Save changes' end @@ -123,7 +123,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do end it 'change Maximum import size' do - page.within(find('[data-testid="account-limit"]')) do + page.within(find('[data-testid="admin-import-export-settings"]')) do fill_in 'Maximum import size (MiB)', with: 15 click_button 'Save changes' end diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index a95fd133133..7dc329e6909 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do include Features::AdminUsersHelpers include Spec::Support::Helpers::ModalHelpers - let_it_be(:user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } - let_it_be(:current_user) { create(:admin) } + let_it_be(:user) { create(:omniauth_user, :no_super_sidebar, provider: 'twitter', extern_uid: '123456') } + let_it_be(:current_user) { create(:admin, :no_super_sidebar) } before do sign_in(current_user) @@ -145,7 +145,7 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do end describe 'Impersonation' do - let_it_be(:another_user) { create(:user) } + let_it_be(:another_user) { create(:user, :no_super_sidebar) } context 'before impersonating' do subject { visit admin_user_path(user_to_visit) } @@ -156,7 +156,7 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do it 'disables impersonate button' do subject - impersonate_btn = find('[data-testid="impersonate_user_link"]') + impersonate_btn = find('[data-testid="impersonate-user-link"]') expect(impersonate_btn).not_to be_nil expect(impersonate_btn['disabled']).not_to be_nil @@ -174,7 +174,7 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do subject expect(page).to have_content('Impersonate') - impersonate_btn = find('[data-testid="impersonate_user_link"]') + impersonate_btn = find('[data-testid="impersonate-user-link"]') expect(impersonate_btn['disabled']).to be_nil end end diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 8e80ce5edd9..8ee30c50a7d 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -350,7 +350,8 @@ RSpec.describe 'Admin::Users', feature_category: :user_management do let_it_be(:ghost_user) { create(:user, :ghost) } it 'does not render actions dropdown' do - expect(page).not_to have_css("[data-testid='user-actions-#{ghost_user.id}'] [data-testid='dropdown-toggle']") + expect(page).not_to have_css( + "[data-testid='user-actions-#{ghost_user.id}'] [data-testid='user-actions-dropdown-toggle']") end end @@ -358,7 +359,8 @@ RSpec.describe 'Admin::Users', feature_category: :user_management do let_it_be(:bot_user) { create(:user, user_type: :alert_bot) } it 'does not render actions dropdown' do - expect(page).not_to have_css("[data-testid='user-actions-#{bot_user.id}'] [data-testid='dropdown-toggle']") + expect(page).not_to have_css( + "[data-testid='user-actions-#{bot_user.id}'] [data-testid='user-actions-dropdown-toggle']") end end end diff --git a/spec/features/alert_management/alert_details_spec.rb b/spec/features/alert_management/alert_details_spec.rb index 45fa4d810aa..b377d3a092b 100644 --- a/spec/features/alert_management/alert_details_spec.rb +++ b/spec/features/alert_management/alert_details_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Alert details', :js, feature_category: :incident_management do let_it_be(:project) { create(:project) } - let_it_be(:developer) { create(:user) } + let_it_be(:developer) { create(:user, :no_super_sidebar) } let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered', title: 'Alert') } before_all do diff --git a/spec/features/alert_management/alert_management_list_spec.rb b/spec/features/alert_management/alert_management_list_spec.rb index 6ed3bdec5f5..cc54af249e1 100644 --- a/spec/features/alert_management/alert_management_list_spec.rb +++ b/spec/features/alert_management/alert_management_list_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Alert Management index', :js, feature_category: :incident_management do let_it_be(:project) { create(:project) } - let_it_be(:developer) { create(:user) } + let_it_be(:developer) { create(:user, :no_super_sidebar) } before_all do project.add_developer(developer) diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb index 006b7ce45d4..1ee02de9a66 100644 --- a/spec/features/boards/board_filters_spec.rb +++ b/spec/features/boards/board_filters_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' RSpec.describe 'Issue board filters', :js, feature_category: :team_planning do - let_it_be(:project) { create(:project, :repository) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, :repository, group: group) } let_it_be(:user) { create(:user) } - let_it_be(:board) { create(:board, project: project) } let_it_be(:project_label) { create(:label, project: project, title: 'Label') } let_it_be(:milestone_1) { create(:milestone, project: project, due_date: 3.days.from_now) } let_it_be(:milestone_2) { create(:milestone, project: project, due_date: Date.tomorrow) } @@ -21,166 +21,195 @@ RSpec.describe 'Issue board filters', :js, feature_category: :team_planning do let(:filter_first_suggestion) { find('.gl-filtered-search-suggestion-list').first('.gl-filtered-search-suggestion') } let(:filter_submit) { find('.gl-search-box-by-click-search-button') } - before do - stub_feature_flags(apollo_boards: false) - project.add_maintainer(user) - sign_in(user) + context 'for a project board' do + let_it_be(:board) { create(:board, project: project) } - visit_project_board - end - - shared_examples 'loads all the users when opened' do - it 'and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + before do + stub_feature_flags(apollo_boards: false) + project.add_maintainer(user) + sign_in(user) + visit project_board_path(project, board) wait_for_requests + end - expect_filtered_search_dropdown_results(filter_dropdown, 4) + shared_examples 'loads all the users when opened' do + it 'and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) - click_on user.username - filter_submit.click + wait_for_requests - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) - expect(find('.board-card')).to have_content(issue.title) - end - end + expect_filtered_search_dropdown_results(filter_dropdown, 3) - describe 'filters by assignee' do - before do - set_filter('assignee') - end + click_on user.username + filter_submit.click - it_behaves_like 'loads all the users when opened', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/351426' do - let(:issue) { issue_2 } + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board-card')).to have_content(issue.title) + end end - end - describe 'filters by author' do - before do - set_filter('author') - end + describe 'filters by assignee' do + before do + set_filter('assignee') + end - it_behaves_like 'loads all the users when opened' do - let(:issue) { issue_1 } + it_behaves_like 'loads all the users when opened', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/351426' do + let(:issue) { issue_2 } + end end - end - describe 'filters by label' do - before do - set_filter('label') + describe 'filters by author' do + before do + set_filter('author') + end + + it_behaves_like 'loads all the users when opened' do + let(:issue) { issue_1 } + end end - it 'loads all the labels when opened and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + describe 'filters by label' do + before do + set_filter('label') + end - expect_filtered_search_dropdown_results(filter_dropdown, 3) + it 'loads all the labels when opened and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) - filter_dropdown.click_on project_label.title - filter_submit.click + expect_filtered_search_dropdown_results(filter_dropdown, 3) - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) - expect(find('.board-card')).to have_content(issue_2.title) - end - end + filter_dropdown.click_on project_label.title + filter_submit.click - describe 'filters by releases' do - before do - set_filter('release') + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board-card')).to have_content(issue_2.title) + end end - it 'loads all the releases when opened and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + describe 'filters by releases' do + before do + set_filter('release') + end - expect_filtered_search_dropdown_results(filter_dropdown, 2) + it 'loads all the releases when opened and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) - click_on release.tag - filter_submit.click + expect_filtered_search_dropdown_results(filter_dropdown, 2) - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) - expect(find('.board-card')).to have_content(issue_1.title) - end - end + click_on release.tag + filter_submit.click - describe 'filters by confidentiality' do - before do - filter_input.click - filter_input.set("confidential:") + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board-card')).to have_content(issue_1.title) + end end - it 'loads all the confidentiality options when opened and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + describe 'filters by confidentiality' do + before do + filter_input.click + filter_input.set("confidential:") + end - expect_filtered_search_dropdown_results(filter_dropdown, 2) + it 'loads all the confidentiality options when opened and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) - filter_dropdown.click_on 'Yes' - filter_submit.click + expect_filtered_search_dropdown_results(filter_dropdown, 2) - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) - expect(find('.board-card')).to have_content(issue_2.title) - end - end + filter_dropdown.click_on 'Yes' + filter_submit.click - describe 'filters by milestone' do - before do - set_filter('milestone') + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board-card')).to have_content(issue_2.title) + end end - it 'loads all the milestones when opened and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + describe 'filters by milestone' do + before do + set_filter('milestone') + end + + it 'loads all the milestones when opened and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) - expect_filtered_search_dropdown_results(filter_dropdown, 6) - expect(filter_dropdown).to have_content('None') - expect(filter_dropdown).to have_content('Any') - expect(filter_dropdown).to have_content('Started') - expect(filter_dropdown).to have_content('Upcoming') + expect_filtered_search_dropdown_results(filter_dropdown, 6) + expect(filter_dropdown).to have_content('None') + expect(filter_dropdown).to have_content('Any') + expect(filter_dropdown).to have_content('Started') + expect(filter_dropdown).to have_content('Upcoming') - dropdown_nodes = page.find_all('.gl-filtered-search-suggestion-list > .gl-filtered-search-suggestion') + dropdown_nodes = page.find_all('.gl-filtered-search-suggestion-list > .gl-filtered-search-suggestion') - expect(dropdown_nodes[4]).to have_content(milestone_2.title) - expect(dropdown_nodes.last).to have_content(milestone_1.title) + expect(dropdown_nodes[4]).to have_content(milestone_2.title) + expect(dropdown_nodes.last).to have_content(milestone_1.title) - click_on milestone_1.title - filter_submit.click + click_on milestone_1.title + filter_submit.click - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + end end - end - describe 'filters by reaction emoji' do - before do - set_filter('my-reaction') + describe 'filters by reaction emoji' do + before do + set_filter('my-reaction') + end + + it 'loads all the emojis when opened and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + + expect_filtered_search_dropdown_results(filter_dropdown, 3) + + click_on 'thumbsup' + filter_submit.click + + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board-card')).to have_content(issue_1.title) + end end - it 'loads all the emojis when opened and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 2) + describe 'filters by type' do + let_it_be(:incident) { create(:incident, project: project) } + + before do + set_filter('type') + end - expect_filtered_search_dropdown_results(filter_dropdown, 3) + it 'loads all the types when opened and submit one as filter', :aggregate_failures do + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 3) - click_on 'thumbsup' - filter_submit.click + expect_filtered_search_dropdown_results(filter_dropdown, 2) - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) - expect(find('.board-card')).to have_content(issue_1.title) + click_on 'Incident' + filter_submit.click + + expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) + expect(find('.board-card')).to have_content(incident.title) + end end end - describe 'filters by type' do - let_it_be(:incident) { create(:incident, project: project) } + context 'for a group board' do + let_it_be(:board) { create(:board, group: group) } + + let_it_be(:child_project_member) { create(:user).tap { |u| project.add_maintainer(u) } } before do - set_filter('type') - end + stub_feature_flags(apollo_boards: false) - it 'loads all the types when opened and submit one as filter', :aggregate_failures do - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 3) + group.add_maintainer(user) + sign_in(user) + end - expect_filtered_search_dropdown_results(filter_dropdown, 2) + context 'when filtering by assignee' do + it 'includes descendant project members in autocomplete' do + visit group_board_path(group, board) + wait_for_requests - click_on 'Incident' - filter_submit.click + set_filter('assignee') - expect(find('.board:nth-child(1)')).to have_selector('.board-card', count: 1) - expect(find('.board-card')).to have_content(incident.title) + expect(page).to have_css('.gl-filtered-search-suggestion', text: child_project_member.name) + end end end @@ -193,9 +222,4 @@ RSpec.describe 'Issue board filters', :js, feature_category: :team_planning do def expect_filtered_search_dropdown_results(filter_dropdown, count) expect(filter_dropdown).to have_selector('.gl-dropdown-item', count: count) end - - def visit_project_board - visit project_board_path(project, board) - wait_for_requests - end end diff --git a/spec/features/boards/multiple_boards_spec.rb b/spec/features/boards/multiple_boards_spec.rb index e9d34c6f87f..9d59d3dd02a 100644 --- a/spec/features/boards/multiple_boards_spec.rb +++ b/spec/features/boards/multiple_boards_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Multiple Issue Boards', :js, feature_category: :team_planning do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, :public) } let_it_be(:planning) { create(:label, project: project, name: 'Planning') } let_it_be(:board) { create(:board, name: 'board1', project: project) } diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 4807b691e4f..358da1e1279 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Project issue boards sidebar', :js, feature_category: :team_planning, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/416414' do +RSpec.describe 'Project issue boards sidebar', :js, feature_category: :team_planning do include BoardHelpers let_it_be(:user) { create(:user) } diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 8ad27b65f11..e22ae4f51fb 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Contributions Calendar', :js, feature_category: :user_profile do include MobileHelpers - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:contributed_project) { create(:project, :public, :repository) } let(:issue_note) { create(:note, project: contributed_project) } diff --git a/spec/features/contextual_sidebar_spec.rb b/spec/features/contextual_sidebar_spec.rb index 132c8eb7192..ab322f18240 100644 --- a/spec/features/contextual_sidebar_spec.rb +++ b/spec/features/contextual_sidebar_spec.rb @@ -4,9 +4,8 @@ require 'spec_helper' RSpec.describe 'Contextual sidebar', :js, feature_category: :remote_development do context 'when context is a project' do - let_it_be(:project) { create(:project) } - - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, namespace: user.namespace) } before do sign_in(user) diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 56272f58e0d..4fe05abd73b 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -60,8 +60,8 @@ RSpec.describe 'Value Stream Analytics', :js, feature_category: :value_stream_ma # NOTE: in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68595 travel back # 5 days in time before we create data for these specs, to mitigate some flakiness # So setting the date range to be the last 2 days should skip past the existing data - from = 2.days.ago.strftime("%Y-%m-%d") - to = 1.day.ago.strftime("%Y-%m-%d") + from = 2.days.ago.to_date.iso8601 + to = 1.day.ago.to_date.iso8601 max_items_per_page = 20 around do |example| diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index 60621f57bde..61631d28aa9 100644 --- a/spec/features/dashboard/activity_spec.rb +++ b/spec/features/dashboard/activity_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Dashboard > Activity', feature_category: :user_profile do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb b/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb index c1849cbee83..a00666c2376 100644 --- a/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb +++ b/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'The group dashboard', :js, feature_category: :groups_and_project include ExternalAuthorizationServiceHelpers include Features::TopNavSpecHelpers - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in user diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb index b077b554773..e1da163cdf5 100644 --- a/spec/features/dashboard/groups_list_spec.rb +++ b/spec/features/dashboard/groups_list_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Dashboard Groups page', :js, feature_category: :groups_and_projects do - let(:user) { create :user } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } let(:nested_group) { create(:group, :nested) } let(:another_group) { create(:group) } @@ -237,4 +237,15 @@ RSpec.describe 'Dashboard Groups page', :js, feature_category: :groups_and_proje expect(page).to have_link("Explore groups", href: explore_groups_path) end + + context 'when there are no groups to display' do + before do + sign_in(user) + visit dashboard_groups_path + end + + it 'shows empty state' do + expect(page).to have_content(s_('GroupsEmptyState|A group is a collection of several projects')) + end + end end diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb index 5e6ec007569..501405c5662 100644 --- a/spec/features/dashboard/issuables_counter_spec.rb +++ b/spec/features/dashboard/issuables_counter_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching, feature_category: :team_planning do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, namespace: user.namespace) } let(:issue) { create(:issue, project: project) } let(:merge_request) { create(:merge_request, source_project: project) } diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 70d9f7e5137..69b32113bba 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Dashboard Issues', feature_category: :team_planning do include FilteredSearchHelpers - let_it_be(:current_user) { create :user } + let_it_be(:current_user) { create(:user, :no_super_sidebar) } let_it_be(:user) { current_user } # Shared examples depend on this being available let_it_be(:public_project) { create(:project, :public) } let_it_be(:project) { create(:project) } diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb index 624f3530f81..4bb04f4ff80 100644 --- a/spec/features/dashboard/merge_requests_spec.rb +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Merge Requests', feature_category: :code_review_workfl include FilteredSearchHelpers include ProjectForksHelper - let(:current_user) { create :user } + let(:current_user) { create(:user, :no_super_sidebar) } let(:user) { current_user } let(:project) { create(:project) } diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb index 0dd25ffaa94..38637115246 100644 --- a/spec/features/dashboard/milestones_spec.rb +++ b/spec/features/dashboard/milestones_spec.rb @@ -14,7 +14,7 @@ RSpec.describe 'Dashboard > Milestones', feature_category: :team_planning do end describe 'as logged-in user' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } let(:project) { create(:project, namespace: user.namespace) } let!(:milestone) { create(:milestone, project: project) } @@ -50,7 +50,7 @@ RSpec.describe 'Dashboard > Milestones', feature_category: :team_planning do end describe 'with merge requests disabled' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } let(:project) { create(:project, :merge_requests_disabled, namespace: user.namespace) } let!(:milestone) { create(:milestone, project: project) } diff --git a/spec/features/dashboard/navbar_spec.rb b/spec/features/dashboard/navbar_spec.rb index ff0ff899fc2..30e7f2d2e4e 100644 --- a/spec/features/dashboard/navbar_spec.rb +++ b/spec/features/dashboard/navbar_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe '"Your work" navbar', feature_category: :navigation do include_context 'dashboard navbar structure' - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } it_behaves_like 'verified navigation bar' do before do diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 747d09f5d08..e5ad9808f83 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Dashboard Projects', feature_category: :groups_and_projects do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project, reload: true) { create(:project, :repository, creator: build(:user)) } # ensure creator != owner to avoid N+1 false-positive let_it_be(:project2) { create(:project, :public) } diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb index 2e01c1304de..c8013d364e3 100644 --- a/spec/features/dashboard/shortcuts_spec.rb +++ b/spec/features/dashboard/shortcuts_spec.rb @@ -50,13 +50,13 @@ RSpec.describe 'Dashboard shortcuts', :js, feature_category: :shared do context 'logged out' do before do + stub_feature_flags(super_sidebar_logged_out: false) visit explore_root_path end it 'navigate to tabs' do find('body').send_keys([:shift, 'G']) - find('.nothing-here-block') expect(page).to have_content('No public groups') find('body').send_keys([:shift, 'S']) diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb index da985c6dc07..f9284f9479e 100644 --- a/spec/features/dashboard/snippets_spec.rb +++ b/spec/features/dashboard/snippets_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Dashboard snippets', feature_category: :source_code_management do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } it_behaves_like 'a "Your work" page with sidebar and breadcrumbs', :dashboard_snippets_path, :snippets diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb index 9d59126df8d..5642d083673 100644 --- a/spec/features/dashboard/todos/todos_spec.rb +++ b/spec/features/dashboard/todos/todos_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe 'Dashboard Todos', feature_category: :team_planning do include DesignManagementTestHelpers - let_it_be(:user) { create(:user, username: 'john') } - let_it_be(:user2) { create(:user, username: 'diane') } - let_it_be(:author) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar, username: 'john') } + let_it_be(:user2) { create(:user, :no_super_sidebar, username: 'diane') } + let_it_be(:author) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, :public) } let_it_be(:issue) { create(:issue, project: project, due_date: Date.today, title: "Fix bug") } diff --git a/spec/features/explore/groups_list_spec.rb b/spec/features/explore/groups_list_spec.rb index 39cd3c80307..91ee6d48a48 100644 --- a/spec/features/explore/groups_list_spec.rb +++ b/spec/features/explore/groups_list_spec.rb @@ -4,88 +4,104 @@ require 'spec_helper' RSpec.describe 'Explore Groups page', :js, feature_category: :groups_and_projects do let!(:user) { create :user } - let!(:group) { create(:group) } - let!(:public_group) { create(:group, :public) } - let!(:private_group) { create(:group, :private) } - let!(:empty_project) { create(:project, group: public_group) } - before do - group.add_owner(user) + context 'when there are groups to show' do + let!(:group) { create(:group) } + let!(:public_group) { create(:group, :public) } + let!(:private_group) { create(:group, :private) } + let!(:empty_project) { create(:project, group: public_group) } - sign_in(user) + before do + group.add_owner(user) - visit explore_groups_path - wait_for_requests - end + sign_in(user) - it 'shows groups user is member of' do - expect(page).to have_content(group.full_name) - expect(page).to have_content(public_group.full_name) - expect(page).not_to have_content(private_group.full_name) - end + visit explore_groups_path + wait_for_requests + end - it 'filters groups' do - fill_in 'filter', with: group.name - wait_for_requests + it 'shows groups user is member of' do + expect(page).to have_content(group.full_name) + expect(page).to have_content(public_group.full_name) + expect(page).not_to have_content(private_group.full_name) + end - expect(page).to have_content(group.full_name) - expect(page).not_to have_content(public_group.full_name) - expect(page).not_to have_content(private_group.full_name) - end + it 'filters groups' do + fill_in 'filter', with: group.name + wait_for_requests - it 'resets search when user cleans the input' do - fill_in 'filter', with: group.name - wait_for_requests + expect(page).to have_content(group.full_name) + expect(page).not_to have_content(public_group.full_name) + expect(page).not_to have_content(private_group.full_name) + end - expect(page).to have_content(group.full_name) - expect(page).not_to have_content(public_group.full_name) + it 'resets search when user cleans the input' do + fill_in 'filter', with: group.name + wait_for_requests - fill_in 'filter', with: "" - page.find('[name="filter"]').send_keys(:enter) - wait_for_requests + expect(page).to have_content(group.full_name) + expect(page).not_to have_content(public_group.full_name) - expect(page).to have_content(group.full_name) - expect(page).to have_content(public_group.full_name) - expect(page).not_to have_content(private_group.full_name) - expect(page.all('.js-groups-list-holder .groups-list li').length).to eq 2 - end + fill_in 'filter', with: "" + page.find('[name="filter"]').send_keys(:enter) + wait_for_requests - it 'shows non-archived projects count' do - # Initially project is not archived - expect(find('.js-groups-list-holder .groups-list li:first-child .stats .number-projects')).to have_text("1") + expect(page).to have_content(group.full_name) + expect(page).to have_content(public_group.full_name) + expect(page).not_to have_content(private_group.full_name) + expect(page.all('.js-groups-list-holder .groups-list li').length).to eq 2 + end - # Archive project - ::Projects::UpdateService.new(empty_project, user, archived: true).execute - visit explore_groups_path + it 'shows non-archived projects count' do + # Initially project is not archived + expect(find('.js-groups-list-holder .groups-list li:first-child .stats .number-projects')).to have_text("1") - # Check project count - expect(find('.js-groups-list-holder .groups-list li:first-child .stats .number-projects')).to have_text("0") + # Archive project + ::Projects::UpdateService.new(empty_project, user, archived: true).execute + visit explore_groups_path - # Unarchive project - ::Projects::UpdateService.new(empty_project, user, archived: false).execute - visit explore_groups_path + # Check project count + expect(find('.js-groups-list-holder .groups-list li:first-child .stats .number-projects')).to have_text("0") - # Check project count - expect(find('.js-groups-list-holder .groups-list li:first-child .stats .number-projects')).to have_text("1") - end + # Unarchive project + ::Projects::UpdateService.new(empty_project, user, archived: false).execute + visit explore_groups_path - describe 'landing component' do - it 'shows a landing component' do - expect(page).to have_content('Below you will find all the groups that are public.') + # Check project count + expect(find('.js-groups-list-holder .groups-list li:first-child .stats .number-projects')).to have_text("1") end - it 'is dismissable' do - find('.dismiss-button').click + describe 'landing component' do + it 'shows a landing component' do + expect(page).to have_content('Below you will find all the groups that are public.') + end + + it 'is dismissable' do + find('.dismiss-button').click + + expect(page).not_to have_content('Below you will find all the groups that are public.') + end - expect(page).not_to have_content('Below you will find all the groups that are public.') + it 'does not show persistently once dismissed' do + find('.dismiss-button').click + + visit explore_groups_path + + expect(page).not_to have_content('Below you will find all the groups that are public.') + end end + end - it 'does not show persistently once dismissed' do - find('.dismiss-button').click + context 'when there are no groups to show' do + before do + sign_in(user) visit explore_groups_path + wait_for_requests + end - expect(page).not_to have_content('Below you will find all the groups that are public.') + it 'shows empty state' do + expect(page).to have_content(_('No public groups')) end end end diff --git a/spec/features/explore/navbar_spec.rb b/spec/features/explore/navbar_spec.rb index 8f281abe6a7..853d66ed4d1 100644 --- a/spec/features/explore/navbar_spec.rb +++ b/spec/features/explore/navbar_spec.rb @@ -7,6 +7,7 @@ RSpec.describe '"Explore" navbar', feature_category: :navigation do it_behaves_like 'verified navigation bar' do before do + stub_feature_flags(super_sidebar_logged_out: false) visit explore_projects_path end end diff --git a/spec/features/explore/user_explores_projects_spec.rb b/spec/features/explore/user_explores_projects_spec.rb index f259ba6a167..43d464e0c9f 100644 --- a/spec/features/explore/user_explores_projects_spec.rb +++ b/spec/features/explore/user_explores_projects_spec.rb @@ -3,6 +3,10 @@ require 'spec_helper' RSpec.describe 'User explores projects', feature_category: :user_profile do + before do + stub_feature_flags(super_sidebar_logged_out: false) + end + describe '"All" tab' do it_behaves_like 'an "Explore" page with sidebar and breadcrumbs', :explore_projects_path, :projects end diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb index f94f0288f99..dfafacf48e2 100644 --- a/spec/features/global_search_spec.rb +++ b/spec/features/global_search_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Global search', :js, feature_category: :global_search do include AfterNextHelpers - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, namespace: user.namespace) } before do diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb index d68b4ccf8f8..953a8e27547 100644 --- a/spec/features/groups/container_registry_spec.rb +++ b/spec/features/groups/container_registry_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Container Registry', :js, feature_category: :container_registry do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } let(:project) { create(:project, namespace: group) } diff --git a/spec/features/groups/dependency_proxy_for_containers_spec.rb b/spec/features/groups/dependency_proxy_for_containers_spec.rb index c0456140291..1e15b97c5aa 100644 --- a/spec/features/groups/dependency_proxy_for_containers_spec.rb +++ b/spec/features/groups/dependency_proxy_for_containers_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'Group Dependency Proxy for containers', :js, feature_category: : include DependencyProxyHelpers include_context 'file upload requests helpers' + include_context 'with a server running the dependency proxy' let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } @@ -21,17 +22,6 @@ RSpec.describe 'Group Dependency Proxy for containers', :js, feature_category: : HTTParty.get(url, headers: headers) end - def run_server(handler) - default_server = Capybara.server - - Capybara.server = Capybara.servers[:puma] - server = Capybara::Server.new(handler) - server.boot - server - ensure - Capybara.server = default_server - end - let_it_be(:external_server) do handler = lambda do |env| if env['REQUEST_PATH'] == '/token' diff --git a/spec/features/groups/dependency_proxy_spec.rb b/spec/features/groups/dependency_proxy_spec.rb index 60922f813df..2d4f6d4fbf2 100644 --- a/spec/features/groups/dependency_proxy_spec.rb +++ b/spec/features/groups/dependency_proxy_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe 'Group Dependency Proxy', feature_category: :dependency_proxy do - let(:owner) { create(:user) } - let(:reporter) { create(:user) } + let(:owner) { create(:user, :no_super_sidebar) } + let(:reporter) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } let(:path) { group_dependency_proxy_path(group) } let(:settings_path) { group_settings_packages_and_registries_path(group) } diff --git a/spec/features/groups/group_page_with_external_authorization_service_spec.rb b/spec/features/groups/group_page_with_external_authorization_service_spec.rb index 5b373aecce8..4cc0fe4171d 100644 --- a/spec/features/groups/group_page_with_external_authorization_service_spec.rb +++ b/spec/features/groups/group_page_with_external_authorization_service_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'The group page', feature_category: :groups_and_projects do include ExternalAuthorizationServiceHelpers - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } before do diff --git a/spec/features/groups/group_runners_spec.rb b/spec/features/groups/group_runners_spec.rb index e9d2d185e8a..4e5d7c6f8e8 100644 --- a/spec/features/groups/group_runners_spec.rb +++ b/spec/features/groups/group_runners_spec.rb @@ -7,182 +7,235 @@ RSpec.describe "Group Runners", feature_category: :runner_fleet do include Spec::Support::Helpers::ModalHelpers let_it_be(:group_owner) { create(:user) } + let_it_be(:group_maintainer) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } before do group.add_owner(group_owner) - sign_in(group_owner) + group.add_maintainer(group_maintainer) end describe "Group runners page", :js do - context "with no runners" do + context 'when logged in as group maintainer' do before do - visit group_runners_path(group) + sign_in(group_maintainer) end - it_behaves_like 'shows no runners registered' - - it 'shows tabs with total counts equal to 0' do - expect(page).to have_link('All 0') - expect(page).to have_link('Group 0') - expect(page).to have_link('Project 0') - end - end + context "with no runners" do + before do + visit group_runners_path(group) + end - context "with an online group runner" do - let!(:group_runner) do - create(:ci_runner, :group, groups: [group], description: 'runner-foo', contacted_at: Time.zone.now) - end + it_behaves_like 'shows no runners registered' - before do - visit group_runners_path(group) + it 'shows tabs with total counts equal to 0' do + expect(page).to have_link('All 0') + expect(page).to have_link('Group 0') + expect(page).to have_link('Project 0') + end end - it_behaves_like 'shows runner in list' do - let(:runner) { group_runner } - end + context "with an online group runner" do + let_it_be(:group_runner) do + create(:ci_runner, :group, groups: [group], description: 'runner-foo', contacted_at: Time.zone.now) + end - it_behaves_like 'pauses, resumes and deletes a runner' do - let(:runner) { group_runner } - end + before do + visit group_runners_path(group) + end - it 'shows an editable group badge' do - within_runner_row(group_runner.id) do - expect(find_link('Edit')[:href]).to end_with(edit_group_runner_path(group, group_runner)) + it_behaves_like 'shows runner in list' do + let(:runner) { group_runner } + end - expect(page).to have_selector '.badge', text: s_('Runners|Group') + it_behaves_like 'shows runner details from list' do + let(:runner) { group_runner } + let(:runner_page_path) { group_runner_path(group, group_runner) } end - end - context 'when description does not match' do - before do - input_filtered_search_keys('runner-baz') + it 'shows a group runner badge' do + within_runner_row(group_runner.id) do + expect(page).to have_selector '.badge', text: s_('Runners|Group') + end end - it_behaves_like 'shows no runners found' + context 'when description does not match' do + before do + input_filtered_search_keys('runner-baz') + end + + it_behaves_like 'shows no runners found' - it 'shows no runner' do - expect(page).not_to have_content 'runner-foo' + it 'shows no runner' do + expect(page).not_to have_content 'runner-foo' + end end end - end - context "with an online project runner" do - let!(:project_runner) do - create(:ci_runner, :project, projects: [project], description: 'runner-bar', contacted_at: Time.zone.now) - end + context "with an online project runner" do + let_it_be(:project_runner) do + create(:ci_runner, :project, projects: [project], description: 'runner-bar', contacted_at: Time.zone.now) + end - before do - visit group_runners_path(group) - end + before do + visit group_runners_path(group) + end - it_behaves_like 'shows runner in list' do - let(:runner) { project_runner } - end + it_behaves_like 'shows runner in list' do + let(:runner) { project_runner } + end - it_behaves_like 'pauses, resumes and deletes a runner' do - let(:runner) { project_runner } + it_behaves_like 'shows runner details from list' do + let(:runner) { project_runner } + let(:runner_page_path) { group_runner_path(group, project_runner) } + end + + it 'shows a project runner badge' do + within_runner_row(project_runner.id) do + expect(page).to have_selector '.badge', text: s_('Runners|Project') + end + end end - it 'shows an editable project runner' do - within_runner_row(project_runner.id) do - expect(find_link('Edit')[:href]).to end_with(edit_group_runner_path(group, project_runner)) + context "with an online instance runner" do + let_it_be(:instance_runner) do + create(:ci_runner, :instance, description: 'runner-baz', contacted_at: Time.zone.now) + end - expect(page).to have_selector '.badge', text: s_('Runners|Project') + before do + visit group_runners_path(group) end - end - end - context "with an online instance runner" do - let!(:instance_runner) do - create(:ci_runner, :instance, description: 'runner-baz', contacted_at: Time.zone.now) - end + context "when selecting 'Show only inherited'" do + before do + find("[data-testid='runner-membership-toggle'] button").click - before do - visit group_runners_path(group) - end + wait_for_requests + end - context "when selecting 'Show only inherited'" do - before do - find("[data-testid='runner-membership-toggle'] button").click + it_behaves_like 'shows runner in list' do + let(:runner) { instance_runner } + end - wait_for_requests + it_behaves_like 'shows runner details from list' do + let(:runner) { instance_runner } + let(:runner_page_path) { group_runner_path(group, instance_runner) } + end end + end - it_behaves_like 'shows runner in list' do - let(:runner) { instance_runner } + describe 'filtered search' do + before do + visit group_runners_path(group) end - it 'shows runner details page' do - click_link("##{instance_runner.id} (#{instance_runner.short_sha})") + it 'allows user to search by paused and status', :js do + focus_filtered_search - expect(current_url).to include(group_runner_path(group, instance_runner)) - expect(page).to have_content "#{s_('Runners|Description')} runner-baz" + page.within(search_bar_selector) do + expect(page).to have_link(s_('Runners|Paused')) + expect(page).to have_content('Status') + end end end - end - context 'with a multi-project runner' do - let(:project) { create(:project, group: group) } - let(:project_2) { create(:project, group: group) } - let!(:runner) { create(:ci_runner, :project, projects: [project, project_2], description: 'group-runner') } + describe 'filter by tag' do + let!(:rnr_1) { create(:ci_runner, :group, groups: [group], description: 'runner-blue', tag_list: ['blue']) } + let!(:rnr_2) { create(:ci_runner, :group, groups: [group], description: 'runner-red', tag_list: ['red']) } - it 'user cannot remove the project runner' do - visit group_runners_path(group) + before do + visit group_runners_path(group) + end - within_runner_row(runner.id) do - expect(page).not_to have_button 'Delete runner' + it_behaves_like 'filters by tag' do + let(:tag) { 'blue' } + let(:found_runner) { rnr_1.description } + let(:missing_runner) { rnr_2.description } end end end - context "with multiple runners" do + context 'when logged in as group owner' do before do - create(:ci_runner, :group, groups: [group], description: 'runner-foo') - create(:ci_runner, :group, groups: [group], description: 'runner-bar') - - visit group_runners_path(group) + sign_in(group_owner) end - it_behaves_like 'deletes runners in bulk' do - let(:runner_count) { '2' } - end - end + context "with an online group runner" do + let_it_be(:group_runner) do + create(:ci_runner, :group, groups: [group], description: 'runner-foo', contacted_at: Time.zone.now) + end - describe 'filtered search' do - before do - visit group_runners_path(group) + before do + visit group_runners_path(group) + end + + it_behaves_like 'pauses, resumes and deletes a runner' do + let(:runner) { group_runner } + end + + it 'shows an edit link' do + within_runner_row(group_runner.id) do + expect(find_link('Edit')[:href]).to end_with(edit_group_runner_path(group, group_runner)) + end + end end - it 'allows user to search by paused and status', :js do - focus_filtered_search + context "with an online project runner" do + let_it_be(:project_runner) do + create(:ci_runner, :project, projects: [project], description: 'runner-bar', contacted_at: Time.zone.now) + end + + before do + visit group_runners_path(group) + end - page.within(search_bar_selector) do - expect(page).to have_link(s_('Runners|Paused')) - expect(page).to have_content('Status') + it_behaves_like 'pauses, resumes and deletes a runner' do + let(:runner) { project_runner } + end + + it 'shows an editable project runner' do + within_runner_row(project_runner.id) do + expect(find_link('Edit')[:href]).to end_with(edit_group_runner_path(group, project_runner)) + end end end - end - describe 'filter by tag' do - let!(:runner_1) { create(:ci_runner, :group, groups: [group], description: 'runner-blue', tag_list: ['blue']) } - let!(:runner_2) { create(:ci_runner, :group, groups: [group], description: 'runner-red', tag_list: ['red']) } + context 'with a multi-project runner' do + let_it_be(:project) { create(:project, group: group) } + let_it_be(:project_2) { create(:project, group: group) } + let_it_be(:runner) do + create(:ci_runner, :project, projects: [project, project_2], description: 'group-runner') + end - before do - visit group_runners_path(group) + it 'owner cannot remove the project runner' do + visit group_runners_path(group) + + within_runner_row(runner.id) do + expect(page).not_to have_button 'Delete runner' + end + end end - it_behaves_like 'filters by tag' do - let(:tag) { 'blue' } - let(:found_runner) { runner_1.description } - let(:missing_runner) { runner_2.description } + context "with multiple runners" do + before do + create(:ci_runner, :group, groups: [group], description: 'runner-foo') + create(:ci_runner, :group, groups: [group], description: 'runner-bar') + + visit group_runners_path(group) + end + + it_behaves_like 'deletes runners in bulk' do + let(:runner_count) { '2' } + end end end end describe "Group runner create page", :js do before do + sign_in(group_owner) + visit new_group_runner_path(group) end @@ -196,23 +249,39 @@ RSpec.describe "Group Runners", feature_category: :runner_fleet do create(:ci_runner, :group, groups: [group], description: 'runner-foo') end - let_it_be(:group_runner_job) { create(:ci_build, runner: group_runner) } + let_it_be(:group_runner_job) { create(:ci_build, runner: group_runner, project: project) } - before do - visit group_runner_path(group, group_runner) - end + context 'when logged in as group maintainer' do + before do + sign_in(group_maintainer) - it 'user views runner details' do - expect(page).to have_content "#{s_('Runners|Description')} runner-foo" + visit group_runner_path(group, group_runner) + end + + it 'user views runner details' do + expect(page).to have_content "#{s_('Runners|Description')} runner-foo" + end end - it_behaves_like 'shows runner jobs tab' do - let(:job_count) { '1' } - let(:job) { group_runner_job } + context 'when logged in as group owner' do + before do + sign_in(group_owner) + + visit group_runner_path(group, group_runner) + end + + it_behaves_like 'shows runner jobs tab' do + let(:job_count) { '1' } + let(:job) { group_runner_job } + end end end describe "Group runner edit page", :js do + before do + sign_in(group_owner) + end + context 'when updating a group runner' do let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) } @@ -239,6 +308,8 @@ RSpec.describe "Group Runners", feature_category: :runner_fleet do let(:runner) { project_runner } let(:runner_page_path) { group_runner_path(group, project_runner) } end + + it_behaves_like 'shows locked field' end end end diff --git a/spec/features/groups/labels/create_spec.rb b/spec/features/groups/labels/create_spec.rb index 5b57e670c1d..8242f422e6e 100644 --- a/spec/features/groups/labels/create_spec.rb +++ b/spec/features/groups/labels/create_spec.rb @@ -9,15 +9,17 @@ RSpec.describe 'Create a group label', feature_category: :team_planning do before do group.add_owner(user) sign_in(user) - visit group_labels_path(group) + + visit new_group_label_path(group) end it 'creates a new label' do - click_link 'New label' fill_in 'Title', with: 'test-label' click_button 'Create label' expect(page).to have_content 'test-label' expect(page).to have_current_path(group_labels_path(group), ignore_query: true) end + + it_behaves_like 'lock_on_merge when creating labels' end diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb index 6e056d35435..70568d4baa2 100644 --- a/spec/features/groups/labels/edit_spec.rb +++ b/spec/features/groups/labels/edit_spec.rb @@ -12,6 +12,7 @@ RSpec.describe 'Edit group label', feature_category: :team_planning do before do group.add_owner(user) sign_in(user) + visit edit_group_label_path(group, label) end @@ -34,4 +35,17 @@ RSpec.describe 'Edit group label', feature_category: :team_planning do expect(page).to have_content("#{label.title} was removed").and have_no_content("#{label.title}</span>") end + + describe 'lock_on_merge' do + let(:label_unlocked) { create(:group_label, group: group, lock_on_merge: false) } + let(:label_locked) { create(:group_label, group: group, lock_on_merge: true) } + let(:edit_label_path_unlocked) { edit_group_label_path(group, label_unlocked) } + let(:edit_label_path_locked) { edit_group_label_path(group, label_locked) } + + before do + visit edit_label_path_unlocked + end + + it_behaves_like 'lock_on_merge when editing labels' + end end diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb index 138031ffaac..dd64ddcede5 100644 --- a/spec/features/groups/members/manage_members_spec.rb +++ b/spec/features/groups/members/manage_members_spec.rb @@ -85,7 +85,7 @@ RSpec.describe 'Groups > Members > Manage members', feature_category: :groups_an end end - it_behaves_like 'inviting members', 'group-members-page' do + it_behaves_like 'inviting members', 'group_members_page' do let_it_be(:entity) { group } let_it_be(:members_page_path) { group_group_members_path(entity) } let_it_be(:subentity) { create(:group, parent: group) } diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb index cd0c9bfe3eb..c04b84be90e 100644 --- a/spec/features/groups/members/request_access_spec.rb +++ b/spec/features/groups/members/request_access_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe 'Groups > Members > Request access', feature_category: :groups_and_projects do - let(:user) { create(:user) } - let(:owner) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } + let(:owner) { create(:user, :no_super_sidebar) } let(:group) { create(:group, :public) } let!(:project) { create(:project, :private, namespace: group) } diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb index a52e2d95fed..6a38f0c59a8 100644 --- a/spec/features/groups/navbar_spec.rb +++ b/spec/features/groups/navbar_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Group navbar', :with_license, feature_category: :navigation do include_context 'group navbar structure' - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } @@ -18,7 +18,6 @@ RSpec.describe 'Group navbar', :with_license, feature_category: :navigation do stub_config(dependency_proxy: { enabled: false }) stub_config(registry: { enabled: false }) - stub_feature_flags(harbor_registry_integration: false) stub_feature_flags(observability_group_tab: false) stub_group_wikis(false) group.add_maintainer(user) @@ -87,8 +86,6 @@ RSpec.describe 'Group navbar', :with_license, feature_category: :navigation do before do group.update!(harbor_integration: harbor_integration) - stub_feature_flags(harbor_registry_integration: true) - insert_harbor_registry_nav(_('Package Registry')) visit group_path(group) diff --git a/spec/features/groups/new_group_page_spec.rb b/spec/features/groups/new_group_page_spec.rb index c3731565ddf..e1034f2bb9d 100644 --- a/spec/features/groups/new_group_page_spec.rb +++ b/spec/features/groups/new_group_page_spec.rb @@ -39,14 +39,14 @@ RSpec.describe 'New group page', :js, feature_category: :groups_and_projects do context 'for a new top-level group' do it 'shows the "Your work" navigation' do visit new_group_path - expect(page).to have_selector(".super-sidebar .context-switcher-toggle", text: "Your work") + expect(page).to have_selector(".super-sidebar", text: "Your work") end end context 'for a new subgroup' do it 'shows the group navigation of the parent group' do visit new_group_path(parent_id: parent_group.id, anchor: 'create-group-pane') - expect(page).to have_selector(".super-sidebar .context-switcher-toggle", text: parent_group.name) + expect(page).to have_selector(".super-sidebar", text: parent_group.name) end end end diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb index ec8215928e4..1d9269501be 100644 --- a/spec/features/groups/packages_spec.rb +++ b/spec/features/groups/packages_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Group Packages', feature_category: :package_registry do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb index 8ea8dc9219a..fa310722860 100644 --- a/spec/features/groups/settings/packages_and_registries_spec.rb +++ b/spec/features/groups/settings/packages_and_registries_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Group Package and registry settings', feature_category: :package_registry do include WaitForRequests - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } let(:sub_group) { create(:group, parent: group) } diff --git a/spec/features/groups/user_sees_package_sidebar_spec.rb b/spec/features/groups/user_sees_package_sidebar_spec.rb index 6a91dfb92bf..4efb9ff7608 100644 --- a/spec/features/groups/user_sees_package_sidebar_spec.rb +++ b/spec/features/groups/user_sees_package_sidebar_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Groups > sidebar', feature_category: :groups_and_projects do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:group) { create(:group) } before do diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 67133b1856f..7af58bf460c 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Group', feature_category: :groups_and_projects do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/help_dropdown_spec.rb b/spec/features/help_dropdown_spec.rb index 5f1d3a5e2b7..08d7dba4d79 100644 --- a/spec/features/help_dropdown_spec.rb +++ b/spec/features/help_dropdown_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe "Help Dropdown", :js, feature_category: :shared do - let_it_be(:user) { create(:user) } - let_it_be(:admin) { create(:admin) } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:admin) { create(:admin, :no_super_sidebar) } before do stub_application_setting(version_check_enabled: true) diff --git a/spec/features/ide/user_opens_merge_request_spec.rb b/spec/features/ide/user_opens_merge_request_spec.rb index dc280133a20..2aa89cadb7d 100644 --- a/spec/features/ide/user_opens_merge_request_spec.rb +++ b/spec/features/ide/user_opens_merge_request_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe 'IDE merge request', :js, feature_category: :web_ide do include CookieHelper - let(:merge_request) { create(:merge_request, :simple, source_project: project) } - let(:project) { create(:project, :public, :repository) } - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :public, :repository, namespace: user.namespace) } + let_it_be(:merge_request) { create(:merge_request, :simple, source_project: project) } before do stub_feature_flags(vscode_web_ide: false) diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb index d6feb008d47..7e447ae32c0 100644 --- a/spec/features/incidents/incident_details_spec.rb +++ b/spec/features/incidents/incident_details_spec.rb @@ -150,6 +150,9 @@ RSpec.describe 'Incident details', :js, feature_category: :incident_management d wait_for_requests sticky_header = find_by_scrolling('[data-testid=issue-sticky-header]') - expect(sticky_header.find('[data-testid=confidential]')).to be_present + + page.within(sticky_header) do + expect(page).to have_text 'Confidential' + end end end diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb index 03ec72980e5..a56df7bdecc 100644 --- a/spec/features/invites_spec.rb +++ b/spec/features/invites_spec.rb @@ -4,7 +4,8 @@ require 'spec_helper' RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_category: :experimentation_expansion do let_it_be(:owner) { create(:user, name: 'John Doe') } - let_it_be(:group) { create(:group, name: 'Owned') } + # private will ensure we really have access to the group when we land on the activity page + let_it_be(:group) { create(:group, :private, name: 'Owned') } let_it_be(:project) { create(:project, :repository, namespace: group) } let(:group_invite) { group.group_members.invite.last } @@ -22,18 +23,6 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate visit user_confirmation_path(confirmation_token: new_user_token) end - def fill_in_sign_up_form(new_user, submit_button_text = 'Register') - fill_in 'new_user_first_name', with: new_user.first_name - fill_in 'new_user_last_name', with: new_user.last_name - fill_in 'new_user_username', with: new_user.username - fill_in 'new_user_email', with: new_user.email - fill_in 'new_user_password', with: new_user.password - - wait_for_all_requests - - click_button submit_button_text - end - def fill_in_welcome_form select 'Software Developer', from: 'user_role' click_button 'Get started!' @@ -58,10 +47,10 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate expect(page).to have_content('To accept this invitation, create an account or sign in') end - it 'pre-fills the "Username or email" field on the sign in box with the invite_email from the invite' do + it 'pre-fills the "Username or primary email" field on the sign in box with the invite_email from the invite' do click_link 'Sign in' - expect(find_field('Username or email').value).to eq(group_invite.invite_email) + expect(find_field('Username or primary email').value).to eq(group_invite.invite_email) end it 'pre-fills the Email field on the sign up box with the invite_email from the invite' do @@ -70,11 +59,11 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate end context 'when invite is sent before account is created;ldap or service sign in for manual acceptance edge case' do - let(:user) { create(:user, email: 'user@example.com') } + let(:user) { create(:user, :no_super_sidebar, email: 'user@example.com') } context 'when invite clicked and not signed in' do before do - visit invite_path(group_invite.raw_invite_token) + visit invite_path(group_invite.raw_invite_token, invite_type: Emails::Members::INITIAL_INVITE) end it 'sign in, grants access and redirects to group activity page' do @@ -82,7 +71,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate gitlab_sign_in(user, remember: true, visit: false) - expect(page).to have_current_path(activity_group_path(group), ignore_query: true) + expect_to_be_on_group_activity_page(group) end end @@ -143,6 +132,10 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate end end end + + def expect_to_be_on_group_activity_page(group) + expect(page).to have_current_path(activity_group_path(group)) + end end end end @@ -195,12 +188,11 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate context 'when the user sign-up using a different email address' do let(:invite_email) { build_stubbed(:user).email } - it 'signs up and redirects to the activity page', - quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/414971' do + it 'signs up and redirects to the projects dashboard' do fill_in_sign_up_form(new_user) fill_in_welcome_form - expect(page).to have_current_path(activity_group_path(group), ignore_query: true) + expect_to_be_on_projects_dashboard_with_zero_authorized_projects end end end @@ -232,8 +224,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate end context 'when the user signs up for an account with the invitation email address' do - it 'redirects to the most recent membership activity page with all invitations automatically accepted', - quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417092' do + it 'redirects to the most recent membership activity page with all invitations automatically accepted' do fill_in_sign_up_form(new_user) fill_in_welcome_form @@ -250,13 +241,13 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate stub_feature_flags(identity_verification: false) end - it 'signs up and redirects to the group activity page' do + it 'signs up and redirects to the projects dashboard' do fill_in_sign_up_form(new_user) confirm_email(new_user) gitlab_sign_in(new_user, remember: true, visit: false) fill_in_welcome_form - expect(page).to have_current_path(activity_group_path(group), ignore_query: true) + expect_to_be_on_projects_dashboard_with_zero_authorized_projects end end @@ -266,15 +257,22 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate allow(User).to receive(:allow_unconfirmed_access_for).and_return 2.days end - it 'signs up and redirects to the group activity page' do + it 'signs up and redirects to the projects dashboard' do fill_in_sign_up_form(new_user) fill_in_welcome_form - expect(page).to have_current_path(activity_group_path(group), ignore_query: true) + expect_to_be_on_projects_dashboard_with_zero_authorized_projects end end end end + + def expect_to_be_on_projects_dashboard_with_zero_authorized_projects + expect(page).to have_current_path(dashboard_projects_path) + + expect(page).to have_content _('Welcome to GitLab') + expect(page).to have_content _('Faster releases. Better code. Less pain.') + end end context 'when accepting an invite without an account' do diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 0a06a052bc2..0c5b33c2530 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -113,33 +113,5 @@ RSpec.describe 'Dropdown assignee', :js, feature_category: :team_planning do expect(page).to have_text invited_to_group_group_user.name expect(page).not_to have_text subsubgroup_user.name end - - context 'when new_graphql_users_autocomplete is disabled' do - before do - stub_feature_flags(new_graphql_users_autocomplete: false) - end - - it 'shows inherited, direct, and invited group members but not descendent members', :aggregate_failures do - visit issues_group_path(subgroup) - - select_tokens 'Assignee', '=' - - expect(page).to have_text group_user.name - expect(page).to have_text subgroup_user.name - expect(page).to have_text invited_to_group_group_user.name - expect(page).not_to have_text subsubgroup_user.name - expect(page).not_to have_text invited_to_project_group_user.name - - visit project_issues_path(subgroup_project) - - select_tokens 'Assignee', '=' - - expect(page).to have_text group_user.name - expect(page).to have_text subgroup_user.name - expect(page).to have_text invited_to_project_group_user.name - expect(page).to have_text invited_to_group_group_user.name - expect(page).not_to have_text subsubgroup_user.name - end - end end end diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb index 3031b20eb7c..e51c82081ff 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'Visual tokens', :js, feature_category: :team_planning do include FilteredSearchHelpers let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } - let_it_be(:user_rock) { create(:user, name: 'The Rock', username: 'rock') } + let_it_be(:user) { create(:user, :no_super_sidebar, name: 'administrator', username: 'root') } + let_it_be(:user_rock) { create(:user, :no_super_sidebar, name: 'The Rock', username: 'rock') } let_it_be(:milestone_nine) { create(:milestone, title: '9.0', project: project) } let_it_be(:milestone_ten) { create(:milestone, title: '10.0', project: project) } let_it_be(:label) { create(:label, project: project, title: 'abc') } diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 5f7a4f26a98..ed2c712feb1 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -8,14 +8,13 @@ RSpec.describe 'New/edit issue', :js, feature_category: :team_planning do include ContentEditorHelpers let_it_be(:project) { create(:project, :repository) } - let_it_be(:user) { create(:user) } - let_it_be(:user2) { create(:user) } - let_it_be(:guest) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:user2) { create(:user, :no_super_sidebar) } + let_it_be(:guest) { create(:user, :no_super_sidebar) } let_it_be(:milestone) { create(:milestone, project: project) } let_it_be(:label) { create(:label, project: project) } let_it_be(:label2) { create(:label, project: project) } let_it_be(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) } - let_it_be(:issue2) { create(:issue, project: project, assignees: [user], milestone: milestone) } let_it_be(:confidential_issue) { create(:issue, project: project, assignees: [user], milestone: milestone, confidential: true) } let(:current_user) { user } @@ -666,69 +665,59 @@ RSpec.describe 'New/edit issue', :js, feature_category: :team_planning do end end - describe 'inline edit' do - context 'within issue 1' do - before do - visit project_issue_path(project, issue) - wait_for_requests - end + describe 'editing an issue by hotkey' do + let_it_be(:issue2) { create(:issue, project: project) } - it 'opens inline edit form with shortcut' do - find('body').send_keys('e') + before do + visit project_issue_path(project, issue2) + end - expect(page).to have_selector('.detail-page-description form') - end + it 'opens inline edit form with shortcut' do + find('body').send_keys('e') - describe 'when user has made no changes' do - it 'let user leave the page without warnings' do - expected_content = 'Issue created' - expect(page).to have_content(expected_content) + expect(page).to have_selector('.detail-page-description form') + end - find('body').send_keys('e') + context 'when user has made no changes' do + it 'let user leave the page without warnings' do + expected_content = 'Issue created' + expect(page).to have_content(expected_content) - click_link 'Boards' + find('body').send_keys('e') - expect(page).not_to have_content(expected_content) - end - end + click_link 'Boards' - describe 'when user has made changes' do - it 'shows a warning and can stay on page', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/397683' do - content = 'new issue content' + expect(page).not_to have_content(expected_content) + end + end - find('body').send_keys('e') - fill_in 'issue-description', with: content + context 'when user has made changes' do + it 'shows a warning and can stay on page' do + content = 'new issue content' - click_link 'Boards' + find('body').send_keys('e') + fill_in 'issue-description', with: content + click_link 'Boards' do page.driver.browser.switch_to.alert.dismiss - - click_button 'Save changes' - wait_for_requests - - expect(page).to have_content(content) end - end - end - context 'within issue 2' do - before do - visit project_issue_path(project, issue2) + click_button 'Save changes' wait_for_requests - end - describe 'when user has made changes' do - it 'shows a warning and can leave page', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/410497' do - content = 'new issue content' - find('body').send_keys('e') - fill_in 'issue-description', with: content + expect(page).to have_content(content) + end - click_link 'Boards' + it 'shows a warning and can leave page' do + content = 'new issue content' + find('body').send_keys('e') + fill_in 'issue-description', with: content + click_link 'Boards' do page.driver.browser.switch_to.alert.accept - - expect(page).not_to have_content(content) end + + expect(page).not_to have_content(content) end end end diff --git a/spec/features/issues/issue_state_spec.rb b/spec/features/issues/issue_state_spec.rb index 758dafccb86..2a8b33183bb 100644 --- a/spec/features/issues/issue_state_spec.rb +++ b/spec/features/issues/issue_state_spec.rb @@ -3,53 +3,71 @@ require 'spec_helper' RSpec.describe 'issue state', :js, feature_category: :team_planning do - let_it_be(:project) { create(:project) } + include CookieHelper + + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } let_it_be(:user) { create(:user) } before do project.add_developer(user) sign_in(user) + set_cookie('new-actions-popover-viewed', 'true') end shared_examples 'issue closed' do |selector| it 'can close an issue' do - wait_for_requests + expect(page).to have_selector('[data-testid="issue-state-badge"]') - expect(find('.status-box')).to have_content 'Open' + expect(find('[data-testid="issue-state-badge"]')).to have_content 'Open' within selector do click_button 'Close issue' wait_for_requests end - expect(find('.status-box')).to have_content 'Closed' + expect(find('[data-testid="issue-state-badge"]')).to have_content 'Closed' end end shared_examples 'issue reopened' do |selector| it 'can reopen an issue' do - wait_for_requests + expect(page).to have_selector('[data-testid="issue-state-badge"]') - expect(find('.status-box')).to have_content 'Closed' + expect(find('[data-testid="issue-state-badge"]')).to have_content 'Closed' within selector do click_button 'Reopen issue' wait_for_requests end - expect(find('.status-box')).to have_content 'Open' + expect(find('[data-testid="issue-state-badge"]')).to have_content 'Open' end end - describe 'when open', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297348' do + describe 'when open' do context 'when clicking the top `Close issue` button', :aggregate_failures do - let(:open_issue) { create(:issue, project: project) } + context 'when move_close_into_dropdown FF is disabled' do + let(:open_issue) { create(:issue, project: project) } - before do - visit project_issue_path(project, open_issue) + before do + stub_feature_flags(move_close_into_dropdown: false) + visit project_issue_path(project, open_issue) + end + + it_behaves_like 'issue closed', '.detail-page-header-actions' end - it_behaves_like 'issue closed', '.detail-page-header' + context 'when move_close_into_dropdown FF is enabled' do + let(:open_issue) { create(:issue, project: project) } + + before do + visit project_issue_path(project, open_issue) + find('#new-actions-header-dropdown > button').click + end + + it_behaves_like 'issue closed', '.dropdown-menu-right' + end end context 'when clicking the bottom `Close issue` button', :aggregate_failures do @@ -63,15 +81,29 @@ RSpec.describe 'issue state', :js, feature_category: :team_planning do end end - describe 'when closed', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297201' do + describe 'when closed' do context 'when clicking the top `Reopen issue` button', :aggregate_failures do - let(:closed_issue) { create(:issue, project: project, state: 'closed') } + context 'when move_close_into_dropdown FF is disabled' do + let(:closed_issue) { create(:issue, project: project, state: 'closed', author: user) } - before do - visit project_issue_path(project, closed_issue) + before do + stub_feature_flags(move_close_into_dropdown: false) + visit project_issue_path(project, closed_issue) + end + + it_behaves_like 'issue reopened', '.detail-page-header-actions' end - it_behaves_like 'issue reopened', '.detail-page-header' + context 'when move_close_into_dropdown FF is enabled' do + let(:closed_issue) { create(:issue, project: project, state: 'closed', author: user) } + + before do + visit project_issue_path(project, closed_issue) + find('#new-actions-header-dropdown > button').click + end + + it_behaves_like 'issue reopened', '.dropdown-menu-right' + end end context 'when clicking the bottom `Reopen issue` button', :aggregate_failures do diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index 4512e88ae72..a6ed0b52e7d 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -103,7 +103,7 @@ RSpec.describe 'issue move to another project', feature_category: :team_planning let(:namespace) { create(:namespace) } let(:regular_project) { create(:project, title: project_title, service_desk_enabled: false) } let(:service_desk_project) { build(:project, :private, namespace: namespace, service_desk_enabled: true) } - let(:service_desk_issue) { create(:issue, project: service_desk_project, author: ::User.support_bot) } + let(:service_desk_issue) { create(:issue, project: service_desk_project, author: ::Users::Internal.support_bot) } before do allow(Gitlab::Email::IncomingEmail).to receive(:enabled?).and_return(true) diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb index a390dca6822..293b6c53eb5 100644 --- a/spec/features/issues/note_polling_spec.rb +++ b/spec/features/issues/note_polling_spec.rb @@ -19,22 +19,6 @@ RSpec.describe 'Issue notes polling', :js, feature_category: :team_planning do expect(page).to have_selector("#note_#{note.id}", text: 'Looks good!') end - - context 'when action_cable_notes is disabled' do - before do - stub_feature_flags(action_cable_notes: false) - end - - it 'displays the new comment' do - visit project_issue_path(project, issue) - close_rich_text_promo_popover_if_present - - note = create(:note, noteable: issue, project: project, note: 'Looks good!') - wait_for_requests - - expect(page).to have_selector("#note_#{note.id}", text: 'Looks good!') - end - end end describe 'updates' do diff --git a/spec/features/issues/service_desk_spec.rb b/spec/features/issues/service_desk_spec.rb index 1b99c8b39d3..120b4ddb6e1 100644 --- a/spec/features/issues/service_desk_spec.rb +++ b/spec/features/issues/service_desk_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' RSpec.describe 'Service Desk Issue Tracker', :js, feature_category: :service_desk do let(:project) { create(:project, :private, service_desk_enabled: true) } - let_it_be(:user) { create(:user) } - let_it_be(:support_bot) { User.support_bot } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:support_bot) { Users::Internal.support_bot } before do # The following two conditions equate to Gitlab::ServiceDesk.supported == true @@ -252,7 +252,7 @@ RSpec.describe 'Service Desk Issue Tracker', :js, feature_category: :service_des end it 'shows service_desk_reply_to in issues list' do - expect(page).to have_text('by GitLab Support Bot') + expect(page).to have_text('by service.desk@example.com via GitLab Support Bot') end end end diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb index 2c537cefa5e..c503c18be8d 100644 --- a/spec/features/issues/todo_spec.rb +++ b/spec/features/issues/todo_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Manually create a todo item from issue', :js, feature_category: :team_planning do let!(:project) { create(:project) } let!(:issue) { create(:issue, project: project) } - let!(:user) { create(:user) } + let!(:user) { create(:user, :no_super_sidebar) } before do project.add_maintainer(user) diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index 76b07d903bc..857cb1f39a2 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -16,7 +16,7 @@ RSpec.describe "User creates issue", feature_category: :team_planning do sign_out(:user) end - it "redirects to signin then back to new issue after signin", :js, quarantine: 'https://gitlab.com/gitlab-org/quality/engineering-productivity/master-broken-incidents/-/issues/1486' do + it "redirects to signin then back to new issue after signin", :js do create(:issue, project: project) visit project_issues_path(project) diff --git a/spec/features/issues/user_sees_live_update_spec.rb b/spec/features/issues/user_sees_live_update_spec.rb index 860603ad546..0822542ca02 100644 --- a/spec/features/issues/user_sees_live_update_spec.rb +++ b/spec/features/issues/user_sees_live_update_spec.rb @@ -19,34 +19,32 @@ RSpec.describe 'Issues > User sees live update', :js, feature_category: :team_pl expect(page).to have_text("new title") issue.update!(title: "updated title") - wait_for_requests + expect(page).to have_text("updated title") end end describe 'confidential issue#show' do - it 'shows confidential sibebar information as confidential and can be turned off', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/254644' do + it 'shows confidential sidebar information as confidential and can be turned off' do issue = create(:issue, :confidential, project: project) visit project_issue_path(project, issue) - expect(page).to have_css('.issuable-note-warning') - expect(find('.issuable-sidebar-item.confidentiality')).to have_css('.is-active') - expect(find('.issuable-sidebar-item.confidentiality')).not_to have_css('.not-active') - - find('.confidential-edit').click - expect(page).to have_css('.sidebar-item-warning-message') + expect(page).to have_text('This is a confidential issue. People without permission will never get a notification.') - within('.sidebar-item-warning-message') do - find('[data-testid="confidential-toggle"]').click + within '.block.confidentiality' do + click_button 'Edit' end - wait_for_requests + expect(page).to have_text('You are going to turn off the confidentiality. This means everyone will be able to see and leave a comment on this issue.') + + click_button 'Turn off' visit project_issue_path(project, issue) - expect(page).not_to have_css('.is-active') + expect(page).not_to have_css('.gl-badge', text: 'Confidential') + expect(page).not_to have_text('This is a confidential issue. People without permission will never get a notification.') end end end diff --git a/spec/features/issues/user_uses_quick_actions_spec.rb b/spec/features/issues/user_uses_quick_actions_spec.rb index dc149ccc698..c15716243ae 100644 --- a/spec/features/issues/user_uses_quick_actions_spec.rb +++ b/spec/features/issues/user_uses_quick_actions_spec.rb @@ -13,7 +13,7 @@ RSpec.describe 'Issues > User uses quick actions', :js, feature_category: :team_ context "issuable common quick actions" do let(:new_url_opts) { {} } - let(:maintainer) { create(:user) } + let(:maintainer) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :public) } let!(:label_bug) { create(:label, project: project, title: 'bug') } let!(:label_feature) { create(:label, project: project, title: 'feature') } @@ -26,7 +26,7 @@ RSpec.describe 'Issues > User uses quick actions', :js, feature_category: :team_ end describe 'issue-only commands' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :public, :repository) } let(:issue) { create(:issue, project: project, due_date: Date.new(2016, 8, 28)) } diff --git a/spec/features/jira_connect/branches_spec.rb b/spec/features/jira_connect/branches_spec.rb index 25dc14a1dc9..ae1dd551c47 100644 --- a/spec/features/jira_connect/branches_spec.rb +++ b/spec/features/jira_connect/branches_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integrations do include ListboxHelpers - let_it_be(:alice) { create(:user, name: 'Alice') } - let_it_be(:bob) { create(:user, name: 'Bob') } + let_it_be(:alice) { create(:user, :no_super_sidebar, name: 'Alice') } + let_it_be(:bob) { create(:user, :no_super_sidebar, name: 'Bob') } let_it_be(:project1) { create(:project, :repository, namespace: alice.namespace, title: 'foo') } let_it_be(:project2) { create(:project, :repository, namespace: alice.namespace, title: 'bar') } diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb index eb79d6e64f3..0cb712622f2 100644 --- a/spec/features/labels_hierarchy_spec.rb +++ b/spec/features/labels_hierarchy_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'Labels Hierarchy', :js, feature_category: :team_planning do include FilteredSearchHelpers include ContentEditorHelpers - let!(:user) { create(:user) } + let!(:user) { create(:user, :no_super_sidebar) } let!(:grandparent) { create(:group) } let!(:parent) { create(:group, parent: grandparent) } let!(:child) { create(:group, parent: parent) } diff --git a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb index 446f6a470de..fea4841c5ea 100644 --- a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb +++ b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' -RSpec.describe 'User closes/reopens a merge request', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297500', - feature_category: :code_review_workflow do +RSpec.describe 'User closes/reopens a merge request', :js, feature_category: :code_review_workflow do let_it_be(:project) { create(:project, :repository) } let_it_be(:user) { create(:user) } @@ -13,89 +12,67 @@ RSpec.describe 'User closes/reopens a merge request', :js, quarantine: 'https:// end describe 'when open' do - context 'when clicking the top `Close merge request` link', :aggregate_failures do - let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) } + let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) } - before do - visit merge_request_path(open_merge_request) - end + before do + visit merge_request_path(open_merge_request) + end - it 'can close a merge request' do - expect(find('.status-box')).to have_content 'Open' + context 'when clicking the top `Close merge request` button', :aggregate_failures do + it 'closes the merge request' do + expect(page).to have_css('.gl-badge', text: 'Open') within '.detail-page-header' do - click_button 'Toggle dropdown' - click_link 'Close merge request' + click_button 'Merge request actions' + click_button 'Close merge request' end - wait_for_requests - - expect(find('.status-box')).to have_content 'Closed' + expect(page).to have_css('.gl-badge', text: 'Closed') end end context 'when clicking the bottom `Close merge request` button', :aggregate_failures do - let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) } - - before do - visit merge_request_path(open_merge_request) - end - - it 'can close a merge request' do - expect(find('.status-box')).to have_content 'Open' + it 'closes the merge request' do + expect(page).to have_css('.gl-badge', text: 'Open') within '.timeline-content-form' do click_button 'Close merge request' - - # Clicking the bottom `Close merge request` button does not yet update - # the header status so for now we'll check that the button text changes - expect(page).not_to have_button 'Close merge request' - expect(page).to have_button 'Reopen merge request' end + + expect(page).to have_css('.gl-badge', text: 'Closed') end end end describe 'when closed' do - context 'when clicking the top `Reopen merge request` link', :aggregate_failures do - let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') } + let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') } - before do - visit merge_request_path(closed_merge_request) - end + before do + visit merge_request_path(closed_merge_request) + end - it 'can reopen a merge request' do - expect(find('.status-box')).to have_content 'Closed' + context 'when clicking the top `Reopen merge request` button', :aggregate_failures do + it 'reopens the merge request' do + expect(page).to have_css('.gl-badge', text: 'Closed') within '.detail-page-header' do - click_button 'Toggle dropdown' - click_link 'Reopen merge request' + click_button 'Merge request actions' + click_button 'Reopen merge request' end - wait_for_requests - - expect(find('.status-box')).to have_content 'Open' + expect(page).to have_css('.gl-badge', text: 'Open') end end context 'when clicking the bottom `Reopen merge request` button', :aggregate_failures do - let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') } - - before do - visit merge_request_path(closed_merge_request) - end - - it 'can reopen a merge request' do - expect(find('.status-box')).to have_content 'Closed' + it 'reopens the merge request' do + expect(page).to have_css('.gl-badge', text: 'Closed') within '.timeline-content-form' do click_button 'Reopen merge request' - - # Clicking the bottom `Reopen merge request` button does not yet update - # the header status so for now we'll check that the button text changes - expect(page).not_to have_button 'Reopen merge request' - expect(page).to have_button 'Close merge request' end + + expect(page).to have_css('.gl-badge', text: 'Open') end end end diff --git a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb index a96ec1f68aa..df39fe492c1 100644 --- a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb +++ b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb @@ -48,7 +48,8 @@ RSpec.describe 'Batch diffs', :js, feature_category: :code_review_workflow do context 'when user visits a URL with a link directly to to a discussion' do context 'which is in the first batched page of diffs' do - it 'scrolls to the correct discussion' do + it 'scrolls to the correct discussion', + quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/410029' } do page.within get_first_diff do click_link('just now') end diff --git a/spec/features/merge_request/user_merges_merge_request_spec.rb b/spec/features/merge_request/user_merges_merge_request_spec.rb index 402405e1fb6..aee42784d05 100644 --- a/spec/features/merge_request/user_merges_merge_request_spec.rb +++ b/spec/features/merge_request/user_merges_merge_request_spec.rb @@ -5,7 +5,7 @@ require "spec_helper" RSpec.describe "User merges a merge request", :js, feature_category: :code_review_workflow do include ContentEditorHelpers - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) @@ -24,7 +24,7 @@ RSpec.describe "User merges a merge request", :js, feature_category: :code_revie end context 'sidebar merge requests counter' do - let(:project) { create(:project, :public, :repository) } + let_it_be(:project) { create(:project, :public, :repository, namespace: user.namespace) } let!(:merge_request) { create(:merge_request, source_project: project) } it 'decrements the open MR count', :sidekiq_inline do diff --git a/spec/features/merge_request/user_opens_checkout_branch_modal_spec.rb b/spec/features/merge_request/user_opens_checkout_branch_modal_spec.rb index 63f03ae64e0..c12816b6521 100644 --- a/spec/features/merge_request/user_opens_checkout_branch_modal_spec.rb +++ b/spec/features/merge_request/user_opens_checkout_branch_modal_spec.rb @@ -6,17 +6,16 @@ RSpec.describe 'Merge request > User opens checkout branch modal', :js, feature_ include ProjectForksHelper include CookieHelper - let(:project) { create(:project, :public, :repository) } - let(:user) { project.creator } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :public, :repository, namespace: user.namespace) } before do - project.add_maintainer(user) sign_in(user) set_cookie('new-actions-popover-viewed', 'true') end describe 'for fork' do - let(:author) { create(:user) } + let(:author) { create(:user, :no_super_sidebar) } let(:source_project) { fork_project(project, author, repository: true) } let(:merge_request) do diff --git a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb index 21c62b0d0d8..e55ecd2a531 100644 --- a/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb +++ b/spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe 'Merge request > User sees check out branch modal', :js, feature_category: :code_review_workflow do include CookieHelper - let(:project) { create(:project, :public, :repository) } - let(:user) { project.creator } - let(:merge_request) { create(:merge_request, source_project: project) } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :public, :repository, creator: user) } + let_it_be(:merge_request) { create(:merge_request, source_project: project) } let(:modal_window_title) { 'Check out, review, and resolve locally' } before do diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb index d237faba663..dd1119c5648 100644 --- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb +++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb @@ -119,37 +119,6 @@ RSpec.describe 'Merge request > User sees deployment widget', :js, feature_categ end before do - stub_feature_flags(review_apps_redeploy_mr_widget: false) - build.success! - deployment.update!(on_stop: manual.name) - visit project_merge_request_path(project, merge_request) - wait_for_requests - end - - it 'does start build when stop button clicked' do - accept_gl_confirm(button_text: 'Stop environment') do - find('.js-stop-env').click - end - - expect(page).to have_content('close_app') - end - - context 'for reporter' do - let(:role) { :reporter } - - it 'does not show stop button' do - expect(page).not_to have_selector('.js-stop-env') - end - end - end - - context 'with stop action with the review_apps_redeploy_mr_widget feature flag turned on' do - let(:manual) do - create(:ci_build, :manual, pipeline: pipeline, name: 'close_app', environment: environment.name) - end - - before do - stub_feature_flags(review_apps_redeploy_mr_widget: true) build.success! deployment.update!(on_stop: manual.name) visit project_merge_request_path(project, merge_request) @@ -173,9 +142,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js, feature_categ end end - context 'with redeploy action and with the review_apps_redeploy_mr_widget feature flag turned on' do + context 'with redeploy action' do before do - stub_feature_flags(review_apps_redeploy_mr_widget: true) build.success! environment.update!(state: 'stopped') visit project_merge_request_path(project, merge_request) diff --git a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb index add8e9f30de..e052d06c158 100644 --- a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb +++ b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb @@ -48,60 +48,29 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request', end # rubocop:enable RSpec/AvoidConditionalStatements - context 'when a user created a merge request in the parent project' do - let!(:merge_request) do - create( - :merge_request, - source_project: project, - target_project: project, - source_branch: 'feature', - target_branch: 'master' - ) - end - - let!(:push_pipeline) do - Ci::CreatePipelineService.new(project, user, ref: 'feature') - .execute(:push) - .payload - end - - let!(:detached_merge_request_pipeline) do - Ci::CreatePipelineService.new(project, user, ref: 'feature') - .execute(:merge_request_event, merge_request: merge_request) - .payload - end - + context 'with feature flag `mr_pipelines_graphql turned off`' do before do - visit project_merge_request_path(project, merge_request) - - page.within('.merge-request-tabs') do - click_link('Pipelines') - end - end - - it 'sees branch pipelines and detached merge request pipelines in correct order' do - page.within('.ci-table') do - expect(page).to have_selector('[data-testid="ci-badge-created"]', count: 2) - expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{detached_merge_request_pipeline.id}") - end + stub_feature_flags(mr_pipelines_graphql: false) end - it 'sees the latest detached merge request pipeline as the head pipeline', :sidekiq_might_not_need_inline do - click_link "Overview" - - page.within('.ci-widget-content') do - expect(page).to have_content("##{detached_merge_request_pipeline.id}") + context 'when a user created a merge request in the parent project' do + let!(:merge_request) do + create( + :merge_request, + source_project: project, + target_project: project, + source_branch: 'feature', + target_branch: 'master' + ) end - end - context 'when a user updated a merge request in the parent project', :sidekiq_might_not_need_inline do - let!(:push_pipeline_2) do + let!(:push_pipeline) do Ci::CreatePipelineService.new(project, user, ref: 'feature') .execute(:push) .payload end - let!(:detached_merge_request_pipeline_2) do + let!(:detached_merge_request_pipeline) do Ci::CreatePipelineService.new(project, user, ref: 'feature') .execute(:merge_request_event, merge_request: merge_request) .payload @@ -117,192 +86,184 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request', it 'sees branch pipelines and detached merge request pipelines in correct order' do page.within('.ci-table') do - expect(page).to have_selector('[data-testid="ci-badge-pending"]', count: 4) - - expect(all('[data-testid="pipeline-url-link"]')[0]) - .to have_content("##{detached_merge_request_pipeline_2.id}") - - expect(all('[data-testid="pipeline-url-link"]')[1]) - .to have_content("##{detached_merge_request_pipeline.id}") + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'created', count: 2) + expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{detached_merge_request_pipeline.id}") + end + end - expect(all('[data-testid="pipeline-url-link"]')[2]) - .to have_content("##{push_pipeline_2.id}") + it 'sees the latest detached merge request pipeline as the head pipeline', :sidekiq_might_not_need_inline do + click_link "Overview" - expect(all('[data-testid="pipeline-url-link"]')[3]) - .to have_content("##{push_pipeline.id}") + page.within('.ci-widget-content') do + expect(page).to have_content("##{detached_merge_request_pipeline.id}") end end - it 'sees detached tag for detached merge request pipelines' do - page.within('.ci-table') do - expect(all('.pipeline-tags')[0]) - .to have_content(expected_detached_mr_tag) + context 'when a user updated a merge request in the parent project', :sidekiq_might_not_need_inline do + let!(:push_pipeline_2) do + Ci::CreatePipelineService.new(project, user, ref: 'feature') + .execute(:push) + .payload + end - expect(all('.pipeline-tags')[1]) - .to have_content(expected_detached_mr_tag) + let!(:detached_merge_request_pipeline_2) do + Ci::CreatePipelineService.new(project, user, ref: 'feature') + .execute(:merge_request_event, merge_request: merge_request) + .payload + end - expect(all('.pipeline-tags')[2]) - .not_to have_content(expected_detached_mr_tag) + before do + visit project_merge_request_path(project, merge_request) - expect(all('.pipeline-tags')[3]) - .not_to have_content(expected_detached_mr_tag) + page.within('.merge-request-tabs') do + click_link('Pipelines') + end end - end - it 'sees the latest detached merge request pipeline as the head pipeline' do - click_link 'Overview' + it 'sees branch pipelines and detached merge request pipelines in correct order' do + page.within('.ci-table') do + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending', count: 4) - page.within('.ci-widget-content') do - expect(page).to have_content("##{detached_merge_request_pipeline_2.id}") + expect(all('[data-testid="pipeline-url-link"]')[0]) + .to have_content("##{detached_merge_request_pipeline_2.id}") + + expect(all('[data-testid="pipeline-url-link"]')[1]) + .to have_content("##{detached_merge_request_pipeline.id}") + + expect(all('[data-testid="pipeline-url-link"]')[2]) + .to have_content("##{push_pipeline_2.id}") + + expect(all('[data-testid="pipeline-url-link"]')[3]) + .to have_content("##{push_pipeline.id}") + end end - end - end - context 'when a user created a merge request in the parent project' do - before do - visit project_merge_request_path(project, merge_request) + it 'sees detached tag for detached merge request pipelines' do + page.within('.ci-table') do + expect(all('.pipeline-tags')[0]) + .to have_content(expected_detached_mr_tag) - page.within('.merge-request-tabs') do - click_link('Pipelines') + expect(all('.pipeline-tags')[1]) + .to have_content(expected_detached_mr_tag) + + expect(all('.pipeline-tags')[2]) + .not_to have_content(expected_detached_mr_tag) + + expect(all('.pipeline-tags')[3]) + .not_to have_content(expected_detached_mr_tag) + end end - end - context 'when a user merges a merge request in the parent project', :sidekiq_might_not_need_inline do - before do + it 'sees the latest detached merge request pipeline as the head pipeline' do click_link 'Overview' - click_button 'Set to auto-merge' - wait_for_requests + page.within('.ci-widget-content') do + expect(page).to have_content("##{detached_merge_request_pipeline_2.id}") + end end + end - context 'when detached merge request pipeline is pending' do - it 'waits the head pipeline' do - expect(page).to have_content mr_widget_title - expect(page).to have_button('Cancel auto-merge') + context 'when a user created a merge request in the parent project' do + before do + visit project_merge_request_path(project, merge_request) + + page.within('.merge-request-tabs') do + click_link('Pipelines') end end - context 'when branch pipeline succeeds' do + context 'when a user merges a merge request in the parent project', :sidekiq_might_not_need_inline do before do click_link 'Overview' - push_pipeline.reload.succeed! + click_button 'Set to auto-merge' wait_for_requests end - it 'waits the head pipeline' do - expect(page).to have_content mr_widget_title - expect(page).to have_button('Cancel auto-merge') + context 'when detached merge request pipeline is pending' do + it 'waits the head pipeline' do + expect(page).to have_content mr_widget_title + expect(page).to have_button('Cancel auto-merge') + end end - end - end - end - context 'when there are no `merge_requests` keyword in .gitlab-ci.yml' do - let(:config) do - { - build: { - script: 'build' - }, - test: { - script: 'test' - }, - deploy: { - script: 'deploy' - } - } - end - - it 'sees a branch pipeline in pipeline tab' do - page.within('.ci-table') do - expect(page).to have_selector('[data-testid="ci-badge-created"]', count: 1) - expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{push_pipeline.id}") - end - end + context 'when branch pipeline succeeds' do + before do + click_link 'Overview' + push_pipeline.reload.succeed! - it 'sees the latest branch pipeline as the head pipeline', :sidekiq_might_not_need_inline do - click_link 'Overview' + wait_for_requests + end - page.within('.ci-widget-content') do - expect(page).to have_content("##{push_pipeline.id}") + it 'waits the head pipeline' do + expect(page).to have_content mr_widget_title + expect(page).to have_button('Cancel auto-merge') + end + end end end - end - end - - context 'when a user created a merge request from a forked project to the parent project', :sidekiq_might_not_need_inline do - let(:merge_request) do - create( - :merge_request, - source_project: forked_project, - target_project: project, - source_branch: 'feature', - target_branch: 'master' - ) - end - - let!(:push_pipeline) do - Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature') - .execute(:push) - .payload - end - - let!(:detached_merge_request_pipeline) do - Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature') - .execute(:merge_request_event, merge_request: merge_request) - .payload - end - let(:forked_project) { fork_project(project, user2, repository: true) } - let(:user2) { create(:user) } - - before do - forked_project.add_maintainer(user2) - - stub_feature_flags(auto_merge_labels_mr_widget: false) + context 'when there are no `merge_requests` keyword in .gitlab-ci.yml' do + let(:config) do + { + build: { + script: 'build' + }, + test: { + script: 'test' + }, + deploy: { + script: 'deploy' + } + } + end - visit project_merge_request_path(project, merge_request) + it 'sees a branch pipeline in pipeline tab' do + page.within('.ci-table') do + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'created', count: 1) + expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{push_pipeline.id}") + end + end - page.within('.merge-request-tabs') do - click_link('Pipelines') - end - end + it 'sees the latest branch pipeline as the head pipeline', :sidekiq_might_not_need_inline do + click_link 'Overview' - it 'sees branch pipelines and detached merge request pipelines in correct order' do - page.within('.ci-table') do - expect(page).to have_selector('[data-testid="ci-badge-pending"]', count: 2) - expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{detached_merge_request_pipeline.id}") + page.within('.ci-widget-content') do + expect(page).to have_content("##{push_pipeline.id}") + end + end end end - it 'sees the latest detached merge request pipeline as the head pipeline' do - click_link "Overview" - - page.within('.ci-widget-content') do - expect(page).to have_content("##{detached_merge_request_pipeline.id}") + context 'when a user created a merge request from a forked project to the parent project', :sidekiq_might_not_need_inline do + let(:merge_request) do + create( + :merge_request, + source_project: forked_project, + target_project: project, + source_branch: 'feature', + target_branch: 'master' + ) end - end - it 'sees pipeline list in forked project' do - visit project_pipelines_path(forked_project) - - expect(page).to have_selector('[data-testid="ci-badge-pending"]', count: 2) - end - - context 'when a user updated a merge request from a forked project to the parent project' do - let!(:push_pipeline_2) do + let!(:push_pipeline) do Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature') .execute(:push) .payload end - let!(:detached_merge_request_pipeline_2) do + let!(:detached_merge_request_pipeline) do Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature') .execute(:merge_request_event, merge_request: merge_request) .payload end + let(:forked_project) { fork_project(project, user2, repository: true) } + let(:user2) { create(:user) } + before do + forked_project.add_maintainer(user2) + visit project_merge_request_path(project, merge_request) page.within('.merge-request-tabs') do @@ -312,35 +273,8 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request', it 'sees branch pipelines and detached merge request pipelines in correct order' do page.within('.ci-table') do - expect(page).to have_selector('[data-testid="ci-badge-pending"]', count: 4) - - expect(all('[data-testid="pipeline-url-link"]')[0]) - .to have_content("##{detached_merge_request_pipeline_2.id}") - - expect(all('[data-testid="pipeline-url-link"]')[1]) - .to have_content("##{detached_merge_request_pipeline.id}") - - expect(all('[data-testid="pipeline-url-link"]')[2]) - .to have_content("##{push_pipeline_2.id}") - - expect(all('[data-testid="pipeline-url-link"]')[3]) - .to have_content("##{push_pipeline.id}") - end - end - - it 'sees detached tag for detached merge request pipelines' do - page.within('.ci-table') do - expect(all('.pipeline-tags')[0]) - .to have_content(expected_detached_mr_tag) - - expect(all('.pipeline-tags')[1]) - .to have_content(expected_detached_mr_tag) - - expect(all('.pipeline-tags')[2]) - .not_to have_content(expected_detached_mr_tag) - - expect(all('.pipeline-tags')[3]) - .not_to have_content(expected_detached_mr_tag) + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending', count: 2) + expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{detached_merge_request_pipeline.id}") end end @@ -348,88 +282,158 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request', click_link "Overview" page.within('.ci-widget-content') do - expect(page).to have_content("##{detached_merge_request_pipeline_2.id}") + expect(page).to have_content("##{detached_merge_request_pipeline.id}") end end it 'sees pipeline list in forked project' do visit project_pipelines_path(forked_project) - expect(page).to have_selector('[data-testid="ci-badge-pending"]', count: 4) + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending', count: 2) end - end - context 'when the latest pipeline is running in the parent project' do - before do - create(:ci_pipeline, - source: :merge_request_event, - project: project, - ref: 'feature', - sha: merge_request.diff_head_sha, - user: user, - merge_request: merge_request, - status: :running) - merge_request.update_head_pipeline - end + context 'when a user updated a merge request from a forked project to the parent project' do + let!(:push_pipeline_2) do + Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature') + .execute(:push) + .payload + end + + let!(:detached_merge_request_pipeline_2) do + Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature') + .execute(:merge_request_event, merge_request: merge_request) + .payload + end - context 'when the previous pipeline failed in the fork project' do before do - detached_merge_request_pipeline.reload.drop! + visit project_merge_request_path(project, merge_request) + + page.within('.merge-request-tabs') do + click_link('Pipelines') + end end - context 'when the parent project enables pipeline must succeed' do - before do - project.update!(only_allow_merge_if_pipeline_succeeds: true) + it 'sees branch pipelines and detached merge request pipelines in correct order' do + page.within('.ci-table') do + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending', count: 4) + + expect(all('[data-testid="pipeline-url-link"]')[0]) + .to have_content("##{detached_merge_request_pipeline_2.id}") + + expect(all('[data-testid="pipeline-url-link"]')[1]) + .to have_content("##{detached_merge_request_pipeline.id}") + + expect(all('[data-testid="pipeline-url-link"]')[2]) + .to have_content("##{push_pipeline_2.id}") + + expect(all('[data-testid="pipeline-url-link"]')[3]) + .to have_content("##{push_pipeline.id}") end + end + + it 'sees detached tag for detached merge request pipelines' do + page.within('.ci-table') do + expect(all('.pipeline-tags')[0]) + .to have_content(expected_detached_mr_tag) + + expect(all('.pipeline-tags')[1]) + .to have_content(expected_detached_mr_tag) - it 'shows Set to auto-merge button' do - visit project_merge_request_path(project, merge_request) + expect(all('.pipeline-tags')[2]) + .not_to have_content(expected_detached_mr_tag) - expect(page).to have_button('Set to auto-merge') + expect(all('.pipeline-tags')[3]) + .not_to have_content(expected_detached_mr_tag) end end - end - end - context 'when a user merges a merge request from a forked project to the parent project' do - before do - click_link("Overview") + it 'sees the latest detached merge request pipeline as the head pipeline' do + click_link "Overview" - click_button 'Set to auto-merge' + page.within('.ci-widget-content') do + expect(page).to have_content("##{detached_merge_request_pipeline_2.id}") + end + end - wait_for_requests - end + it 'sees pipeline list in forked project' do + visit project_pipelines_path(forked_project) - context 'when detached merge request pipeline is pending' do - it 'waits the head pipeline' do - expect(page).to have_content mr_widget_title - expect(page).to have_button('Cancel auto-merge') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending', count: 4) end end - context 'when detached merge request pipeline succeeds' do + context 'when the latest pipeline is running in the parent project' do before do - detached_merge_request_pipeline.reload.succeed! - - refresh + create(:ci_pipeline, + source: :merge_request_event, + project: project, + ref: 'feature', + sha: merge_request.diff_head_sha, + user: user, + merge_request: merge_request, + status: :running) + merge_request.update_head_pipeline end - it 'merges the merge request' do - expect(page).to have_content('Merged by') - expect(page).to have_button('Revert') + context 'when the previous pipeline failed in the fork project' do + before do + detached_merge_request_pipeline.reload.drop! + end + + context 'when the parent project enables pipeline must succeed' do + before do + project.update!(only_allow_merge_if_pipeline_succeeds: true) + end + + it 'shows Set to auto-merge button' do + visit project_merge_request_path(project, merge_request) + + expect(page).to have_button('Set to auto-merge') + end + end end end - context 'when branch pipeline succeeds' do + context 'when a user merges a merge request from a forked project to the parent project' do before do - push_pipeline.reload.succeed! + click_link("Overview") + + click_button 'Set to auto-merge' wait_for_requests end - it 'waits the head pipeline' do - expect(page).to have_content mr_widget_title - expect(page).to have_button('Cancel auto-merge') + context 'when detached merge request pipeline is pending' do + it 'waits the head pipeline' do + expect(page).to have_content mr_widget_title + expect(page).to have_button('Cancel auto-merge') + end + end + + context 'when detached merge request pipeline succeeds' do + before do + detached_merge_request_pipeline.reload.succeed! + + wait_for_requests + end + + it 'merges the merge request' do + expect(page).to have_content('Merged by') + expect(page).to have_button('Revert') + end + end + + context 'when branch pipeline succeeds' do + before do + push_pipeline.reload.succeed! + + wait_for_requests + end + + it 'waits the head pipeline' do + expect(page).to have_content mr_widget_title + expect(page).to have_button('Cancel auto-merge') + end end end end diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb index 75df93d1a6c..1db09790e1c 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -646,7 +646,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_expand_button within('[data-testid="widget-extension-collapsed-section"]') do - click_link 'addTest' + click_button 'View details' end end @@ -693,7 +693,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_expand_button within('[data-testid="widget-extension-collapsed-section"]') do - click_link 'Test#sum when a is 1 and b is 3 returns summary' + click_button 'View details' end end @@ -741,7 +741,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_expand_button within('[data-testid="widget-extension-collapsed-section"]') do - click_link 'addTest' + click_button 'View details' end end @@ -788,7 +788,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_expand_button within('[data-testid="widget-extension-collapsed-section"]') do - click_link 'addTest' + click_button 'View details' end end @@ -834,7 +834,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_expand_button within('[data-testid="widget-extension-collapsed-section"]') do - click_link 'Test#sum when a is 4 and b is 4 returns summary' + click_button 'View details' end end @@ -881,7 +881,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_expand_button within('[data-testid="widget-extension-collapsed-section"]') do - click_link 'addTest' + click_button 'View details' end end @@ -958,4 +958,21 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: end end end + + context 'views MR when pipeline has code coverage enabled' do + let!(:pipeline) { create(:ci_pipeline, status: 'success', project: project, ref: merge_request.source_branch) } + let!(:build) { create(:ci_build, :success, :coverage, pipeline: pipeline) } + + before do + merge_request.update!(head_pipeline: pipeline) + + visit project_merge_request_path(project, merge_request) + end + + it 'shows the coverage' do + within '.ci-widget' do + expect(find_by_testid('pipeline-coverage')).to have_content('Test coverage 99.90% ') + end + end + end end diff --git a/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb b/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb index 5801e8a1a11..77cd116ecc9 100644 --- a/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb +++ b/spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb @@ -30,15 +30,33 @@ RSpec.describe 'Merge request > User sees pipelines from forked project', :js, before do create(:ci_build, pipeline: pipeline, name: 'rspec') create(:ci_build, pipeline: pipeline, name: 'spinach') - sign_in(user) - visit project_merge_request_path(target_project, merge_request) end - it 'user visits a pipelines page', :sidekiq_might_not_need_inline do - page.within('.merge-request-tabs') { click_link 'Pipelines' } + context 'with feature flag `mr_pipelines_graphql` turned off' do + before do + stub_feature_flags(mr_pipelines_graphql: false) + visit project_merge_request_path(target_project, merge_request) + end + + it 'user visits a pipelines page', :sidekiq_might_not_need_inline do + page.within('.merge-request-tabs') { click_link 'Pipelines' } + + page.within('.ci-table') do + expect(page).to have_content(pipeline.id) + end + end + end + + context 'with feature flag `mr_pipelines_graphql` turned on' do + before do + stub_feature_flags(mr_pipelines_graphql: true) + visit project_merge_request_path(target_project, merge_request) + end + + it 'user visits a pipelines page', :sidekiq_might_not_need_inline do + page.within('.merge-request-tabs') { click_link 'Pipelines' } - page.within('.ci-table') do expect(page).to have_content(pipeline.id) end end diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb index 5ce919fe2e6..bb3890f5242 100644 --- a/spec/features/merge_request/user_sees_pipelines_spec.rb +++ b/spec/features/merge_request/user_sees_pipelines_spec.rb @@ -3,285 +3,291 @@ require 'spec_helper' RSpec.describe 'Merge request > User sees pipelines', :js, feature_category: :code_review_workflow do - describe 'pipeline tab' do - let(:merge_request) { create(:merge_request) } - let(:project) { merge_request.target_project } - let(:user) { project.creator } - + context 'with feature flag `mr_pipelines_graphql turned off`' do before do - project.add_maintainer(user) - sign_in(user) + stub_feature_flags(mr_pipelines_graphql: false) end - context 'with pipelines' do - let!(:pipeline) do - create( - :ci_pipeline, - :success, - project: merge_request.source_project, - ref: merge_request.source_branch, - sha: merge_request.diff_head_sha - ) - end - - let!(:manual_job) { create(:ci_build, :manual, name: 'job1', stage: 'deploy', pipeline: pipeline) } - - let!(:job) { create(:ci_build, :success, name: 'job2', stage: 'test', pipeline: pipeline) } + describe 'pipeline tab' do + let(:merge_request) { create(:merge_request) } + let(:project) { merge_request.target_project } + let(:user) { project.creator } before do - merge_request.update_attribute(:head_pipeline_id, pipeline.id) + project.add_maintainer(user) + sign_in(user) end - it 'pipelines table displays correctly' do - visit project_merge_request_path(project, merge_request) - - expect(page.find('.ci-widget')).to have_content('passed') - - page.within('.merge-request-tabs') do - click_link('Pipelines') + context 'with pipelines' do + let!(:pipeline) do + create( + :ci_pipeline, + :success, + project: merge_request.source_project, + ref: merge_request.source_branch, + sha: merge_request.diff_head_sha + ) end - wait_for_requests + let!(:manual_job) { create(:ci_build, :manual, name: 'job1', stage: 'deploy', pipeline: pipeline) } - page.within(find('[data-testid="pipeline-table-row"]', match: :first)) do - expect(page).to have_selector('[data-testid="ci-badge-passed"]') - expect(page).to have_content(pipeline.id) - expect(page).to have_content('API') - expect(page).to have_css('[data-testid="pipeline-mini-graph"]') - expect(page).to have_css('[data-testid="pipelines-manual-actions-dropdown"]') - expect(page).to have_css('[data-testid="pipeline-multi-actions-dropdown"]') - end - end + let!(:job) { create(:ci_build, :success, name: 'job2', stage: 'test', pipeline: pipeline) } - context 'with a detached merge request pipeline' do - let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) } + before do + merge_request.update_attribute(:head_pipeline_id, pipeline.id) + end - it 'displays the "Run pipeline" button' do + it 'pipelines table displays correctly' do visit project_merge_request_path(project, merge_request) + expect(page.find('.ci-widget')).to have_content('passed') + page.within('.merge-request-tabs') do click_link('Pipelines') end wait_for_requests - expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') + page.within(find('[data-testid="pipeline-table-row"]', match: :first)) do + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'passed') + expect(page).to have_content(pipeline.id) + expect(page).to have_content('API') + expect(page).to have_css('[data-testid="pipeline-mini-graph"]') + expect(page).to have_css('[data-testid="pipelines-manual-actions-dropdown"]') + expect(page).to have_css('[data-testid="pipeline-multi-actions-dropdown"]') + end end - end - context 'with a merged results pipeline' do - let(:merge_request) { create(:merge_request, :with_merge_request_pipeline) } + context 'with a detached merge request pipeline' do + let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) } - it 'displays the "Run pipeline" button' do - visit project_merge_request_path(project, merge_request) + it 'displays the "Run pipeline" button' do + visit project_merge_request_path(project, merge_request) - page.within('.merge-request-tabs') do - click_link('Pipelines') - end + page.within('.merge-request-tabs') do + click_link('Pipelines') + end - wait_for_requests + wait_for_requests - expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') + expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') + end end - end - end - context 'without pipelines' do - before do - visit project_merge_request_path(project, merge_request) - end + context 'with a merged results pipeline' do + let(:merge_request) { create(:merge_request, :with_merge_request_pipeline) } + + it 'displays the "Run pipeline" button' do + visit project_merge_request_path(project, merge_request) + + page.within('.merge-request-tabs') do + click_link('Pipelines') + end + + wait_for_requests - it 'user visits merge request page' do - page.within('.merge-request-tabs') do - expect(page).to have_link('Pipelines') + expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') + end end end - it 'shows empty state with run pipeline button' do - page.within('.merge-request-tabs') do - click_link('Pipelines') + context 'without pipelines' do + before do + visit project_merge_request_path(project, merge_request) end - expect(page).to have_content('There are currently no pipelines.') - expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') - end - end - end + it 'user visits merge request page' do + page.within('.merge-request-tabs') do + expect(page).to have_link('Pipelines') + end + end - describe 'fork MRs in parent project', :sidekiq_inline do - include ProjectForksHelper - - let_it_be(:parent_project) { create(:project, :public, :repository) } - let_it_be(:forked_project) { fork_project(parent_project, developer_in_fork, repository: true, target_project: create(:project, :public, :repository)) } - let_it_be(:developer_in_parent) { create(:user) } - let_it_be(:developer_in_fork) { create(:user) } - let_it_be(:reporter_in_parent_and_developer_in_fork) { create(:user) } - - let(:merge_request) do - create( - :merge_request, - :with_detached_merge_request_pipeline, - source_project: forked_project, - source_branch: 'feature', - target_project: parent_project, - target_branch: 'master' - ) - end + it 'shows empty state with run pipeline button' do + page.within('.merge-request-tabs') do + click_link('Pipelines') + end - let(:config) do - { test: { script: 'test', rules: [{ if: '$CI_MERGE_REQUEST_ID' }] } } + expect(page).to have_content('There are currently no pipelines.') + expect(page.find('[data-testid="run_pipeline_button"]')).to have_text('Run pipeline') + end + end end - before_all do - parent_project.add_developer(developer_in_parent) - parent_project.add_reporter(reporter_in_parent_and_developer_in_fork) - forked_project.add_developer(developer_in_fork) - forked_project.add_developer(reporter_in_parent_and_developer_in_fork) - end + describe 'fork MRs in parent project', :sidekiq_inline do + include ProjectForksHelper - before do - stub_ci_pipeline_yaml_file(YAML.dump(config)) - sign_in(actor) - end + let_it_be(:parent_project) { create(:project, :public, :repository) } + let_it_be(:forked_project) { fork_project(parent_project, developer_in_fork, repository: true, target_project: create(:project, :public, :repository)) } + let_it_be(:developer_in_parent) { create(:user) } + let_it_be(:developer_in_fork) { create(:user) } + let_it_be(:reporter_in_parent_and_developer_in_fork) { create(:user) } - after do - parent_project.all_pipelines.delete_all - forked_project.all_pipelines.delete_all - end + let(:merge_request) do + create( + :merge_request, + :with_detached_merge_request_pipeline, + source_project: forked_project, + source_branch: 'feature', + target_project: parent_project, + target_branch: 'master' + ) + end - context 'when actor is a developer in parent project' do - let(:actor) { developer_in_parent } + let(:config) do + { test: { script: 'test', rules: [{ if: '$CI_MERGE_REQUEST_ID' }] } } + end - it 'creates a pipeline in the parent project when user proceeds with the warning' do - visit project_merge_request_path(parent_project, merge_request) + before_all do + parent_project.add_developer(developer_in_parent) + parent_project.add_reporter(reporter_in_parent_and_developer_in_fork) + forked_project.add_developer(developer_in_fork) + forked_project.add_developer(reporter_in_parent_and_developer_in_fork) + end - create_merge_request_pipeline - act_on_security_warning(action: 'Run pipeline') + before do + stub_ci_pipeline_yaml_file(YAML.dump(config)) + sign_in(actor) + end - check_pipeline(expected_project: parent_project) - check_head_pipeline(expected_project: parent_project) + after do + parent_project.all_pipelines.delete_all + forked_project.all_pipelines.delete_all end - it 'does not create a pipeline in the parent project when user cancels the action', :clean_gitlab_redis_cache, :clean_gitlab_redis_shared_state do - visit project_merge_request_path(parent_project, merge_request) + context 'when actor is a developer in parent project' do + let(:actor) { developer_in_parent } - create_merge_request_pipeline - act_on_security_warning(action: 'Cancel') + it 'creates a pipeline in the parent project when user proceeds with the warning' do + visit project_merge_request_path(parent_project, merge_request) - check_no_new_pipeline_created - end - end + create_merge_request_pipeline + act_on_security_warning(action: 'Run pipeline') - context 'when actor is a developer in fork project' do - let(:actor) { developer_in_fork } + check_pipeline(expected_project: parent_project) + check_head_pipeline(expected_project: parent_project) + end - it 'creates a pipeline in the fork project' do - visit project_merge_request_path(parent_project, merge_request) + it 'does not create a pipeline in the parent project when user cancels the action', :clean_gitlab_redis_cache, :clean_gitlab_redis_shared_state do + visit project_merge_request_path(parent_project, merge_request) - create_merge_request_pipeline + create_merge_request_pipeline + act_on_security_warning(action: 'Cancel') - check_pipeline(expected_project: forked_project) - check_head_pipeline(expected_project: forked_project) + check_no_new_pipeline_created + end end - end - context 'when actor is a reporter in parent project and a developer in fork project' do - let(:actor) { reporter_in_parent_and_developer_in_fork } + context 'when actor is a developer in fork project' do + let(:actor) { developer_in_fork } - it 'creates a pipeline in the fork project' do - visit project_merge_request_path(parent_project, merge_request) + it 'creates a pipeline in the fork project' do + visit project_merge_request_path(parent_project, merge_request) - create_merge_request_pipeline + create_merge_request_pipeline - check_pipeline(expected_project: forked_project) - check_head_pipeline(expected_project: forked_project) + check_pipeline(expected_project: forked_project) + check_head_pipeline(expected_project: forked_project) + end end - end - def create_merge_request_pipeline - page.within('.merge-request-tabs') { click_link('Pipelines') } - click_on('Run pipeline') - end + context 'when actor is a reporter in parent project and a developer in fork project' do + let(:actor) { reporter_in_parent_and_developer_in_fork } - def check_pipeline(expected_project:) - page.within('.ci-table') do - expect(page).to have_selector('[data-testid="pipeline-table-row"]', count: 4) + it 'creates a pipeline in the fork project' do + visit project_merge_request_path(parent_project, merge_request) - page.within(first('[data-testid="pipeline-table-row"]')) do - page.within('.pipeline-tags') do - expect(page.find('[data-testid="pipeline-url-link"]')[:href]).to include(expected_project.full_path) - expect(page).to have_content('merge request') - end - page.within('.pipeline-triggerer') do - expect(page).to have_link(href: user_path(actor)) + create_merge_request_pipeline + + check_pipeline(expected_project: forked_project) + check_head_pipeline(expected_project: forked_project) + end + end + + def create_merge_request_pipeline + page.within('.merge-request-tabs') { click_link('Pipelines') } + click_on('Run pipeline') + end + + def check_pipeline(expected_project:) + page.within('.ci-table') do + expect(page).to have_selector('[data-testid="pipeline-table-row"]', count: 4) + + page.within(first('[data-testid="pipeline-table-row"]')) do + page.within('.pipeline-tags') do + expect(page.find('[data-testid="pipeline-url-link"]')[:href]).to include(expected_project.full_path) + expect(page).to have_content('merge request') + end + page.within('.pipeline-triggerer') do + expect(page).to have_link(href: user_path(actor)) + end end end end - end - def check_head_pipeline(expected_project:) - page.within('.merge-request-tabs') { click_link('Overview') } + def check_head_pipeline(expected_project:) + page.within('.merge-request-tabs') { click_link('Overview') } - page.within('.ci-widget-content') do - expect(page.find('.pipeline-id')[:href]).to include(expected_project.full_path) + page.within('.ci-widget-content') do + expect(page.find('.pipeline-id')[:href]).to include(expected_project.full_path) + end end - end - def act_on_security_warning(action:) - page.within('#create-pipeline-for-fork-merge-request-modal') do - expect(page).to have_content('Are you sure you want to run this pipeline?') - click_button(action) + def act_on_security_warning(action:) + page.within('#create-pipeline-for-fork-merge-request-modal') do + expect(page).to have_content('Are you sure you want to run this pipeline?') + click_button(action) + end end - end - def check_no_new_pipeline_created - page.within('.ci-table') do - expect(page).to have_selector('[data-testid="pipeline-table-row"]', count: 2) + def check_no_new_pipeline_created + page.within('.ci-table') do + expect(page).to have_selector('[data-testid="pipeline-table-row"]', count: 2) + end end end - end - - describe 'race condition' do - let(:project) { create(:project, :repository) } - let(:user) { create(:user) } - let(:build_push_data) { { ref: 'feature', checkout_sha: TestEnv::BRANCH_SHA['feature'] } } - let(:merge_request_params) do - { "source_branch" => "feature", "source_project_id" => project.id, - "target_branch" => "master", "target_project_id" => project.id, "title" => "A" } - end + describe 'race condition' do + let(:project) { create(:project, :repository) } + let(:user) { create(:user) } + let(:build_push_data) { { ref: 'feature', checkout_sha: TestEnv::BRANCH_SHA['feature'] } } - before do - project.add_maintainer(user) - sign_in user - end + let(:merge_request_params) do + { "source_branch" => "feature", "source_project_id" => project.id, + "target_branch" => "master", "target_project_id" => project.id, "title" => "A" } + end - context 'when pipeline and merge request were created simultaneously', :delete do before do - stub_ci_pipeline_to_return_yaml_file + project.add_maintainer(user) + sign_in user + end + + context 'when pipeline and merge request were created simultaneously', :delete do + before do + stub_ci_pipeline_to_return_yaml_file - threads = [] + threads = [] - threads << Thread.new do - Sidekiq::Worker.skipping_transaction_check do - @merge_request = MergeRequests::CreateService.new(project: project, current_user: user, params: merge_request_params).execute + threads << Thread.new do + Sidekiq::Worker.skipping_transaction_check do + @merge_request = MergeRequests::CreateService.new(project: project, current_user: user, params: merge_request_params).execute + end end - end - threads << Thread.new do - Sidekiq::Worker.skipping_transaction_check do - @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push).payload + threads << Thread.new do + Sidekiq::Worker.skipping_transaction_check do + @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push).payload + end end - end - threads.each { |thr| thr.join } - end + threads.each { |thr| thr.join } + end - it 'user sees pipeline in merge request widget', :sidekiq_might_not_need_inline do - visit project_merge_request_path(project, @merge_request) + it 'user sees pipeline in merge request widget', :sidekiq_might_not_need_inline do + visit project_merge_request_path(project, @merge_request) - expect(page.find(".ci-widget")).to have_content(TestEnv::BRANCH_SHA['feature']) - expect(page.find(".ci-widget")).to have_content("##{@pipeline.id}") + expect(page.find(".ci-widget")).to have_content(TestEnv::BRANCH_SHA['feature']) + expect(page.find(".ci-widget")).to have_content("##{@pipeline.id}") + end end end end diff --git a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb index e3be99254dc..16578af238d 100644 --- a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb +++ b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ include ListboxHelpers include CookieHelper - let(:project) { create(:project, :public, :repository) } - let(:user) { project.creator } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :public, :repository, namespace: user.namespace) } def select_source_branch(branch_name) find('.js-source-branch', match: :first).click @@ -16,7 +16,6 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ end before do - project.add_maintainer(user) sign_in(user) set_cookie('new-actions-popover-viewed', 'true') end diff --git a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_sets_to_auto_merge_spec.rb index ebec8a6d2ea..4dc0c03aedc 100644 --- a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_request/user_sets_to_auto_merge_spec.rb @@ -2,7 +2,9 @@ require 'spec_helper' -RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, feature_category: :code_review_workflow do +RSpec.describe 'Merge request > User sets to auto-merge', :js, feature_category: :code_review_workflow do + include ContentEditorHelpers + let(:project) { create(:project, :public, :repository) } let(:user) { project.creator } let(:merge_request) do @@ -32,22 +34,23 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, featur context 'when there is active pipeline for merge request' do before do create(:ci_build, pipeline: pipeline) - stub_feature_flags(auto_merge_labels_mr_widget: true) sign_in(user) visit project_merge_request_path(project, merge_request) end - describe 'enabling Merge when pipeline succeeds' do + describe 'setting to auto-merge when pipeline succeeds' do shared_examples 'Set to auto-merge activator' do - it 'activates the Merge when pipeline succeeds feature', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/410055' do + it 'activates auto-merge feature', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/410055' do + close_rich_text_promo_popover_if_present + expect(page).to have_content 'Set to auto-merge' click_button "Set to auto-merge" + wait_for_requests expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds" expect(page).to have_content "Source branch will not be deleted" expect(page).to have_selector ".js-cancel-auto-merge" - visit project_merge_request_path(project, merge_request) # Needed to refresh the page - expect(page).to have_content /enabled an automatic merge when the pipeline for \h{8} succeeds/i + expect(page).to have_content(/enabled an automatic merge when the pipeline for \h{8} succeeds/i) end end @@ -57,6 +60,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, featur context 'when enabled after it was previously canceled' do before do + close_rich_text_promo_popover_if_present click_button "Set to auto-merge" wait_for_requests @@ -64,14 +68,12 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, featur click_button "Cancel auto-merge" wait_for_requests - - expect(page).to have_content 'Set to auto-merge' end it_behaves_like 'Set to auto-merge activator' end - context 'when it was enabled and then canceled' do + context 'when it is enabled and then canceled' do let(:merge_request) do create( :merge_request_with_diffs, @@ -94,7 +96,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, featur end end - context 'when merge when pipeline succeeds is enabled' do + context 'when there is an active pipeline' do let(:merge_request) do create( :merge_request_with_diffs, @@ -112,12 +114,13 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, featur end before do - stub_feature_flags(auto_merge_labels_mr_widget: true) sign_in user visit project_merge_request_path(project, merge_request) end - it 'allows to cancel the automatic merge', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/410494' do + it 'allows to cancel the auto-merge', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/410055' do + close_rich_text_promo_popover_if_present + click_button "Cancel auto-merge" expect(page).to have_button "Set to auto-merge" @@ -128,22 +131,13 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js, featur end end - context 'when pipeline is not active' do - it 'does not allow to enable merge when pipeline succeeds' do - stub_feature_flags(auto_merge_labels_mr_widget: false) - - visit project_merge_request_path(project, merge_request) - - expect(page).not_to have_link 'Merge when pipeline succeeds' + context 'when there is no active pipeline' do + before do + sign_in user + visit project_merge_request_path(project, merge_request.reload) end - end - - context 'when pipeline is not active and auto_merge_labels_mr_widget on' do - it 'does not allow to enable merge when pipeline succeeds' do - stub_feature_flags(auto_merge_labels_mr_widget: true) - - visit project_merge_request_path(project, merge_request) + it 'does not allow to set to auto-merge' do expect(page).not_to have_link 'Set to auto-merge' end end diff --git a/spec/features/merge_request/user_uses_quick_actions_spec.rb b/spec/features/merge_request/user_uses_quick_actions_spec.rb index 1c63f5b56b0..b2cc25f1c34 100644 --- a/spec/features/merge_request/user_uses_quick_actions_spec.rb +++ b/spec/features/merge_request/user_uses_quick_actions_spec.rb @@ -11,15 +11,9 @@ RSpec.describe 'Merge request > User uses quick actions', :js, :use_clean_rails_ feature_category: :code_review_workflow do include Features::NotesHelpers - let(:project) { create(:project, :public, :repository) } - let(:user) { project.creator } - let(:guest) { create(:user) } - let(:merge_request) { create(:merge_request, source_project: project) } - let!(:milestone) { create(:milestone, project: project, title: 'ASAP') } - context "issuable common quick actions" do let!(:new_url_opts) { { merge_request: { source_branch: 'feature', target_branch: 'master' } } } - let(:maintainer) { create(:user) } + let(:maintainer) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :public, :repository) } let!(:label_bug) { create(:label, project: project, title: 'bug') } let!(:label_feature) { create(:label, project: project, title: 'feature') } @@ -32,7 +26,8 @@ RSpec.describe 'Merge request > User uses quick actions', :js, :use_clean_rails_ end describe 'merge-request-only commands' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } + let(:guest) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :public, :repository) } let(:merge_request) { create(:merge_request, source_project: project) } let!(:milestone) { create(:milestone, project: project, title: 'ASAP') } diff --git a/spec/features/monitor_sidebar_link_spec.rb b/spec/features/monitor_sidebar_link_spec.rb index 6e464cb8752..1d39f749ca7 100644 --- a/spec/features/monitor_sidebar_link_spec.rb +++ b/spec/features/monitor_sidebar_link_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Monitor dropdown sidebar', :aggregate_failures, feature_category: :shared do let_it_be_with_reload(:project) { create(:project, :internal, :repository) } - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let(:role) { nil } diff --git a/spec/features/nav/pinned_nav_items_spec.rb b/spec/features/nav/pinned_nav_items_spec.rb index cf53e0a322a..1a3ac973ed4 100644 --- a/spec/features/nav/pinned_nav_items_spec.rb +++ b/spec/features/nav/pinned_nav_items_spec.rb @@ -168,17 +168,19 @@ RSpec.describe 'Navigation menu item pinning', :js, feature_category: :navigatio private - def add_pin(menu_item_title) - menu_item = find("[data-testid=\"nav-item-link\"]", text: menu_item_title) - menu_item.hover - menu_item.find("[data-testid=\"thumbtack-icon\"]").click + def add_pin(nav_item_title) + nav_item = find("[data-testid=\"nav-item\"]", text: nav_item_title) + nav_item.hover + pin_button = nav_item.find("[data-testid=\"nav-item-pin\"]") + pin_button.click wait_for_requests end - def remove_pin(menu_item_title) - menu_item = find("[data-testid=\"nav-item-link\"]", text: menu_item_title) - menu_item.hover - menu_item.find("[data-testid=\"thumbtack-solid-icon\"]").click + def remove_pin(nav_item_title) + nav_item = find("[data-testid=\"nav-item\"]", text: nav_item_title) + nav_item.hover + unpin_button = nav_item.find("[data-testid=\"nav-item-unpin\"]") + unpin_button.click wait_for_requests end diff --git a/spec/features/nav/top_nav_responsive_spec.rb b/spec/features/nav/top_nav_responsive_spec.rb index ff8132dc087..2a07742c91e 100644 --- a/spec/features/nav/top_nav_responsive_spec.rb +++ b/spec/features/nav/top_nav_responsive_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'top nav responsive', :js, feature_category: :navigation do include MobileHelpers include Features::InviteMembersModalHelpers - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/nav/top_nav_spec.rb b/spec/features/nav/top_nav_spec.rb index ccbf4646273..bf91897eb26 100644 --- a/spec/features/nav/top_nav_spec.rb +++ b/spec/features/nav/top_nav_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'top nav responsive', :js, feature_category: :navigation do include Features::InviteMembersModalHelpers - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb index ca20a1cd81b..b65416ee618 100644 --- a/spec/features/oauth_login_spec.rb +++ b/spec/features/oauth_login_spec.rb @@ -136,7 +136,7 @@ RSpec.describe 'OAuth Login', :allow_forgery_protection, feature_category: :syst # record as the host / port depends on whether or not the spec uses # JS. let(:application) do - create(:oauth_application, scopes: 'api', redirect_uri: redirect_uri, confidential: false) + create(:oauth_application, scopes: 'api', redirect_uri: redirect_uri, confidential: true) end let(:params) do diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb index a756c524cbb..697ad4c87f7 100644 --- a/spec/features/profiles/user_edit_profile_spec.rb +++ b/spec/features/profiles/user_edit_profile_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'User edit profile', feature_category: :user_profile do include Features::NotesHelpers - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do stub_feature_flags(edit_user_profile_vue: false) @@ -478,7 +478,7 @@ RSpec.describe 'User edit profile', feature_category: :user_profile do end context 'Remove status button' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do user.status = UserStatus.new(message: 'Eating bread', emoji: 'stuffed_flatbread') diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb index 7d858e3c92c..3af8dadcde0 100644 --- a/spec/features/profiles/user_visits_notifications_tab_spec.rb +++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb @@ -12,14 +12,6 @@ RSpec.describe 'User visits the notifications tab', :js, feature_category: :user visit(profile_notifications_path) end - it 'turns on the receive product marketing emails setting' do - expect(page).to have_content('Notifications') - - expect do - check 'Receive product marketing emails' - end.to change { user.reload.email_opted_in }.to(true) - end - it 'changes the project notifications setting' do expect(page).to have_content('Notifications') diff --git a/spec/features/profiles/user_visits_profile_account_page_spec.rb b/spec/features/profiles/user_visits_profile_account_page_spec.rb index 8ff9cbc242e..8569cefd1f4 100644 --- a/spec/features/profiles/user_visits_profile_account_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_account_page_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User visits the profile account page', feature_category: :user_profile do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/profiles/user_visits_profile_authentication_log_spec.rb b/spec/features/profiles/user_visits_profile_authentication_log_spec.rb index ac0ed91468c..f92b8e2e751 100644 --- a/spec/features/profiles/user_visits_profile_authentication_log_spec.rb +++ b/spec/features/profiles/user_visits_profile_authentication_log_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User visits the authentication log', feature_category: :user_profile do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } context 'when user signed in' do before do diff --git a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb index d690589b893..033711f699e 100644 --- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'User visits the profile preferences page', :js, feature_category: :user_profile do include ListboxHelpers - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb index 14fc6ed33b3..821c3d5ef2b 100644 --- a/spec/features/profiles/user_visits_profile_spec.rb +++ b/spec/features/profiles/user_visits_profile_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User visits their profile', feature_category: :user_profile do - let_it_be_with_refind(:user) { create(:user) } + let_it_be_with_refind(:user) { create(:user, :no_super_sidebar) } before do stub_feature_flags(profile_tabs_vue: false) diff --git a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb index 547e47ead77..728fe1a3172 100644 --- a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User visits the profile SSH keys page', feature_category: :user_profile do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/projects/active_tabs_spec.rb b/spec/features/projects/active_tabs_spec.rb index 594c2b442aa..973a1e76679 100644 --- a/spec/features/projects/active_tabs_spec.rb +++ b/spec/features/projects/active_tabs_spec.rb @@ -3,9 +3,8 @@ require 'spec_helper' RSpec.describe 'Project active tab', feature_category: :groups_and_projects do - let_it_be(:project) { create(:project, :repository, :with_namespace_settings) } - - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, :with_namespace_settings, namespace: user.namespace) } before do sign_in(user) diff --git a/spec/features/projects/branches/user_creates_branch_spec.rb b/spec/features/projects/branches/user_creates_branch_spec.rb index 8d636dacb75..eafb75d75ac 100644 --- a/spec/features/projects/branches/user_creates_branch_spec.rb +++ b/spec/features/projects/branches/user_creates_branch_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'User creates branch', :js, feature_category: :groups_and_project include Features::BranchesHelpers let_it_be(:group) { create(:group, :public) } - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } shared_examples 'creates new branch' do specify do diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb index b09aa91f4ab..adaa5e48967 100644 --- a/spec/features/projects/ci/editor_spec.rb +++ b/spec/features/projects/ci/editor_spec.rb @@ -71,7 +71,7 @@ RSpec.describe 'Pipeline Editor', :js, feature_category: :pipeline_composition d it 'renders the empty page', :aggregate_failures do expect(page).to have_content 'Optimize your workflow with CI/CD Pipelines' - expect(page).to have_selector '[data-testid="create_new_ci_button"]' + expect(page).to have_selector '[data-testid="create-new-ci-button"]' end context 'when clicking on the create new CI button' do diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index eadcc0e62c4..b16f43a16b6 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'Gcp Cluster', :js, feature_category: :deployment_management do include GoogleApi::CloudPlatformHelpers let(:project) { create(:project) } - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do project.add_maintainer(user) diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index 6da8eea687e..1393cc6db15 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'User Cluster', :js, feature_category: :deployment_management do include GoogleApi::CloudPlatformHelpers let(:project) { create(:project) } - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do project.add_maintainer(user) diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb index d40f929d0b2..e075cc86319 100644 --- a/spec/features/projects/clusters_spec.rb +++ b/spec/features/projects/clusters_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'Clusters', :js, feature_category: :groups_and_projects do include GoogleApi::CloudPlatformHelpers let(:project) { create(:project) } - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do project.add_maintainer(user) diff --git a/spec/features/projects/commit/user_sees_pipelines_tab_spec.rb b/spec/features/projects/commit/user_sees_pipelines_tab_spec.rb index e44364c7f2d..bc5d468c97a 100644 --- a/spec/features/projects/commit/user_sees_pipelines_tab_spec.rb +++ b/spec/features/projects/commit/user_sees_pipelines_tab_spec.rb @@ -36,7 +36,7 @@ RSpec.describe 'Commit > Pipelines tab', :js, feature_category: :source_code_man wait_for_requests page.within('[data-testid="pipeline-table-row"]') do - expect(page).to have_selector('[data-testid="ci-badge-passed"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'passed') expect(page).to have_content(pipeline.id) expect(page).to have_content('API') expect(page).to have_css('[data-testid="pipeline-mini-graph"]') diff --git a/spec/features/projects/confluence/user_views_confluence_page_spec.rb b/spec/features/projects/confluence/user_views_confluence_page_spec.rb index c1ce6ea4536..216bea74c09 100644 --- a/spec/features/projects/confluence/user_views_confluence_page_spec.rb +++ b/spec/features/projects/confluence/user_views_confluence_page_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User views the Confluence page', feature_category: :integrations do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :public) } diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index 11ea72b87a2..3abe3ce1396 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -10,24 +10,19 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do before do sign_in(user) project.add_role(user, role) - stub_feature_flags(environment_details_vue: false) end def auto_stop_button_selector %q{button[title="Prevent environment from auto-stopping"]} end - describe 'environment details page vue' do + describe 'environment details page', :js do let_it_be(:environment) { create(:environment, project: project) } let!(:permissions) {} let!(:deployment) {} let!(:action) {} let!(:cluster) {} - before do - stub_feature_flags(environment_details_vue: true) - end - context 'with auto-stop' do let_it_be(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) } @@ -35,122 +30,16 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do visit_environment(environment) end - it 'shows auto stop info', :js do - expect(page).to have_content('Auto stops') - end - - it 'shows auto stop button', :js do - expect(page).to have_selector(auto_stop_button_selector) - expect(page.find(auto_stop_button_selector).find(:xpath, '..')['action']).to have_content(cancel_auto_stop_project_environment_path(environment.project, environment)) - end - - it 'allows user to cancel auto stop', :js do - page.find(auto_stop_button_selector).click - wait_for_all_requests - expect(page).to have_content('Auto stop successfully canceled.') - expect(page).not_to have_selector(auto_stop_button_selector) - end - end - - context 'without deployments' do - before do - visit_environment(environment) - end - - it 'does not show deployments', :js do - expect(page).to have_content('You don\'t have any deployments right now.') - end - end - - context 'with deployments' do - before do - visit_environment(environment) - end - - context 'when there is a successful deployment' do - let(:pipeline) { create(:ci_pipeline, project: project) } - let(:build) { create(:ci_build, :success, pipeline: pipeline) } - - let(:deployment) do - create(:deployment, :success, environment: environment, deployable: build) - end - - it 'does show deployments', :js do - wait_for_requests - expect(page).to have_link("#{build.name} (##{build.id})") - end - end - - context 'when there is a failed deployment' do - let(:pipeline) { create(:ci_pipeline, project: project) } - let(:build) { create(:ci_build, pipeline: pipeline) } - - let(:deployment) do - create(:deployment, :failed, environment: environment, deployable: build) - end - - it 'does show deployments', :js do - wait_for_requests - expect(page).to have_link("#{build.name} (##{build.id})") - end - end - - context 'with related deployable present' do - let_it_be(:previous_pipeline) { create(:ci_pipeline, project: project) } - - let_it_be(:previous_build) do - create(:ci_build, :success, pipeline: previous_pipeline, environment: environment.name) - end - - let_it_be(:previous_deployment) do - create(:deployment, :success, environment: environment, deployable: previous_build) - end - - let_it_be(:pipeline) { create(:ci_pipeline, project: project) } - let_it_be(:build) { create(:ci_build, pipeline: pipeline, environment: environment.name) } - - let_it_be(:deployment) do - create(:deployment, :success, environment: environment, deployable: build) - end - - before do - visit_environment(environment) - end - - it 'shows deployment information and buttons', :js do - wait_for_requests - expect(page).to have_button('Re-deploy to environment') - expect(page).to have_button('Rollback environment') - expect(page).to have_link("#{build.name} (##{build.id})") - end - end - end - end - - describe 'environment details page' do - let_it_be(:environment) { create(:environment, project: project) } - let!(:permissions) {} - let!(:deployment) {} - let!(:action) {} - let!(:cluster) {} - - context 'with auto-stop' do - let!(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) } - - before do - visit_environment(environment) - end - - it 'shows auto stop info', :js do + it 'shows auto stop info' do expect(page).to have_content('Auto stops') end - it 'shows auto stop button', :js do + it 'shows auto stop button' do expect(page).to have_selector(auto_stop_button_selector) expect(page.find(auto_stop_button_selector).find(:xpath, '..')['action']).to have_content(cancel_auto_stop_project_environment_path(environment.project, environment)) end - it 'allows user to cancel auto stop', :js do + it 'allows user to cancel auto stop' do page.find(auto_stop_button_selector).click wait_for_all_requests expect(page).to have_content('Auto stop successfully canceled.') @@ -208,10 +97,6 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do it 'does show deployments' do expect(page).to have_link("#{build.name} (##{build.id})") end - - it 'shows a tooltip on the job name' do - expect(page).to have_css("[title=\"#{build.name} (##{build.id})\"].has-tooltip") - end end context 'when there is a failed deployment' do @@ -227,26 +112,6 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do end end - context 'with many deployments' do - let(:pipeline) { create(:ci_pipeline, project: project) } - let(:build) { create(:ci_build, pipeline: pipeline) } - - let!(:second) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: Time.current) } - let!(:first) { create(:deployment, environment: environment, deployable: build, status: :running) } - let!(:last) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: 2.days.ago) } - let!(:third) { create(:deployment, environment: environment, deployable: build, status: :canceled, finished_at: 1.day.ago) } - - before do - visit_environment(environment) - end - - it 'shows all of them in ordered way' do - ids = find_all('[data-testid="deployment-id"]').map { |e| e.text } - expected_ordered_ids = [first, second, third, last].map { |d| "##{d.iid}" } - expect(ids).to eq(expected_ordered_ids) - end - end - context 'with upcoming deployments' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } @@ -265,7 +130,7 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do # See https://gitlab.com/gitlab-org/gitlab/-/issues/350618 for more information. it 'shows upcoming deployments in unordered way' do displayed_ids = find_all('[data-testid="deployment-id"]').map { |e| e.text } - internal_ids = [runnind_deployment_1, runnind_deployment_2, success_without_finished_at].map { |d| "##{d.iid}" } + internal_ids = [runnind_deployment_1, runnind_deployment_2, success_without_finished_at].map { |d| d.iid.to_s } expect(displayed_ids).to match_array(internal_ids) end end @@ -309,20 +174,19 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do end it 'does show a play button' do - expect(page).to have_link(action.name) + expect(page).to have_button(action.name, visible: :all) end - it 'does allow to play manual action', :js do + it 'does allow to play manual action' do expect(action).to be_manual - find('button.dropdown').click + click_button('Deploy to...') - expect { click_link(action.name) } + expect { click_button(action.name) } .not_to change { Ci::Pipeline.count } wait_for_all_requests - expect(page).to have_content(action.name) expect(action.reload).to be_pending end end @@ -347,38 +211,6 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do end end - context 'with terminal' do - context 'when user configured kubernetes from CI/CD > Clusters' do - let!(:cluster) do - create(:cluster, :project, :provided_by_gcp, projects: [project]) - end - - context 'for project maintainer' do - let(:role) { :maintainer } - - context 'web terminal', :js do - before do - # Stub #terminals as it causes js-enabled feature specs to - # render the page incorrectly - # - # In EE we have to stub EE::Environment since it overwrites - # the "terminals" method. - allow_next_instance_of(Gitlab.ee? ? EE::Environment : Environment) do |instance| - allow(instance).to receive(:terminals) { nil } - end - - visit terminal_project_environment_path(project, environment) - end - - it 'displays a web terminal' do - expect(page).to have_selector('#terminal') - expect(page).to have_link(nil, href: environment.external_url) - end - end - end - end - end - context 'when environment is available' do context 'with stop action' do let(:build) { create(:ci_build, :success, pipeline: pipeline, environment: environment.name) } @@ -446,6 +278,8 @@ RSpec.describe 'Environment', feature_category: :groups_and_projects do visit folder_project_environments_path(project, id: 'staging-1.0') end + wait_for_requests + expect(reqs.first.status_code).to eq(200) expect(page).to have_content('Environments / staging-1.0') end diff --git a/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb index 4af5c91479a..127610cf4db 100644 --- a/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb +++ b/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb @@ -7,13 +7,14 @@ RSpec.describe 'User creates feature flag', :js do let(:user) { create(:user) } let(:project) { create(:project, namespace: user.namespace) } + let!(:environment) { create(:environment, :production, project: project) } before do project.add_developer(user) sign_in(user) end - it 'user creates a flag enabled for user ids' do + it 'user creates a flag enabled for user ids with existing environment' do visit(new_project_feature_flag_path(project)) set_feature_flag_info('test_feature', 'Test feature') within_strategy_row(1) do @@ -29,6 +30,22 @@ RSpec.describe 'User creates feature flag', :js do expect(page).to have_text('test_feature') end + it 'user creates a flag enabled for user ids with non-existing environment' do + visit(new_project_feature_flag_path(project)) + set_feature_flag_info('test_feature', 'Test feature') + within_strategy_row(1) do + select 'User IDs', from: 'Type' + fill_in 'User IDs', with: 'user1, user2' + environment_plus_button.click + environment_search_input.set('foo-bar') + environment_search_create_button.first.click + end + click_button 'Create feature flag' + + expect_user_to_see_feature_flags_index_page + expect(page).to have_text('test_feature') + end + it 'user creates a flag with default environment scopes' do visit(new_project_feature_flag_path(project)) set_feature_flag_info('test_flag', 'Test flag') @@ -74,14 +91,18 @@ RSpec.describe 'User creates feature flag', :js do end def environment_plus_button - find('.js-new-environments-dropdown') + find('[data-testid=new-environments-dropdown]') end def environment_search_input - find('.js-new-environments-dropdown input') + find('[data-testid=new-environments-dropdown] input') end def environment_search_results - all('.js-new-environments-dropdown button.dropdown-item') + all('[data-testid=new-environments-dropdown] li') + end + + def environment_search_create_button + all('[data-testid=new-environments-dropdown] button') end end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index b798524b9c4..8f66b722ead 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -3,10 +3,10 @@ require 'spec_helper' RSpec.describe 'Edit Project Settings', feature_category: :groups_and_projects do - let(:member) { create(:user) } + let(:member) { create(:user, :no_super_sidebar) } let!(:project) { create(:project, :public, :repository) } let!(:issue) { create(:issue, project: project) } - let(:non_member) { create(:user) } + let(:non_member) { create(:user, :no_super_sidebar) } describe 'project features visibility selectors', :js do before do diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 95e96159744..595aad0144b 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe 'Projects > Files > Project owner creates a license file', :js, feature_category: :groups_and_projects do - let(:project) { create(:project, :repository) } - let(:project_maintainer) { project.first_owner } + let_it_be(:project_maintainer) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, namespace: project_maintainer.namespace) } before do project.repository.delete_file(project_maintainer, 'LICENSE', diff --git a/spec/features/projects/files/user_find_file_spec.rb b/spec/features/projects/files/user_find_file_spec.rb index 5406726eb6e..005a870bea0 100644 --- a/spec/features/projects/files/user_find_file_spec.rb +++ b/spec/features/projects/files/user_find_file_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'User find project file', feature_category: :groups_and_projects do include ListboxHelpers - let(:user) { create :user } + let(:user) { create :user, :no_super_sidebar } let(:project) { create :project, :repository } before do diff --git a/spec/features/projects/files/user_searches_for_files_spec.rb b/spec/features/projects/files/user_searches_for_files_spec.rb index 25456593fc4..627912df408 100644 --- a/spec/features/projects/files/user_searches_for_files_spec.rb +++ b/spec/features/projects/files/user_searches_for_files_spec.rb @@ -3,7 +3,8 @@ require 'spec_helper' RSpec.describe 'Projects > Files > User searches for files', feature_category: :groups_and_projects do - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, namespace: user.namespace) } before do sign_in(user) @@ -11,7 +12,7 @@ RSpec.describe 'Projects > Files > User searches for files', feature_category: : describe 'project main screen' do context 'when project is empty' do - let(:project) { create(:project) } + let_it_be(:project) { create(:project, namespace: user.namespace) } before do visit project_path(project) @@ -25,10 +26,7 @@ RSpec.describe 'Projects > Files > User searches for files', feature_category: : end context 'when project is not empty' do - let(:project) { create(:project, :repository) } - before do - project.add_developer(user) visit project_path(project) end @@ -39,10 +37,7 @@ RSpec.describe 'Projects > Files > User searches for files', feature_category: : end describe 'project tree screen' do - let(:project) { create(:project, :repository) } - before do - project.add_developer(user) visit project_tree_path(project, project.default_branch) end diff --git a/spec/features/projects/forks/fork_list_spec.rb b/spec/features/projects/forks/fork_list_spec.rb index 966147637f5..86e4e03259e 100644 --- a/spec/features/projects/forks/fork_list_spec.rb +++ b/spec/features/projects/forks/fork_list_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'listing forks of a project', feature_category: :groups_and_proje let(:source) { create(:project, :public, :repository) } let!(:fork) { fork_project(source, nil, repository: true) } - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do source.add_maintainer(user) diff --git a/spec/features/projects/graph_spec.rb b/spec/features/projects/graph_spec.rb index 16a3686215f..9b0803e4b0c 100644 --- a/spec/features/projects/graph_spec.rb +++ b/spec/features/projects/graph_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Project Graph', :js, feature_category: :groups_and_projects do - let(:user) { create :user } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :repository, namespace: user.namespace) } let(:branch_name) { 'master' } diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index ad2fccc14bf..bda45da0fa5 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -38,6 +38,10 @@ RSpec.describe 'Import/Export - project export integration test', :js, feature_c context 'admin user' do before do sign_in(user) + + # Now that we export project in batches we produce more queries than before + # needing to increase the default threshold + allow(Gitlab::QueryLimiting::Transaction).to receive(:threshold).and_return(200) end it 'exports a project successfully', :sidekiq_inline do diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb index 77f95827d88..afcf0e660f7 100644 --- a/spec/features/projects/jobs/user_browses_jobs_spec.rb +++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb @@ -72,7 +72,7 @@ RSpec.describe 'User browses jobs', feature_category: :groups_and_projects do wait_for_requests - expect(page).to have_selector('[data-testid="ci-badge-canceled"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'canceled') expect(page).not_to have_selector('[data-testid="jobs-table-error-alert"]') end end @@ -93,7 +93,7 @@ RSpec.describe 'User browses jobs', feature_category: :groups_and_projects do wait_for_requests - expect(page).to have_selector('[data-testid="ci-badge-pending"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending') end end @@ -133,7 +133,7 @@ RSpec.describe 'User browses jobs', feature_category: :groups_and_projects do wait_for_requests - expect(page).to have_selector('[data-testid="ci-badge-pending"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'pending') end it 'unschedules a job successfully' do @@ -141,7 +141,7 @@ RSpec.describe 'User browses jobs', feature_category: :groups_and_projects do wait_for_requests - expect(page).to have_selector('[data-testid="ci-badge-manual"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'manual') end end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index c203e644280..1bee4cc5081 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -66,7 +66,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :grou wait_for_requests - expect(page).to have_css('[data-testid="ci-badge-passed"]', text: 'passed') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'passed') end it 'shows commit`s data', :js do @@ -93,7 +93,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :grou visit project_job_path(project, job) within '.js-pipeline-info' do - expect(page).to have_content("Pipeline ##{pipeline.id} for #{pipeline.ref}") + expect(page).to have_content("Pipeline ##{pipeline.id} #{pipeline.status} for #{pipeline.ref}") end end @@ -239,7 +239,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :grou href = new_project_issue_path(project, options) - page.within('.build-sidebar') do + page.within('aside.right-sidebar') do expect(find('[data-testid="job-new-issue"]')['href']).to include(href) end end @@ -1051,7 +1051,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :grou it 'retries the job' do find('[data-testid="retry-button-modal"]').click - within '[data-testid="ci-header-content"]' do + within '[data-testid="job-header-content"]' do expect(page).to have_content('pending') end end diff --git a/spec/features/projects/labels/user_creates_labels_spec.rb b/spec/features/projects/labels/user_creates_labels_spec.rb index 46729048fe7..6e52963bee2 100644 --- a/spec/features/projects/labels/user_creates_labels_spec.rb +++ b/spec/features/projects/labels/user_creates_labels_spec.rb @@ -63,6 +63,8 @@ RSpec.describe "User creates labels", feature_category: :team_planning do end end end + + it_behaves_like "lock_on_merge when creating labels" end context "in another project" do diff --git a/spec/features/projects/labels/user_edits_labels_spec.rb b/spec/features/projects/labels/user_edits_labels_spec.rb index bf1182cfddd..059edea2109 100644 --- a/spec/features/projects/labels/user_edits_labels_spec.rb +++ b/spec/features/projects/labels/user_edits_labels_spec.rb @@ -13,16 +13,16 @@ RSpec.describe "User edits labels", feature_category: :team_planning do project.add_maintainer(user) sign_in(user) - visit(edit_project_label_path(project, label)) + visit edit_project_label_path(project, label) end - it "updates label's title" do - new_title = "fix" + it 'update label with new title' do + new_title = 'fix' - fill_in("Title", with: new_title) - click_button("Save changes") + fill_in('Title', with: new_title) + click_button('Save changes') - page.within(".other-labels .manage-labels-list") do + page.within('.other-labels .manage-labels-list') do expect(page).to have_content(new_title).and have_no_content(label.title) end end @@ -38,4 +38,17 @@ RSpec.describe "User edits labels", feature_category: :team_planning do expect(page).to have_content("#{label.title} was removed").and have_no_content("#{label.title}</span>") end + + describe 'lock_on_merge' do + let_it_be_with_reload(:label_unlocked) { create(:label, project: project, lock_on_merge: false) } + let_it_be(:label_locked) { create(:label, project: project, lock_on_merge: true) } + let_it_be(:edit_label_path_unlocked) { edit_project_label_path(project, label_unlocked) } + let_it_be(:edit_label_path_locked) { edit_project_label_path(project, label_locked) } + + before do + visit edit_label_path_unlocked + end + + it_behaves_like 'lock_on_merge when editing labels' + end end diff --git a/spec/features/projects/members/manage_members_spec.rb b/spec/features/projects/members/manage_members_spec.rb index 0e3ac5ff3ac..76b2a73e170 100644 --- a/spec/features/projects/members/manage_members_spec.rb +++ b/spec/features/projects/members/manage_members_spec.rb @@ -173,7 +173,7 @@ RSpec.describe 'Projects > Members > Manage members', :js, feature_category: :on end end - it_behaves_like 'inviting members', 'project-members-page' do + it_behaves_like 'inviting members', 'project_members_page' do let_it_be(:entity) { project } let_it_be(:members_page_path) { project_project_members_path(entity) } let_it_be(:subentity) { project } diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 9af36b4b2a9..d1e58ba91f0 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' RSpec.describe 'Projects > Members > User requests access', :js, feature_category: :groups_and_projects do include Spec::Support::Helpers::ModalHelpers - let_it_be(:user) { create(:user) } - let_it_be(:maintainer) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:maintainer) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, :public, :repository) } let(:owner) { project.first_owner } diff --git a/spec/features/projects/milestones/user_interacts_with_labels_spec.rb b/spec/features/projects/milestones/user_interacts_with_labels_spec.rb index 36dfee7811d..3742c9f19d8 100644 --- a/spec/features/projects/milestones/user_interacts_with_labels_spec.rb +++ b/spec/features/projects/milestones/user_interacts_with_labels_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User interacts with labels', feature_category: :team_planning do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, namespace: user.namespace) } let(:milestone) { create(:milestone, project: project, title: 'v2.2', description: '# Description header') } let(:issue1) { create(:issue, project: project, title: 'Bugfix1', milestone: milestone) } diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb index b6645e9b710..e967c1be3bc 100644 --- a/spec/features/projects/navbar_spec.rb +++ b/spec/features/projects/navbar_spec.rb @@ -8,15 +8,13 @@ RSpec.describe 'Project navbar', :with_license, feature_category: :groups_and_pr include_context 'project navbar structure' - let_it_be(:project) { create(:project, :repository) } - - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, namespace: user.namespace) } before do sign_in(user) stub_config(registry: { enabled: false }) - stub_feature_flags(harbor_registry_integration: false) stub_feature_flags(ml_experiment_tracking: false) insert_package_nav(_('Deployments')) insert_infrastructure_registry_nav @@ -88,8 +86,6 @@ RSpec.describe 'Project navbar', :with_license, feature_category: :groups_and_pr let_it_be(:harbor_integration) { create(:harbor_integration, project: project) } before do - stub_feature_flags(harbor_registry_integration: true) - insert_harbor_registry_nav(_('Terraform modules')) visit project_path(project) diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 6e6d9ff4af9..926fea24e14 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -10,7 +10,7 @@ RSpec.describe 'New project', :js, feature_category: :groups_and_projects do end context 'as a user' do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) @@ -76,7 +76,7 @@ RSpec.describe 'New project', :js, feature_category: :groups_and_projects do end context 'as an admin' do - let(:user) { create(:admin) } + let(:user) { create(:admin, :no_super_sidebar) } shared_examples '"New project" page' do before do @@ -566,14 +566,14 @@ RSpec.describe 'New project', :js, feature_category: :groups_and_projects do let(:provider) { :bitbucket } context 'as a user' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:oauth_config_instructions) { 'To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration' } it_behaves_like 'has instructions to enable OAuth' end context 'as an admin', :do_not_mock_admin_mode_setting do - let(:user) { create(:admin) } + let(:user) { create(:admin, :no_super_sidebar) } let(:oauth_config_instructions) { 'To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration' } it_behaves_like 'has instructions to enable OAuth' @@ -581,7 +581,7 @@ RSpec.describe 'New project', :js, feature_category: :groups_and_projects do end describe 'sidebar' do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:parent_group) { create(:group) } before do @@ -616,14 +616,14 @@ RSpec.describe 'New project', :js, feature_category: :groups_and_projects do context 'for a new top-level project' do it 'shows the "Your work" navigation' do visit new_project_path - expect(page).to have_selector(".super-sidebar .context-switcher-toggle", text: "Your work") + expect(page).to have_selector(".super-sidebar", text: "Your work") end end context 'for a new group project' do it 'shows the group sidebar of the parent group' do visit new_project_path(namespace_id: parent_group.id) - expect(page).to have_selector(".super-sidebar .context-switcher-toggle", text: parent_group.name) + expect(page).to have_selector(".super-sidebar", text: parent_group.name) end end end diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb index eec9f2befb6..8350214bf99 100644 --- a/spec/features/projects/pages/user_edits_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_settings_spec.rb @@ -5,7 +5,7 @@ RSpec.describe 'Pages edits pages settings', :js, feature_category: :pages do include Spec::Support::Helpers::ModalHelpers let_it_be_with_reload(:project) { create(:project, :pages_published, pages_https_only: false) } - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 358c55376d4..322d25ed052 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -12,389 +12,301 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :groups_and_projects let!(:user) { create(:user) } let!(:maintainer) { create(:user) } - context 'with pipeline_schedules_vue feature flag turned off' do + context 'logged in as the pipeline schedule owner' do before do - stub_feature_flags(pipeline_schedules_vue: false) + project.add_developer(user) + pipeline_schedule.update!(owner: user) + gitlab_sign_in(user) end - context 'logged in as the pipeline schedule owner' do + describe 'GET /projects/pipeline_schedules' do before do - project.add_developer(user) - pipeline_schedule.update!(owner: user) - gitlab_sign_in(user) + visit_pipelines_schedules end - describe 'GET /projects/pipeline_schedules' do - before do - visit_pipelines_schedules - end - - it 'edits the pipeline' do - page.within('.pipeline-schedule-table-row') do - click_link 'Edit' - end + it 'edits the pipeline' do + page.find('[data-testid="edit-pipeline-schedule-btn"]').click - expect(page).to have_content('Edit Pipeline Schedule') - end + expect(page).to have_content(s_('PipelineSchedules|Edit pipeline schedule')) end + end - describe 'PATCH /projects/pipelines_schedules/:id/edit' do - before do - edit_pipeline_schedule - end - - it 'displays existing properties' do - description = find_field('schedule_description').value - expect(description).to eq('pipeline schedule') - expect(page).to have_button('master') - expect(page).to have_button('Select timezone') - end + describe 'PATCH /projects/pipelines_schedules/:id/edit' do + before do + edit_pipeline_schedule + end - it 'edits the scheduled pipeline' do - fill_in 'schedule_description', with: 'my brand new description' + it 'displays existing properties' do + description = find_field('schedule-description').value + expect(description).to eq('pipeline schedule') + expect(page).to have_button('master') + expect(page).to have_button(_('Select timezone')) + end - save_pipeline_schedule + it 'edits the scheduled pipeline' do + fill_in 'schedule-description', with: 'my brand new description' - expect(page).to have_content('my brand new description') - end + save_pipeline_schedule - context 'when ref is nil' do - before do - pipeline_schedule.update_attribute(:ref, nil) - edit_pipeline_schedule - end + expect(page).to have_content('my brand new description') + end - it 'shows the pipeline schedule with default ref' do - page.within('[data-testid="schedule-target-ref"]') do - expect(first('.gl-button-text').text).to eq('master') - end - end + context 'when ref is nil' do + before do + pipeline_schedule.update_attribute(:ref, nil) + edit_pipeline_schedule end - context 'when ref is empty' do - before do - pipeline_schedule.update_attribute(:ref, '') - edit_pipeline_schedule - end - - it 'shows the pipeline schedule with default ref' do - page.within('[data-testid="schedule-target-ref"]') do - expect(first('.gl-button-text').text).to eq('master') - end + it 'shows the pipeline schedule with default ref' do + page.within('#schedule-target-branch-tag') do + expect(first('.gl-button-text').text).to eq('master') end end end - end - - context 'logged in as a project maintainer' do - before do - project.add_maintainer(user) - gitlab_sign_in(user) - end - describe 'GET /projects/pipeline_schedules' do + context 'when ref is empty' do before do - visit_pipelines_schedules + pipeline_schedule.update_attribute(:ref, '') + edit_pipeline_schedule end - describe 'The view' do - it 'displays the required information description' do - page.within('.pipeline-schedule-table-row') do - expect(page).to have_content('pipeline schedule') - expect(find("[data-testid='next-run-cell'] time")['title']) - .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y')) - expect(page).to have_link('master') - expect(page).to have_link("##{pipeline.id}") - end - end - - it 'creates a new scheduled pipeline' do - click_link 'New schedule' - - expect(page).to have_content('Schedule a new pipeline') - end - - it 'changes ownership of the pipeline' do - click_button 'Take ownership' - - page.within('#pipeline-take-ownership-modal') do - click_link 'Take ownership' - end - - page.within('.pipeline-schedule-table-row') do - expect(page).not_to have_content('No owner') - expect(page).to have_link('Sidney Jones') - end - end - - it 'deletes the pipeline' do - click_link 'Delete' - - accept_gl_confirm(button_text: 'Delete pipeline schedule') - - expect(page).not_to have_css(".pipeline-schedule-table-row") + it 'shows the pipeline schedule with default ref' do + page.within('#schedule-target-branch-tag') do + expect(first('.gl-button-text').text).to eq('master') end end + end + end + end - context 'when ref is nil' do - before do - pipeline_schedule.update_attribute(:ref, nil) - visit_pipelines_schedules - end - - it 'shows a list of the pipeline schedules with empty ref column' do - expect(first('.branch-name-cell').text).to eq('') - end - end + context 'logged in as a project maintainer' do + before do + project.add_maintainer(user) + pipeline_schedule.update!(owner: maintainer) + gitlab_sign_in(user) + end - context 'when ref is empty' do - before do - pipeline_schedule.update_attribute(:ref, '') - visit_pipelines_schedules - end + describe 'GET /projects/pipeline_schedules' do + before do + visit_pipelines_schedules - it 'shows a list of the pipeline schedules with empty ref column' do - expect(first('.branch-name-cell').text).to eq('') - end - end + wait_for_requests end - describe 'POST /projects/pipeline_schedules/new' do - before do - visit_new_pipeline_schedule - end - - it 'sets defaults for timezone and target branch' do - expect(page).to have_button('master') - expect(page).to have_button('Select timezone') + describe 'The view' do + it 'displays the required information description' do + page.within('[data-testid="pipeline-schedule-table-row"]') do + expect(page).to have_content('pipeline schedule') + expect(find('[data-testid="next-run-cell"] time')['title']) + .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y')) + expect(page).to have_link('master') + expect(find("[data-testid='last-pipeline-status'] a")['href']).to include(pipeline.id.to_s) + end end it 'creates a new scheduled pipeline' do - fill_in_schedule_form - save_pipeline_schedule + click_link 'New schedule' - expect(page).to have_content('my fancy description') + expect(page).to have_content('Schedule a new pipeline') end - it 'prevents an invalid form from being submitted' do - save_pipeline_schedule + it 'changes ownership of the pipeline' do + find("[data-testid='take-ownership-pipeline-schedule-btn']").click - expect(page).to have_content('This field is required') - end - end + page.within('#pipeline-take-ownership-modal') do + click_button s_('PipelineSchedules|Take ownership') - context 'when user creates a new pipeline schedule with variables' do - before do - visit_pipelines_schedules - click_link 'New schedule' - fill_in_schedule_form - all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA') - all('[name="schedule[variables_attributes][][secret_value]"]')[0].set('AAA123') - all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB') - all('[name="schedule[variables_attributes][][secret_value]"]')[1].set('BBB123') - save_pipeline_schedule - end + wait_for_requests + end - it 'user sees the new variable in edit window', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/397040' do - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - page.within('.ci-variable-list') do - expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('AAA') - expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('AAA123') - expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-key").value).to eq('BBB') - expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-value", visible: false).value).to eq('BBB123') + page.within('[data-testid="pipeline-schedule-table-row"]') do + expect(page).not_to have_content('No owner') + expect(page).to have_link('Sidney Jones') end end - end - context 'when user edits a variable of a pipeline schedule' do - before do - create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| - create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + it 'deletes the pipeline' do + page.within('[data-testid="pipeline-schedule-table-row"]') do + click_button s_('PipelineSchedules|Delete pipeline schedule') end - visit_pipelines_schedules - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - find('.js-ci-variable-list-section .js-secret-value-reveal-button').click - first('.js-ci-variable-input-key').set('foo') - first('.js-ci-variable-input-value').set('bar') - click_button 'Save pipeline schedule' - end + accept_gl_confirm(button_text: s_('PipelineSchedules|Delete pipeline schedule')) - it 'user sees the updated variable in edit window' do - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - page.within('.ci-variable-list') do - expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('foo') - expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('bar') - end + expect(page).not_to have_css('[data-testid="pipeline-schedule-table-row"]') end end - context 'when user removes a variable of a pipeline schedule' do + context 'when ref is nil' do before do - create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| - create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) - end - + pipeline_schedule.update_attribute(:ref, nil) visit_pipelines_schedules - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - find('.ci-variable-list .ci-variable-row-remove-button').click - click_button 'Save pipeline schedule' + wait_for_requests end - it 'user does not see the removed variable in edit window' do - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - page.within('.ci-variable-list') do - expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('') - expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('') + it 'shows a list of the pipeline schedules with empty ref column' do + target = find('[data-testid="pipeline-schedule-target"]') + + page.within('[data-testid="pipeline-schedule-table-row"]') do + expect(target.text).to eq(s_('PipelineSchedules|None')) end end end - context 'when active is true and next_run_at is NULL' do + context 'when ref is empty' do before do - create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| - pipeline_schedule.update_attribute(:next_run_at, nil) # Consequently next_run_at will be nil - end + pipeline_schedule.update_attribute(:ref, '') + visit_pipelines_schedules + wait_for_requests end - it 'user edit and recover the problematic pipeline schedule' do - visit_pipelines_schedules - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - fill_in 'schedule_cron', with: '* 1 2 3 4' - click_button 'Save pipeline schedule' + it 'shows a list of the pipeline schedules with empty ref column' do + target = find('[data-testid="pipeline-schedule-target"]') - page.within('.pipeline-schedule-table-row:nth-child(1)') do - expect(page).to have_css("[data-testid='next-run-cell'] time") - end + expect(target.text).to eq(s_('PipelineSchedules|None')) end end end - context 'logged in as non-member' do + describe 'POST /projects/pipeline_schedules/new' do before do - gitlab_sign_in(user) + visit_new_pipeline_schedule end - describe 'GET /projects/pipeline_schedules' do - before do - visit_pipelines_schedules - end + it 'sets defaults for timezone and target branch' do + expect(page).to have_button('master') + expect(page).to have_button('Select timezone') + end - describe 'The view' do - it 'does not show create schedule button' do - expect(page).not_to have_link('New schedule') - end - end + it 'creates a new scheduled pipeline' do + fill_in_schedule_form + create_pipeline_schedule + + expect(page).to have_content('my fancy description') end - end - context 'not logged in' do - describe 'GET /projects/pipeline_schedules' do - before do - visit_pipelines_schedules - end + it 'prevents an invalid form from being submitted' do + create_pipeline_schedule - describe 'The view' do - it 'does not show create schedule button' do - expect(page).not_to have_link('New schedule') - end - end + expect(page).to have_content("Cron timezone can't be blank") end end - end - context 'with pipeline_schedules_vue feature flag turned on' do - context 'logged in as a project maintainer' do + context 'when user creates a new pipeline schedule with variables' do before do - project.add_maintainer(maintainer) - pipeline_schedule.update!(owner: user) - gitlab_sign_in(maintainer) + visit_pipelines_schedules + click_link 'New schedule' + fill_in_schedule_form + all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA') + all('[name="schedule[variables_attributes][][secret_value]"]')[0].set('AAA123') + all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB') + all('[name="schedule[variables_attributes][][secret_value]"]')[1].set('BBB123') + create_pipeline_schedule end - describe 'GET /projects/pipeline_schedules' do - before do - visit_pipelines_schedules - - wait_for_requests + it 'user sees the new variable in edit window', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/397040' do + find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click + page.within('.ci-variable-list') do + expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-key").value).to eq('AAA') + expect(find(".ci-variable-row:nth-child(1) .js-ci-variable-input-value", visible: false).value).to eq('AAA123') + expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-key").value).to eq('BBB') + expect(find(".ci-variable-row:nth-child(2) .js-ci-variable-input-value", visible: false).value).to eq('BBB123') end + end + end - describe 'The view' do - it 'displays the required information description' do - page.within('[data-testid="pipeline-schedule-table-row"]') do - expect(page).to have_content('pipeline schedule') - expect(find("[data-testid='next-run-cell'] time")['title']) - .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y')) - expect(page).to have_link('master') - expect(find("[data-testid='last-pipeline-status'] a")['href']).to include(pipeline.id.to_s) - end - end - - it 'changes ownership of the pipeline' do - click_button 'Take ownership' + context 'when user edits a variable of a pipeline schedule' do + before do + create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| + create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + end - page.within('#pipeline-take-ownership-modal') do - click_button 'Take ownership' + visit_pipelines_schedules + first('[data-testid="edit-pipeline-schedule-btn"]').click + click_button _('Reveal values') + first('[data-testid="pipeline-form-ci-variable-key"]').set('foo') + first('[data-testid="pipeline-form-ci-variable-value"]').set('bar') + save_pipeline_schedule + end - wait_for_requests - end + it 'user sees the updated variable' do + first('[data-testid="edit-pipeline-schedule-btn"]').click - page.within('[data-testid="pipeline-schedule-table-row"]') do - expect(page).not_to have_content('No owner') - expect(page).to have_link('Sidney Jones') - end - end + expect(first('[data-testid="pipeline-form-ci-variable-key"]').value).to eq('foo') + expect(first('[data-testid="pipeline-form-ci-variable-value"]').value).to eq('') - it 'runs the pipeline' do - click_button 'Run pipeline schedule' + click_button _('Reveal values') - wait_for_requests + expect(first('[data-testid="pipeline-form-ci-variable-value"]').value).to eq('bar') + end + end - expect(page).to have_content("Successfully scheduled a pipeline to run. Go to the Pipelines page for details.") - end + context 'when user removes a variable of a pipeline schedule' do + before do + create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| + create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + end - it 'deletes the pipeline' do - click_button 'Delete pipeline schedule' + visit_pipelines_schedules + first('[data-testid="edit-pipeline-schedule-btn"]').click + find('[data-testid="remove-ci-variable-row"]').click + save_pipeline_schedule + end - accept_gl_confirm(button_text: 'Delete pipeline schedule') + it 'user does not see the removed variable in edit window' do + first('[data-testid="edit-pipeline-schedule-btn"]').click - expect(page).not_to have_css('[data-testid="pipeline-schedule-table-row"]') - end - end + expect(first('[data-testid="pipeline-form-ci-variable-key"]').value).to eq('') + expect(first('[data-testid="pipeline-form-ci-variable-value"]').value).to eq('') end end - context 'logged in as non-member' do + context 'when active is true and next_run_at is NULL' do before do - gitlab_sign_in(user) + create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| + pipeline_schedule.update_attribute(:next_run_at, nil) # Consequently next_run_at will be nil + end end - describe 'GET /projects/pipeline_schedules' do - before do - visit_pipelines_schedules + it 'user edit and recover the problematic pipeline schedule' do + visit_pipelines_schedules + first('[data-testid="edit-pipeline-schedule-btn"]').click + fill_in 'schedule_cron', with: '* 1 2 3 4' + save_pipeline_schedule - wait_for_requests - end - - describe 'The view' do - it 'does not show create schedule button' do - expect(page).not_to have_link('New schedule') - end + page.within(first('[data-testid="pipeline-schedule-table-row"]')) do + expect(page).to have_css("[data-testid='next-run-cell'] time") end end end + end - context 'not logged in' do - describe 'GET /projects/pipeline_schedules' do - before do - visit_pipelines_schedules + context 'logged in as non-member' do + before do + gitlab_sign_in(user) + end - wait_for_requests + describe 'GET /projects/pipeline_schedules' do + before do + visit_pipelines_schedules + end + + describe 'The view' do + it 'does not show create schedule button' do + expect(page).not_to have_link('New schedule') end + end + end + end - describe 'The view' do - it 'does not show create schedule button' do - expect(page).not_to have_link('New schedule') - end + context 'not logged in' do + describe 'GET /projects/pipeline_schedules' do + before do + visit_pipelines_schedules + end + + describe 'The view' do + it 'does not show create schedule button' do + expect(page).not_to have_link('New schedule') end end end @@ -413,7 +325,7 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :groups_and_projects end def select_timezone - find('[data-testid="schedule-timezone"] .gl-new-dropdown-toggle').click + find('#schedule-timezone .gl-new-dropdown-toggle').click find("li", text: "Arizona").click end @@ -421,12 +333,16 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :groups_and_projects click_button 'master' end + def create_pipeline_schedule + click_button s_('PipelineSchedules|Create pipeline schedule') + end + def save_pipeline_schedule - click_button 'Save pipeline schedule' + click_button s_('PipelineSchedules|Edit pipeline schedule') end def fill_in_schedule_form - fill_in 'schedule_description', with: 'my fancy description' + fill_in 'schedule-description', with: 'my fancy description' fill_in 'schedule_cron', with: '* 1 2 3 4' select_timezone diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index bb49fb734d7..2fc8345fb47 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -224,7 +224,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do expect(page).not_to have_content('Retry job') within('[data-testid="pipeline-details-header"]') do - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end end end @@ -278,7 +278,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do expect(page).not_to have_content('Retry job') within('[data-testid="pipeline-details-header"]') do - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end end @@ -312,7 +312,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do expect(page).not_to have_content('Play job') within('[data-testid="pipeline-details-header"]') do - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end end end @@ -537,7 +537,7 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do it 'shows running status in pipeline header', :sidekiq_might_not_need_inline do within('[data-testid="pipeline-details-header"]') do - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end end end @@ -843,12 +843,10 @@ RSpec.describe 'Pipeline', :js, feature_category: :groups_and_projects do end it 'displays the PipelineSchedule in an inactive state' do - stub_feature_flags(pipeline_schedules_vue: false) - visit project_pipeline_schedules_path(project) page.click_link('Inactive') - expect(page).to have_selector('table.ci-table > tbody > tr > td', text: 'blocked user schedule') + expect(page).to have_selector('[data-testid="pipeline-schedule-description"]', text: 'blocked user schedule') end it 'does not create a new Pipeline', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/408215' do diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 26fcd8ca3ca..c1aa2c35337 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do let(:expected_detached_mr_tag) { 'merge request' } context 'when user is logged in' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) @@ -115,7 +115,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do it 'indicates that pipeline can be canceled' do expect(page).to have_selector('.js-pipelines-cancel-button') - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end context 'when canceling' do @@ -127,7 +127,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do it 'indicated that pipelines was canceled', :sidekiq_might_not_need_inline do expect(page).not_to have_selector('.js-pipelines-cancel-button') - expect(page).to have_selector('[data-testid="ci-badge-canceled"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'canceled') end end end @@ -144,7 +144,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do it 'indicates that pipeline can be retried' do expect(page).to have_selector('.js-pipelines-retry-button') - expect(page).to have_selector('[data-testid="ci-badge-failed"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'failed') end context 'when retrying' do @@ -155,7 +155,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do it 'shows running pipeline that is not retryable' do expect(page).not_to have_selector('.js-pipelines-retry-button') - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end end end @@ -396,7 +396,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do end it 'shows the pipeline as preparing' do - expect(page).to have_selector('[data-testid="ci-badge-preparing"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'preparing') end end @@ -417,7 +417,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do end it 'has pipeline running' do - expect(page).to have_selector('[data-testid="ci-badge-running"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'running') end context 'when canceling' do @@ -428,7 +428,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do it 'indicates that pipeline was canceled', :sidekiq_might_not_need_inline do expect(page).not_to have_selector('.js-pipelines-cancel-button') - expect(page).to have_selector('[data-testid="ci-badge-canceled"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'canceled') end end end @@ -450,7 +450,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :continuous_integration do end it 'has failed pipeline', :sidekiq_might_not_need_inline do - expect(page).to have_selector('[data-testid="ci-badge-failed"]') + expect(page).to have_selector('[data-testid="ci-badge-link"]', text: 'failed') end end end diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb index b46451f4255..c2914c020e3 100644 --- a/spec/features/projects/settings/monitor_settings_spec.rb +++ b/spec/features/projects/settings/monitor_settings_spec.rb @@ -5,9 +5,8 @@ require 'spec_helper' RSpec.describe 'Projects > Settings > For a forked project', :js, feature_category: :groups_and_projects do include ListboxHelpers - let_it_be(:project) { create(:project, :repository, create_templates: :issue) } - - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, create_templates: :issue, namespace: user.namespace) } before do sign_in(user) diff --git a/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb b/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb index 1ab88ec0fff..ee54065fdf8 100644 --- a/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb +++ b/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Project > Settings > Packages and registries > Container registry tag expiration policy', feature_category: :groups_and_projects do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) } let(:container_registry_enabled) { true } diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb index 9df82e447aa..7f0367f47f7 100644 --- a/spec/features/projects/settings/registry_settings_spec.rb +++ b/spec/features/projects/settings/registry_settings_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Project > Settings > Packages and registries > Container registry tag expiration policy', feature_category: :groups_and_projects do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) } let(:container_registry_enabled) { true } diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb index d068cb219f1..5cc2e2d3c05 100644 --- a/spec/features/projects/settings/service_desk_setting_spec.rb +++ b/spec/features/projects/settings/service_desk_setting_spec.rb @@ -56,7 +56,7 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache, feature_c wait_for_requests project.reload - expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_custom_address) + expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_alias_address) page.within '#js-service-desk' do fill_in('service-desk-project-suffix', with: 'foo') diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb index ee017336acc..626d4de7baf 100644 --- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb +++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : using RSpec::Parameterized::TableSyntax let_it_be(:project) { create(:project, :repository, :public) } - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb index 5a744be5d81..22d00e9a351 100644 --- a/spec/features/projects/user_sees_sidebar_spec.rb +++ b/spec/features/projects/user_sees_sidebar_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_projects do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) } # NOTE: See documented behaviour https://design.gitlab.com/regions/navigation#contextual-navigation @@ -182,7 +182,7 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro end context 'as guest' do - let(:guest) { create(:user) } + let(:guest) { create(:user, :no_super_sidebar) } let!(:issue) { create(:issue, :opened, project: project, author: guest) } before do diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb index 77f753b92eb..b7b2093d78a 100644 --- a/spec/features/projects/user_uses_shortcuts_spec.rb +++ b/spec/features/projects/user_uses_shortcuts_spec.rb @@ -3,9 +3,8 @@ require 'spec_helper' RSpec.describe 'User uses shortcuts', :js, feature_category: :groups_and_projects do - let_it_be(:project) { create(:project, :repository) } - - let(:user) { project.first_owner } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:project) { create(:project, :repository, namespace: user.namespace) } before do sign_in(user) @@ -15,58 +14,6 @@ RSpec.describe 'User uses shortcuts', :js, feature_category: :groups_and_project wait_for_requests end - context 'disabling shortcuts' do - before do - page.evaluate_script("localStorage.removeItem('shortcutsDisabled')") - end - - it 'can disable shortcuts from help menu' do - open_modal_shortcut_keys - click_toggle_button - close_modal - - open_modal_shortcut_keys - - expect(page).not_to have_selector('[data-testid="modal-shortcuts"]') - - page.refresh - open_modal_shortcut_keys - - # after reload, shortcuts modal doesn't exist at all until we add it - expect(page).not_to have_selector('[data-testid="modal-shortcuts"]') - end - - it 're-enables shortcuts' do - open_modal_shortcut_keys - click_toggle_button - close_modal - - open_modal_from_help_menu - click_toggle_button - close_modal - - open_modal_shortcut_keys - expect(find('[data-testid="modal-shortcuts"]')).to be_visible - end - - def open_modal_shortcut_keys - find('body').native.send_key('?') - end - - def open_modal_from_help_menu - find('.header-help-dropdown-toggle').click - find('button', text: 'Keyboard shortcuts').click - end - - def click_toggle_button - find('.js-toggle-shortcuts .gl-toggle').click - end - - def close_modal - find('.modal button[aria-label="Close"]').click - end - end - context 'when navigating to the Project pages' do it 'redirects to the project overview page' do visit project_issues_path(project) diff --git a/spec/features/projects/wikis_spec.rb b/spec/features/projects/wikis_spec.rb index 5d950da6674..63714954c0c 100644 --- a/spec/features/projects/wikis_spec.rb +++ b/spec/features/projects/wikis_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" RSpec.describe 'Project wikis', :js, feature_category: :wiki do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let(:wiki) { create(:project_wiki, user: user, project: project) } let(:project) { create(:project, namespace: user.namespace, creator: user) } diff --git a/spec/features/projects/work_items/work_item_spec.rb b/spec/features/projects/work_items/work_item_spec.rb index 618d3e2efd0..a1f5466f5bf 100644 --- a/spec/features/projects/work_items/work_item_spec.rb +++ b/spec/features/projects/work_items/work_item_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe 'Work item', :js, feature_category: :team_planning do - let_it_be_with_reload(:user) { create(:user) } - let_it_be_with_reload(:user2) { create(:user, name: 'John') } + let_it_be_with_reload(:user) { create(:user, :no_super_sidebar) } + let_it_be_with_reload(:user2) { create(:user, :no_super_sidebar, name: 'John') } let_it_be(:project) { create(:project, :public) } let_it_be(:work_item) { create(:work_item, project: project) } @@ -39,6 +39,44 @@ RSpec.describe 'Work item', :js, feature_category: :team_planning do expect(page).to have_selector('[data-testid="work-item-actions-dropdown"]') end + it 'reassigns to another user', + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/413074' do + find('[data-testid="work-item-assignees-input"]').fill_in(with: user.username) + wait_for_requests + + send_keys(:enter) + find("body").click + wait_for_requests + + find('[data-testid="work-item-assignees-input"]').fill_in(with: user2.username) + wait_for_requests + + send_keys(:enter) + find("body").click + wait_for_requests + + expect(work_item.reload.assignees).to include(user2) + end + + it 'updates the assignee in real-time' do + Capybara::Session.new(:other_session) + + using_session :other_session do + visit work_items_path + expect(work_item.reload.assignees).not_to include(user) + end + + find('[data-testid="work-item-assignees-input"]').hover + find('[data-testid="assign-self"]').click + wait_for_requests + + expect(work_item.reload.assignees).to include(user) + + using_session :other_session do + expect(work_item.reload.assignees).to include(user) + end + end + it_behaves_like 'work items title' it_behaves_like 'work items toggle status button' it_behaves_like 'work items assignees' @@ -90,5 +128,11 @@ RSpec.describe 'Work item', :js, feature_category: :team_planning do expect(page).to have_selector('[data-testid="award-button"].disabled') end end + + it 'assignees input field is disabled' do + within('[data-testid="work-item-assignees-input"]') do + expect(page).to have_field(type: 'text', disabled: true) + end + end end end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index d28fafaac45..7ca9395f669 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do include MobileHelpers describe 'template' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in user @@ -78,7 +78,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'shows tip about push to create git command' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in user @@ -214,7 +214,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'showing information about source of a project fork', :js do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:base_project) { create(:project, :public, :repository) } let(:forked_project) { fork_project(base_project, user, repository: true) } @@ -265,7 +265,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'when the project repository is disabled', :js do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :repository_disabled, :repository, namespace: user.namespace) } before do @@ -282,7 +282,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'removal', :js do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, namespace: user.namespace) } before do @@ -307,7 +307,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'tree view (default view is set to Files)', :js do - let(:user) { create(:user, project_view: 'files') } + let(:user) { create(:user, :no_super_sidebar, project_view: 'files') } let(:project) { create(:forked_project_with_submodules) } before do @@ -379,7 +379,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'activity view' do - let(:user) { create(:user, project_view: 'activity') } + let(:user) { create(:user, :no_super_sidebar, project_view: 'activity') } let(:project) { create(:project, :repository) } before do @@ -410,7 +410,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do end describe 'edit' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:project) { create(:project, :public) } let(:path) { edit_project_path(project) } @@ -425,7 +425,7 @@ RSpec.describe 'Project', feature_category: :groups_and_projects do describe 'view for a user without an access to a repo' do let(:project) { create(:project, :repository) } - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } it 'does not contain default branch information in its content' do default_branch = 'merge-commit-analyze-side-branch' diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index 3c63ec82778..091c318459b 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -9,396 +9,387 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do sign_in(user) end - context 'when project_runners_vue_ui is disabled' do - before do - stub_feature_flags(project_runners_vue_ui: false) - end + context 'with user as project maintainer' do + let_it_be(:project) { create(:project).tap { |project| project.add_maintainer(user) } } - context 'with user as project maintainer' do - let_it_be(:project) { create(:project).tap { |project| project.add_maintainer(user) } } + context 'when user views runners page', :js do + before do + visit project_runners_path(project) + end - context 'when user views runners page', :js do - before do - visit project_runners_path(project) - end + it 'user can see a link with instructions on how to install GitLab Runner' do + expect(page).to have_link(s_('Runners|New project runner'), href: new_project_runner_path(project)) + end - it 'user can see a link with instructions on how to install GitLab Runner' do - expect(page).to have_link(s_('Runners|New project runner'), href: new_project_runner_path(project)) - end + it_behaves_like "shows and resets runner registration token" do + let(:dropdown_text) { s_('Runners|Register a project runner') } + let(:registration_token) { project.runners_token } + end + end - it_behaves_like "shows and resets runner registration token" do - let(:dropdown_text) { s_('Runners|Register a project runner') } - let(:registration_token) { project.runners_token } - end + context 'when user views new runner page', :js do + before do + visit new_project_runner_path(project) end - context 'when user views new runner page', :js do - before do - visit new_project_runner_path(project) - end + it_behaves_like 'creates runner and shows register page' do + let(:register_path_pattern) { register_project_runner_path(project, '.*') } + end - it_behaves_like 'creates runner and shows register page' do - let(:register_path_pattern) { register_project_runner_path(project, '.*') } - end + it_behaves_like 'shows locked field' + end + end - it 'shows the locked field' do - expect(page).to have_selector('input[type="checkbox"][name="locked"]') - expect(page).to have_content(_('Lock to current projects')) - end - end + context 'when a project has enabled shared_runners' do + let_it_be(:project) { create(:project) } + + before do + project.add_maintainer(user) end - context 'when a project has enabled shared_runners' do - let_it_be(:project) { create(:project) } + context 'when a project_type runner is activated on the project' do + let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) } - before do - project.add_maintainer(user) - end + it 'user sees the project runner' do + visit project_runners_path(project) - context 'when a project_type runner is activated on the project' do - let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) } + within '[data-testid="assigned_project_runners"]' do + expect(page).to have_content(project_runner.display_name) + end - it 'user sees the project runner' do - visit project_runners_path(project) + click_on project_runner.short_sha - within '[data-testid="assigned_project_runners"]' do - expect(page).to have_content(project_runner.display_name) - end + expect(page).to have_content(project_runner.platform) + end - click_on project_runner.short_sha + it 'user can pause and resume the project runner' do + visit project_runners_path(project) - expect(page).to have_content(project_runner.platform) + within '[data-testid="assigned_project_runners"]' do + expect(page).to have_link('Pause') end - it 'user can pause and resume the project runner' do - visit project_runners_path(project) + click_on 'Pause' - within '[data-testid="assigned_project_runners"]' do - expect(page).to have_link('Pause') - end + within '[data-testid="assigned_project_runners"]' do + expect(page).to have_link('Resume') + end - click_on 'Pause' + click_on 'Resume' - within '[data-testid="assigned_project_runners"]' do - expect(page).to have_link('Resume') - end + within '[data-testid="assigned_project_runners"]' do + expect(page).to have_link('Pause') + end + end - click_on 'Resume' + it 'user removes an activated project runner if this is last project for that runners' do + visit project_runners_path(project) - within '[data-testid="assigned_project_runners"]' do - expect(page).to have_link('Pause') - end + within '[data-testid="assigned_project_runners"]' do + click_on 'Remove runner' end - it 'user removes an activated project runner if this is last project for that runners' do - visit project_runners_path(project) + expect(page).not_to have_content(project_runner.display_name) + end - within '[data-testid="assigned_project_runners"]' do - click_on 'Remove runner' - end + it 'user edits the runner to be protected' do + visit project_runners_path(project) + + within '[data-testid="assigned_project_runners"]' do + first('[data-testid="edit-runner-link"]').click + end + + expect(page.find_field('runner[access_level]')).not_to be_checked + + check 'runner_access_level' + click_button 'Save changes' + + expect(page).to have_content 'Protected Yes' + end - expect(page).not_to have_content(project_runner.display_name) + context 'when a runner has a tag' do + before do + project_runner.update!(tag_list: ['tag']) end - it 'user edits the runner to be protected' do + it 'user edits runner not to run untagged jobs' do visit project_runners_path(project) within '[data-testid="assigned_project_runners"]' do first('[data-testid="edit-runner-link"]').click end - expect(page.find_field('runner[access_level]')).not_to be_checked + expect(page.find_field('runner[run_untagged]')).to be_checked - check 'runner_access_level' + uncheck 'runner_run_untagged' click_button 'Save changes' - expect(page).to have_content 'Protected Yes' + expect(page).to have_content 'Can run untagged jobs No' end + end - context 'when a runner has a tag' do - before do - project_runner.update!(tag_list: ['tag']) - end - - it 'user edits runner not to run untagged jobs' do - visit project_runners_path(project) - - within '[data-testid="assigned_project_runners"]' do - first('[data-testid="edit-runner-link"]').click - end - - expect(page.find_field('runner[run_untagged]')).to be_checked + context 'when a shared runner is activated on the project' do + let!(:shared_runner) { create(:ci_runner, :instance) } - uncheck 'runner_run_untagged' - click_button 'Save changes' + it 'user sees CI/CD setting page' do + visit project_runners_path(project) - expect(page).to have_content 'Can run untagged jobs No' + within '[data-testid="available-shared-runners"]' do + expect(page).to have_content(shared_runner.display_name) end end - context 'when a shared runner is activated on the project' do - let!(:shared_runner) { create(:ci_runner, :instance) } + context 'when multiple shared runners are configured' do + let_it_be(:shared_runner_2) { create(:ci_runner, :instance) } - it 'user sees CI/CD setting page' do + it 'shows the runner count' do visit project_runners_path(project) within '[data-testid="available-shared-runners"]' do - expect(page).to have_content(shared_runner.display_name) + expect(page).to have_content format(_('Available shared runners: %{count}'), { count: 2 }) end end - context 'when multiple shared runners are configured' do - let_it_be(:shared_runner_2) { create(:ci_runner, :instance) } + it 'adds pagination to the shared runner list' do + stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1) - it 'shows the runner count' do - visit project_runners_path(project) + visit project_runners_path(project) - within '[data-testid="available-shared-runners"]' do - expect(page).to have_content format(_('Available shared runners: %{count}'), { count: 2 }) - end + within '[data-testid="available-shared-runners"]' do + expect(find('.pagination')).not_to be_nil end + end + end + end - it 'adds pagination to the shared runner list' do - stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1) + context 'when multiple project runners are configured' do + let!(:project_runner_2) { create(:ci_runner, :project, projects: [project]) } - visit project_runners_path(project) + it 'adds pagination to the runner list' do + stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1) - within '[data-testid="available-shared-runners"]' do - expect(find('.pagination')).not_to be_nil - end - end - end + visit project_runners_path(project) + + expect(find('.pagination')).not_to be_nil end + end + end - context 'when multiple project runners are configured' do - let!(:project_runner_2) { create(:ci_runner, :project, projects: [project]) } + context 'when a project runner exists in another project' do + let(:another_project) { create(:project) } + let!(:project_runner) { create(:ci_runner, :project, projects: [another_project]) } - it 'adds pagination to the runner list' do - stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1) + before do + another_project.add_maintainer(user) + end - visit project_runners_path(project) + it 'user enables and disables a project runner' do + visit project_runners_path(project) - expect(find('.pagination')).not_to be_nil - end + within '[data-testid="available_project_runners"]' do + click_on 'Enable for this project' + end + + expect(page.find('[data-testid="assigned_project_runners"]')).to have_content(project_runner.display_name) + + within '[data-testid="assigned_project_runners"]' do + click_on 'Disable for this project' end + + expect(page.find('[data-testid="available_project_runners"]')).to have_content(project_runner.display_name) end + end - context 'when a project runner exists in another project' do - let(:another_project) { create(:project) } - let!(:project_runner) { create(:ci_runner, :project, projects: [another_project]) } + context 'shared runner text' do + context 'when application settings have shared_runners_text' do + let(:shared_runners_text) { 'custom **shared** runners description' } + let(:shared_runners_html) { 'custom shared runners description' } before do - another_project.add_maintainer(user) + stub_application_setting(shared_runners_text: shared_runners_text) end - it 'user enables and disables a project runner' do + it 'user sees shared runners description' do visit project_runners_path(project) - within '[data-testid="available_project_runners"]' do - click_on 'Enable for this project' + page.within("[data-testid='shared-runners-description']") do + expect(page).not_to have_content('The same shared runner executes code from multiple projects') + expect(page).to have_content(shared_runners_html) end - - expect(page.find('[data-testid="assigned_project_runners"]')).to have_content(project_runner.display_name) - - within '[data-testid="assigned_project_runners"]' do - click_on 'Disable for this project' - end - - expect(page.find('[data-testid="available_project_runners"]')).to have_content(project_runner.display_name) end end - context 'shared runner text' do - context 'when application settings have shared_runners_text' do - let(:shared_runners_text) { 'custom **shared** runners description' } - let(:shared_runners_html) { 'custom shared runners description' } + context 'when application settings have an unsafe link in shared_runners_text' do + let(:shared_runners_text) { '<a href="javascript:alert(\'xss\')">link</a>' } - before do - stub_application_setting(shared_runners_text: shared_runners_text) - end + before do + stub_application_setting(shared_runners_text: shared_runners_text) + end - it 'user sees shared runners description' do - visit project_runners_path(project) + it 'user sees no link' do + visit project_runners_path(project) - page.within("[data-testid='shared-runners-description']") do - expect(page).not_to have_content('The same shared runner executes code from multiple projects') - expect(page).to have_content(shared_runners_html) - end + page.within("[data-testid='shared-runners-description']") do + expect(page).to have_content('link') + expect(page).not_to have_link('link') end end + end - context 'when application settings have an unsafe link in shared_runners_text' do - let(:shared_runners_text) { '<a href="javascript:alert(\'xss\')">link</a>' } + context 'when application settings have an unsafe image in shared_runners_text' do + let(:shared_runners_text) { '<img src="404.png" onerror="alert(\'xss\')"/>' } - before do - stub_application_setting(shared_runners_text: shared_runners_text) - end + before do + stub_application_setting(shared_runners_text: shared_runners_text) + end - it 'user sees no link' do - visit project_runners_path(project) + it 'user sees image safely' do + visit project_runners_path(project) - page.within("[data-testid='shared-runners-description']") do - expect(page).to have_content('link') - expect(page).not_to have_link('link') - end + page.within("[data-testid='shared-runners-description']") do + expect(page).to have_css('img') + expect(page).not_to have_css('img[onerror]') end end + end + end + end - context 'when application settings have an unsafe image in shared_runners_text' do - let(:shared_runners_text) { '<img src="404.png" onerror="alert(\'xss\')"/>' } + context 'enable shared runners in project settings', :js do + before do + project.add_maintainer(user) - before do - stub_application_setting(shared_runners_text: shared_runners_text) - end + visit project_runners_path(project) + end - it 'user sees image safely' do - visit project_runners_path(project) + context 'when a project has enabled shared_runners' do + let(:project) { create(:project, shared_runners_enabled: true) } - page.within("[data-testid='shared-runners-description']") do - expect(page).to have_css('img') - expect(page).not_to have_css('img[onerror]') - end - end - end + it 'shared runners toggle is on' do + expect(page).to have_selector('[data-testid="toggle-shared-runners"]') + expect(page).to have_selector('[data-testid="toggle-shared-runners"] .is-checked') end end - context 'enable shared runners in project settings', :js do - before do - project.add_maintainer(user) + context 'when a project has disabled shared_runners' do + let(:project) { create(:project, shared_runners_enabled: false) } - visit project_runners_path(project) + it 'shared runners toggle is off' do + expect(page).not_to have_selector('[data-testid="toggle-shared-runners"] .is-checked') end + end + end - context 'when a project has enabled shared_runners' do - let(:project) { create(:project, shared_runners_enabled: true) } + context 'group runners in project settings' do + before do + project.add_maintainer(user) + end - it 'shared runners toggle is on' do - expect(page).to have_selector('[data-testid="toggle-shared-runners"]') - expect(page).to have_selector('[data-testid="toggle-shared-runners"] .is-checked') - end + let_it_be(:group) { create :group } + let_it_be(:project) { create :project, group: group } + + context 'as project and group maintainer' do + before do + group.add_maintainer(user) end - context 'when a project has disabled shared_runners' do - let(:project) { create(:project, shared_runners_enabled: false) } + context 'project with a group but no group runner' do + it 'group runners are not available' do + visit project_runners_path(project) - it 'shared runners toggle is off' do - expect(page).not_to have_selector('[data-testid="toggle-shared-runners"] .is-checked') + expect(page).not_to have_content 'To register them, go to the group\'s Runners page.' + expect(page).to have_content 'Ask your group owner to set up a group runner' end end end - context 'group runners in project settings' do + context 'as project maintainer and group owner' do before do - project.add_maintainer(user) + group.add_owner(user) end - let_it_be(:group) { create :group } - let_it_be(:project) { create :project, group: group } + context 'project with a group but no group runner' do + it 'group runners are available' do + visit project_runners_path(project) - context 'as project and group maintainer' do - before do - group.add_maintainer(user) + expect(page).to have_content 'This group does not have any group runners yet.' + + expect(page).to have_content 'To register them, go to the group\'s Runners page.' + expect(page).not_to have_content 'Ask your group owner to set up a group runner' end + end + end - context 'project with a group but no group runner' do - it 'group runners are not available' do - visit project_runners_path(project) + context 'as project maintainer' do + context 'project without a group' do + let(:project) { create :project } - expect(page).not_to have_content 'To register them, go to the group\'s Runners page.' - expect(page).to have_content 'Ask your group owner to set up a group runner' - end + it 'group runners are not available' do + visit project_runners_path(project) + + expect(page).to have_content 'This project does not belong to a group and cannot make use of group runners.' end end - context 'as project maintainer and group owner' do - before do - group.add_owner(user) - end + context 'with group project' do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } context 'project with a group but no group runner' do - it 'group runners are available' do + it 'group runners are not available' do visit project_runners_path(project) expect(page).to have_content 'This group does not have any group runners yet.' - expect(page).to have_content 'To register them, go to the group\'s Runners page.' - expect(page).not_to have_content 'Ask your group owner to set up a group runner' + expect(page).not_to have_content 'To register them, go to the group\'s Runners page.' + expect(page).to have_content 'Ask your group owner to set up a group runner.' end end - end - context 'as project maintainer' do - context 'project without a group' do - let(:project) { create :project } + context 'project with a group and a group runner' do + let_it_be(:group_runner) do + create(:ci_runner, :group, groups: [group], description: 'group-runner') + end - it 'group runners are not available' do + it 'group runners are available' do visit project_runners_path(project) - expect(page).to have_content 'This project does not belong to a group and cannot make use of group runners.' + expect(page).to have_content 'Available group runners: 1' + expect(page).to have_content 'group-runner' end - end - context 'with group project' do - let_it_be(:group) { create(:group) } - let_it_be(:project) { create(:project, group: group) } + it 'group runners may be disabled for a project' do + visit project_runners_path(project) - context 'project with a group but no group runner' do - it 'group runners are not available' do - visit project_runners_path(project) + click_on 'Disable group runners' - expect(page).to have_content 'This group does not have any group runners yet.' + expect(page).to have_content 'Enable group runners' + expect(project.reload.group_runners_enabled).to be false - expect(page).not_to have_content 'To register them, go to the group\'s Runners page.' - expect(page).to have_content 'Ask your group owner to set up a group runner.' - end - end + click_on 'Enable group runners' - context 'project with a group and a group runner' do - let_it_be(:group_runner) do - create(:ci_runner, :group, groups: [group], description: 'group-runner') - end + expect(page).to have_content 'Disable group runners' + expect(project.reload.group_runners_enabled).to be true + end - it 'group runners are available' do - visit project_runners_path(project) + context 'when multiple group runners are configured' do + let_it_be(:group_runner_2) { create(:ci_runner, :group, groups: [group]) } - expect(page).to have_content 'Available group runners: 1' - expect(page).to have_content 'group-runner' - end - - it 'group runners may be disabled for a project' do + it 'shows the runner count' do visit project_runners_path(project) - click_on 'Disable group runners' - - expect(page).to have_content 'Enable group runners' - expect(project.reload.group_runners_enabled).to be false - - click_on 'Enable group runners' - - expect(page).to have_content 'Disable group runners' - expect(project.reload.group_runners_enabled).to be true - end - - context 'when multiple group runners are configured' do - let_it_be(:group_runner_2) { create(:ci_runner, :group, groups: [group]) } - - it 'shows the runner count' do - visit project_runners_path(project) - - within '[data-testid="group-runners"]' do - expect(page).to have_content format(_('Available group runners: %{runners}'), { runners: 2 }) - end + within '[data-testid="group-runners"]' do + expect(page).to have_content format(_('Available group runners: %{runners}'), { runners: 2 }) end + end - it 'adds pagination to the group runner list' do - stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1) + it 'adds pagination to the group runner list' do + stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1) - visit project_runners_path(project) + visit project_runners_path(project) - within '[data-testid="group-runners"]' do - expect(find('.pagination')).not_to be_nil - end + within '[data-testid="group-runners"]' do + expect(find('.pagination')).not_to be_nil end end end diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb index 976324a5032..d2847203669 100644 --- a/spec/features/search/user_searches_for_code_spec.rb +++ b/spec/features/search/user_searches_for_code_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'User searches for code', :js, :disable_rate_limiter, feature_cat using RSpec::Parameterized::TableSyntax include ListboxHelpers - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be_with_reload(:project) { create(:project, :repository, namespace: user.namespace) } context 'when signed in' do diff --git a/spec/features/search/user_searches_for_comments_spec.rb b/spec/features/search/user_searches_for_comments_spec.rb index f7af1797c71..f47e692c652 100644 --- a/spec/features/search/user_searches_for_comments_spec.rb +++ b/spec/features/search/user_searches_for_comments_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'User searches for comments', :js, :disable_rate_limiter, feature_category: :global_search do let_it_be(:project) { create(:project, :repository) } - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } before do project.add_reporter(user) diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb index 724daf9277d..140d8763813 100644 --- a/spec/features/search/user_searches_for_commits_spec.rb +++ b/spec/features/search/user_searches_for_commits_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User searches for commits', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, :repository) } let(:sha) { '6d394385cf567f80a8fd85055db1ab4c5295806f' } diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb index 9451e337db1..d816b393cce 100644 --- a/spec/features/search/user_searches_for_issues_spec.rb +++ b/spec/features/search/user_searches_for_issues_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User searches for issues', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, namespace: user.namespace) } let!(:issue1) { create(:issue, title: 'issue Foo', project: project, created_at: 1.hour.ago) } diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb index d7b52d9e07a..61af5e86eea 100644 --- a/spec/features/search/user_searches_for_merge_requests_spec.rb +++ b/spec/features/search/user_searches_for_merge_requests_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User searches for merge requests', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, namespace: user.namespace) } let_it_be(:merge_request1) { create(:merge_request, title: 'Merge Request Foo', source_project: project, target_project: project, created_at: 1.hour.ago) } let_it_be(:merge_request2) { create(:merge_request, :simple, title: 'Merge Request Bar', source_project: project, target_project: project) } diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb index 7ca7958f61b..ad62c8eb3da 100644 --- a/spec/features/search/user_searches_for_milestones_spec.rb +++ b/spec/features/search/user_searches_for_milestones_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'User searches for milestones', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, namespace: user.namespace) } let_it_be(:milestone1) { create(:milestone, title: 'Foo', project: project) } let_it_be(:milestone2) { create(:milestone, title: 'Bar', project: project) } diff --git a/spec/features/search/user_searches_for_projects_spec.rb b/spec/features/search/user_searches_for_projects_spec.rb index 48a94161927..51e5ad85e2b 100644 --- a/spec/features/search/user_searches_for_projects_spec.rb +++ b/spec/features/search/user_searches_for_projects_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'User searches for projects', :js, :disable_rate_limiter, feature context 'when signed out' do context 'when block_anonymous_global_searches is disabled' do before do - stub_feature_flags(block_anonymous_global_searches: false) + stub_feature_flags(block_anonymous_global_searches: false, super_sidebar_logged_out: false) end include_examples 'top right search form' diff --git a/spec/features/search/user_searches_for_users_spec.rb b/spec/features/search/user_searches_for_users_spec.rb index e0a07c5103d..b52f6aeba68 100644 --- a/spec/features/search/user_searches_for_users_spec.rb +++ b/spec/features/search/user_searches_for_users_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' RSpec.describe 'User searches for users', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - let_it_be(:user1) { create(:user, username: 'gob_bluth', name: 'Gob Bluth') } - let_it_be(:user2) { create(:user, username: 'michael_bluth', name: 'Michael Bluth') } - let_it_be(:user3) { create(:user, username: 'gob_2018', name: 'George Oscar Bluth') } + let_it_be(:user1) { create(:user, :no_super_sidebar, username: 'gob_bluth', name: 'Gob Bluth') } + let_it_be(:user2) { create(:user, :no_super_sidebar, username: 'michael_bluth', name: 'Michael Bluth') } + let_it_be(:user3) { create(:user, :no_super_sidebar, username: 'gob_2018', name: 'George Oscar Bluth') } before do sign_in(user1) diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb index 65f262075f9..a5b63243d0b 100644 --- a/spec/features/search/user_searches_for_wiki_pages_spec.rb +++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'User searches for wiki pages', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) } let_it_be(:wiki_page) do create(:wiki_page, wiki: project.wiki, title: 'directory/title', content: 'Some Wiki content') diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb index 71d0f8d6d7f..3f2a71b63dc 100644 --- a/spec/features/search/user_uses_header_search_field_spec.rb +++ b/spec/features/search/user_uses_header_search_field_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'User uses header search field', :js, :disable_rate_limiter, feat include FilteredSearchHelpers let_it_be(:project) { create(:project, :repository) } - let_it_be(:reporter) { create(:user) } - let_it_be(:developer) { create(:user) } + let_it_be(:reporter) { create(:user, :no_super_sidebar) } + let_it_be(:developer) { create(:user, :no_super_sidebar) } let(:user) { reporter } diff --git a/spec/features/sentry_js_spec.rb b/spec/features/sentry_js_spec.rb index d3880011914..0cf32864b1e 100644 --- a/spec/features/sentry_js_spec.rb +++ b/spec/features/sentry_js_spec.rb @@ -41,6 +41,7 @@ RSpec.describe 'Sentry', feature_category: :error_tracking do it 'loads sentry if sentry settings are enabled', :js do allow(Gitlab::CurrentSettings).to receive(:sentry_enabled).and_return(true) + allow(Gitlab::CurrentSettings).to receive(:sentry_clientside_dsn).and_return('https://mockdsn@example.com/1') visit new_user_session_path diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb index 0268c8ad0d4..08d2d0575eb 100644 --- a/spec/features/signed_commits_spec.rb +++ b/spec/features/signed_commits_spec.rb @@ -2,8 +2,8 @@ require 'spec_helper' -RSpec.describe 'GPG signed commits', feature_category: :source_code_management do - let(:project) { create(:project, :public, :repository) } +RSpec.describe 'GPG signed commits', :js, feature_category: :source_code_management do + let_it_be(:project) { create(:project, :public, :repository) } it 'changes from unverified to verified when the user changes their email to match the gpg key', :sidekiq_might_not_need_inline do ref = GpgHelpers::SIGNED_AND_AUTHORED_SHA @@ -47,7 +47,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d expect(page).to have_selector('.gl-badge', text: 'Verified') end - context 'shows popover badges', :js do + context 'shows popover badges' do let(:user_1) do create :user, email: GpgHelpers::User1.emails.first, username: 'nannie.bernhard', name: 'Nannie Bernhard' end @@ -163,7 +163,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d end end - context 'view signed commit on the tree view', :js do + context 'view signed commit on the tree view' do shared_examples 'a commit with a signature' do before do visit project_tree_path(project, 'signed-commits') diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb index afb53c563de..7a07299a14f 100644 --- a/spec/features/snippets/search_snippets_spec.rb +++ b/spec/features/snippets/search_snippets_spec.rb @@ -4,10 +4,11 @@ require 'spec_helper' RSpec.describe 'Search Snippets', :js, feature_category: :global_search do it 'user searches for snippets by title' do + user = create(:user, :no_super_sidebar) public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle') - private_snippet = create(:personal_snippet, :private, title: 'Middle and End') + private_snippet = create(:personal_snippet, :private, title: 'Middle and End', author: user) - sign_in private_snippet.author + sign_in user visit dashboard_snippets_path submit_search('Middle') diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb index 2673ad5e1d7..bbb120edb80 100644 --- a/spec/features/snippets/show_spec.rb +++ b/spec/features/snippets/show_spec.rb @@ -3,9 +3,13 @@ require 'spec_helper' RSpec.describe 'Snippet', :js, feature_category: :source_code_management do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let_it_be(:snippet) { create(:personal_snippet, :public, :repository, author: user) } + before do + stub_feature_flags(super_sidebar_logged_out: false) + end + it_behaves_like 'show and render proper snippet blob' do let(:anchor) { nil } @@ -36,7 +40,7 @@ RSpec.describe 'Snippet', :js, feature_category: :source_code_management do end context 'when authenticated as a different user' do - let_it_be(:different_user) { create(:user) } + let_it_be(:different_user) { create(:user, :no_super_sidebar) } before do sign_in(different_user) diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index 090d854081a..341cc150a64 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'User creates snippet', :js, feature_category: :source_code_manag include DropzoneHelper include Features::SnippetSpecHelpers - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } let(:title) { 'My Snippet Title' } let(:file_content) { 'Hello World!' } @@ -130,7 +130,7 @@ RSpec.describe 'User creates snippet', :js, feature_category: :source_code_manag expect(page).not_to have_content(files_validation_message) end - it 'previews a snippet with file', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/408203' do + it 'previews a snippet with file' do # Click placeholder first to expand full description field snippet_fill_in_description('My Snippet') dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif') @@ -145,7 +145,11 @@ RSpec.describe 'User creates snippet', :js, feature_category: :source_code_manag # Adds a cache buster for checking if the image exists as Selenium is now handling the cached requests # not anymore as requests when they come straight from memory cache. # accept_confirm is needed because of https://gitlab.com/gitlab-org/gitlab/-/issues/262102 - reqs = inspect_requests { accept_confirm { visit("#{link}?ran=#{SecureRandom.base64(20)}") } } + reqs = inspect_requests do + visit("#{link}?ran=#{SecureRandom.base64(20)}") do + page.driver.browser.switch_to.alert.accept + end + end expect(reqs.first.status_code).to eq(200) end end diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb index beadeab1736..24d63cadf00 100644 --- a/spec/features/task_lists_spec.rb +++ b/spec/features/task_lists_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'Task Lists', :js, feature_category: :team_planning do include Warden::Test::Helpers let_it_be(:project) { create(:project, :public, :repository) } - let_it_be(:user) { create(:user) } - let_it_be(:user2) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:user2) { create(:user, :no_super_sidebar) } let(:markdown) do <<-MARKDOWN.strip_heredoc diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb index 77ef3df97f6..b78efa65888 100644 --- a/spec/features/unsubscribe_links_spec.rb +++ b/spec/features/unsubscribe_links_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'Unsubscribe links', :sidekiq_inline, feature_category: :shared d include Warden::Test::Helpers let_it_be(:project) { create(:project, :public) } - let_it_be(:author) { create(:user).tap { |u| project.add_reporter(u) } } - let_it_be(:recipient) { create(:user) } + let_it_be(:author) { create(:user, :no_super_sidebar).tap { |u| project.add_reporter(u) } } + let_it_be(:recipient) { create(:user, :no_super_sidebar) } let(:params) { { title: 'A bug!', description: 'Fix it!', assignee_ids: [recipient.id] } } let(:issue) { Issues::CreateService.new(container: project, current_user: author, params: params).execute[:issue] } @@ -22,6 +22,10 @@ RSpec.describe 'Unsubscribe links', :sidekiq_inline, feature_category: :shared d end context 'when logged out' do + before do + stub_feature_flags(super_sidebar_logged_out: false) + end + context 'when visiting the link from the body' do it 'shows the unsubscribe confirmation page and redirects to root path when confirming' do visit body_link diff --git a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb index cd181f73473..5de544e866e 100644 --- a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb +++ b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User uploads avatar to profile', feature_category: :user_profile do - let!(:user) { create(:user) } + let!(:user) { create(:user, :no_super_sidebar) } let(:avatar_file_path) { Rails.root.join('spec', 'fixtures', 'dk.png') } shared_examples 'upload avatar' do diff --git a/spec/features/usage_stats_consent_spec.rb b/spec/features/usage_stats_consent_spec.rb index c446fe1531b..92f7a944007 100644 --- a/spec/features/usage_stats_consent_spec.rb +++ b/spec/features/usage_stats_consent_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Usage stats consent', feature_category: :service_ping do context 'when signed in' do - let(:user) { create(:admin, created_at: 8.days.ago) } + let(:user) { create(:admin, :no_super_sidebar, created_at: 8.days.ago) } let(:message) { 'To help improve GitLab, we would like to periodically collect usage information.' } before do diff --git a/spec/features/users/active_sessions_spec.rb b/spec/features/users/active_sessions_spec.rb index 53a4c8a91e9..663d2283dbd 100644 --- a/spec/features/users/active_sessions_spec.rb +++ b/spec/features/users/active_sessions_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions, feature_category: :system_access do it 'successful login adds a new active user login' do - user = create(:user) + user = create(:user, :no_super_sidebar) now = Time.zone.parse('2018-03-12 09:06') travel_to(now) do @@ -31,7 +31,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions, feature_cat end it 'successful login cleans up obsolete entries' do - user = create(:user) + user = create(:user, :no_super_sidebar) Gitlab::Redis::Sessions.with do |redis| redis.sadd?("session:lookup:user:gitlab:#{user.id}", '59822c7d9fcdfa03725eff41782ad97d') @@ -45,7 +45,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions, feature_cat end it 'sessionless login does not clean up obsolete entries' do - user = create(:user) + user = create(:user, :no_super_sidebar) personal_access_token = create(:personal_access_token, user: user) Gitlab::Redis::Sessions.with do |redis| @@ -61,7 +61,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions, feature_cat end it 'logout deletes the active user login' do - user = create(:user) + user = create(:user, :no_super_sidebar) gitlab_sign_in(user) expect(page).to have_current_path root_path, ignore_query: true diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb index 83473964d6b..368f272ba23 100644 --- a/spec/features/users/anonymous_sessions_spec.rb +++ b/spec/features/users/anonymous_sessions_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state, feature_categor end it 'increases the TTL when the login succeeds' do - user = create(:user) + user = create(:user, :no_super_sidebar) gitlab_sign_in(user) expect(page).to have_content(user.name) diff --git a/spec/features/users/email_verification_on_login_spec.rb b/spec/features/users/email_verification_on_login_spec.rb index 7675de28f86..d83040efd72 100644 --- a/spec/features/users/email_verification_on_login_spec.rb +++ b/spec/features/users/email_verification_on_login_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, :js, feature_category: :system_access do include EmailHelpers - let_it_be_with_reload(:user) { create(:user) } - let_it_be(:another_user) { create(:user) } + let_it_be_with_reload(:user) { create(:user, :no_super_sidebar) } + let_it_be(:another_user) { create(:user, :no_super_sidebar) } let_it_be(:new_email) { build_stubbed(:user).email } let(:require_email_verification_enabled) { user } @@ -220,7 +220,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, shared_examples 'no email verification required when 2fa enabled or ff disabled' do context 'when 2FA is enabled' do - let_it_be(:user) { create(:user, :two_factor) } + let_it_be(:user) { create(:user, :no_super_sidebar, :two_factor) } it_behaves_like 'no email verification required', two_factor_auth: true end @@ -234,8 +234,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, describe 'when failing to login the maximum allowed number of times' do before do - # See comment in RequireEmailVerification::MAXIMUM_ATTEMPTS on why this is divided by 2 - (RequireEmailVerification::MAXIMUM_ATTEMPTS / 2).times do + RequireEmailVerification::MAXIMUM_ATTEMPTS.times do gitlab_sign_in(user, password: 'wrong_password') end end @@ -345,7 +344,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, before do perform_enqueued_jobs do - (User.maximum_attempts / 2).times do + User.maximum_attempts.times do gitlab_sign_in(user, password: 'wrong_password') end end diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 047590fb3aa..c07e419be1f 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ expect(authentication_metrics) .to increment(:user_authenticated_counter) - user = create(:user) + user = create(:user, :no_super_sidebar) expect(user.reset_password_token).to be_nil @@ -43,7 +43,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ # This behavior is dependent on there only being one user User.delete_all - user = create(:admin, password_automatically_set: true) + user = create(:admin, :no_super_sidebar, password_automatically_set: true) visit root_path expect(page).to have_current_path edit_user_password_path, ignore_query: true @@ -77,7 +77,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ .and increment(:user_unauthenticated_counter) .and increment(:user_session_destroyed_counter).twice - user = create(:user, :blocked) + user = create(:user, :no_super_sidebar, :blocked) gitlab_sign_in(user) @@ -90,14 +90,14 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ .and increment(:user_unauthenticated_counter) .and increment(:user_session_destroyed_counter).twice - user = create(:user, :blocked) + user = create(:user, :no_super_sidebar, :blocked) expect { gitlab_sign_in(user) }.not_to change { user.reload.sign_in_count } end end describe 'with an unconfirmed email address' do - let!(:user) { create(:user, confirmed_at: nil) } + let!(:user) { create(:user, :no_super_sidebar, confirmed_at: nil) } let(:grace_period) { 2.days } let(:alert_title) { 'Please confirm your email address' } let(:alert_message) { "To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select Resend confirmation email" } @@ -141,7 +141,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'when resending the confirmation email' do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } it 'redirects to the "almost there" page' do visit new_user_confirmation_path @@ -154,7 +154,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end describe 'with a disallowed password' do - let(:user) { create(:user, :disallowed_password) } + let(:user) { create(:user, :no_super_sidebar, :disallowed_password) } before do expect(authentication_metrics) @@ -180,7 +180,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ .to increment(:user_unauthenticated_counter) .and increment(:user_password_invalid_counter) - gitlab_sign_in(User.ghost) + gitlab_sign_in(Users::Internal.ghost) expect(page).to have_content('Invalid login or password.') end @@ -190,8 +190,8 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ .to increment(:user_unauthenticated_counter) .and increment(:user_password_invalid_counter) - expect { gitlab_sign_in(User.ghost) } - .not_to change { User.ghost.reload.sign_in_count } + expect { gitlab_sign_in(Users::Internal.ghost) } + .not_to change { Users::Internal.ghost.reload.sign_in_count } end end @@ -286,6 +286,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ enter_code(code, only_two_factor_webauthn_enabled: only_two_factor_webauthn_enabled) expect(page).to have_content('Invalid two-factor code.') + expect(user.reload.failed_attempts).to eq(1) end end end @@ -294,7 +295,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ # Freeze time to prevent failures when time between code being entered and # validated greater than otp_allowed_drift context 'with valid username/password', :freeze_time do - let(:user) { create(:user, :two_factor) } + let(:user) { create(:user, :no_super_sidebar, :two_factor) } before do gitlab_sign_in(user, remember: true) @@ -371,13 +372,13 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'when user with TOTP enabled' do - let(:user) { create(:user, :two_factor) } + let(:user) { create(:user, :no_super_sidebar, :two_factor) } include_examples 'can login with recovery codes' end context 'when user with only Webauthn enabled' do - let(:user) { create(:user, :two_factor_via_webauthn, registrations_count: 1) } + let(:user) { create(:user, :no_super_sidebar, :two_factor_via_webauthn, registrations_count: 1) } include_examples 'can login with recovery codes', only_two_factor_webauthn_enabled: true end @@ -468,6 +469,12 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end describe 'without two-factor authentication' do + it 'renders sign in text for providers' do + visit new_user_session_path + + expect(page).to have_content(_('or sign in with')) + end + it 'displays the remember me checkbox' do visit new_user_session_path @@ -487,7 +494,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'with correct username and password' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } it 'allows basic login' do expect(authentication_metrics) @@ -576,8 +583,8 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end end - context 'with invalid username and password' do - let(:user) { create(:user) } + context 'with correct username and invalid password' do + let(:user) { create(:user, :no_super_sidebar) } it 'blocks invalid login' do expect(authentication_metrics) @@ -588,12 +595,13 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ expect_single_session_with_short_ttl expect(page).to have_content('Invalid login or password.') + expect(user.reload.failed_attempts).to eq(1) end end end describe 'with required two-factor authentication enabled' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } # TODO: otp_grace_period_started_at @@ -631,7 +639,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'after the grace period' do - let(:user) { create(:user, otp_grace_period_started_at: 9999.hours.ago) } + let(:user) { create(:user, :no_super_sidebar, otp_grace_period_started_at: 9999.hours.ago) } it 'redirects to two-factor configuration page' do expect(authentication_metrics) @@ -720,7 +728,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'after the grace period' do - let(:user) { create(:user, otp_grace_period_started_at: 9999.hours.ago) } + let(:user) { create(:user, :no_super_sidebar, otp_grace_period_started_at: 9999.hours.ago) } it 'redirects to two-factor configuration page' do expect(authentication_metrics) @@ -911,7 +919,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'when terms are enforced', :js do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do enforce_terms @@ -1082,7 +1090,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions, feature_category: :system_ end context 'when sending confirmation email and not yet confirmed' do - let!(:user) { create(:user, confirmed_at: nil) } + let!(:user) { create(:user, :no_super_sidebar, confirmed_at: nil) } let(:grace_period) { 2.days } let(:alert_title) { 'Please confirm your email address' } let(:alert_message) { "To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select Resend confirmation email" } diff --git a/spec/features/users/logout_spec.rb b/spec/features/users/logout_spec.rb index c9839247e7d..d0e5be8dca3 100644 --- a/spec/features/users/logout_spec.rb +++ b/spec/features/users/logout_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Logout/Sign out', :js, feature_category: :system_access do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb index fdd0c38a718..d1ff60b6069 100644 --- a/spec/features/users/overview_spec.rb +++ b/spec/features/users/overview_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Overview tab on a user profile', :js, feature_category: :user_profile do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } let(:contributed_project) { create(:project, :public, :repository) } def push_code_contribution diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb index 2db58ce04a1..99451ac472d 100644 --- a/spec/features/users/rss_spec.rb +++ b/spec/features/users/rss_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe 'User RSS', feature_category: :user_profile do - let(:user) { create(:user) } - let(:path) { user_path(create(:user)) } + let(:user) { create(:user, :no_super_sidebar) } + let(:path) { user_path(create(:user, :no_super_sidebar)) } describe 'with "user_profile_overflow_menu_vue" feature flag off' do before do @@ -22,6 +22,7 @@ RSpec.describe 'User RSS', feature_category: :user_profile do context 'when signed out' do before do + stub_feature_flags(super_sidebar_logged_out: false) visit path end @@ -45,6 +46,7 @@ RSpec.describe 'User RSS', feature_category: :user_profile do context 'when signed out' do before do + stub_feature_flags(super_sidebar_logged_out: false) visit path end diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index f8653b22377..522eb12f507 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -7,6 +7,10 @@ RSpec.describe 'User page', feature_category: :user_profile do let_it_be(:user) { create(:user, bio: '<b>Lorem</b> <i>ipsum</i> dolor sit <a href="https://example.com">amet</a>') } + before do + stub_feature_flags(super_sidebar_logged_out: false) + end + subject(:visit_profile) { visit(user_path(user)) } context 'with "user_profile_overflow_menu_vue" feature flag enabled', :js do diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb index 450b9fa46b1..111c0cce1b1 100644 --- a/spec/features/users/signup_spec.rb +++ b/spec/features/users/signup_spec.rb @@ -234,7 +234,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do confirm_email - expect(find_field('Username or email').value).to eq(new_user.email) + expect(find_field('Username or primary email').value).to eq(new_user.email) end end @@ -332,7 +332,6 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do click_button 'Register' expect(page).to have_current_path(users_sign_up_welcome_path), ignore_query: true - visit new_project_path select 'Software Developer', from: 'user_role' click_button 'Get started!' @@ -341,7 +340,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do expect(created_user.software_developer_role?).to be_truthy expect(created_user.setup_for_company).to be_nil - expect(page).to have_current_path(new_project_path) + expect(page).to have_current_path(dashboard_projects_path) end it_behaves_like 'Signup name validation', 'new_user_first_name', 127, 'First name' @@ -388,7 +387,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do end end - it 'redirects to step 2 of the signup process, sets the role and redirects back' do + it 'allows visiting of a page after initial registration' do visit new_user_registration_path fill_in_signup_form @@ -397,15 +396,6 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do visit new_project_path - expect(page).to have_current_path(users_sign_up_welcome_path) - - select 'Software Developer', from: 'user_role' - click_button 'Get started!' - - created_user = User.find_by_username(new_user.username) - - expect(created_user.software_developer_role?).to be_truthy - expect(created_user.setup_for_company).to be_nil expect(page).to have_current_path(new_project_path) end diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb index 2876351be37..98ac9fa5f92 100644 --- a/spec/features/users/snippets_spec.rb +++ b/spec/features/users/snippets_spec.rb @@ -4,10 +4,10 @@ require 'spec_helper' RSpec.describe 'Snippets tab on a user profile', :js, feature_category: :source_code_management do context 'when the user has snippets' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do - stub_feature_flags(profile_tabs_vue: false) + stub_feature_flags(profile_tabs_vue: false, super_sidebar_logged_out: false) end context 'pagination' do @@ -30,7 +30,7 @@ RSpec.describe 'Snippets tab on a user profile', :js, feature_category: :source_ let!(:other_snippet) { create(:snippet, :public) } it 'contains only internal and public snippets of a user when a user is logged in' do - sign_in(create(:user)) + sign_in(create(:user, :no_super_sidebar)) visit user_path(user) page.within('.user-profile-nav') { click_link 'Snippets' } wait_for_requests diff --git a/spec/features/users/terms_spec.rb b/spec/features/users/terms_spec.rb index cf62ccaf999..3495af3ae85 100644 --- a/spec/features/users/terms_spec.rb +++ b/spec/features/users/terms_spec.rb @@ -27,7 +27,7 @@ RSpec.describe 'Users > Terms', :js, feature_category: :user_profile do end context 'when user is a project bot' do - let(:project_bot) { create(:user, :project_bot) } + let(:project_bot) { create(:user, :no_super_sidebar, :project_bot) } before do enforce_terms @@ -42,7 +42,7 @@ RSpec.describe 'Users > Terms', :js, feature_category: :user_profile do end context 'when user is a service account' do - let(:service_account) { create(:user, :service_account) } + let(:service_account) { create(:user, :no_super_sidebar, :service_account) } before do enforce_terms @@ -57,7 +57,7 @@ RSpec.describe 'Users > Terms', :js, feature_category: :user_profile do end context 'when signed in' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do sign_in(user) diff --git a/spec/features/users/user_browses_projects_on_user_page_spec.rb b/spec/features/users/user_browses_projects_on_user_page_spec.rb index 8bdc09f3f87..5e047192e7b 100644 --- a/spec/features/users/user_browses_projects_on_user_page_spec.rb +++ b/spec/features/users/user_browses_projects_on_user_page_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Users > User browses projects on user page', :js, feature_category: :groups_and_projects do - let!(:user) { create :user } + let!(:user) { create(:user, :no_super_sidebar) } let!(:private_project) do create :project, :private, name: 'private', namespace: user.namespace do |project| project.add_maintainer(user) @@ -29,7 +29,7 @@ RSpec.describe 'Users > User browses projects on user page', :js, feature_catego end before do - stub_feature_flags(profile_tabs_vue: false) + stub_feature_flags(profile_tabs_vue: false, super_sidebar_logged_out: false) end it 'hides loading spinner after load', :js do @@ -87,7 +87,7 @@ RSpec.describe 'Users > User browses projects on user page', :js, feature_catego end context 'when signed in as another user' do - let(:another_user) { create :user } + let(:another_user) { create(:user, :no_super_sidebar) } before do sign_in(another_user) diff --git a/spec/features/webauthn_spec.rb b/spec/features/webauthn_spec.rb index 5c42facfa8b..52e2b375187 100644 --- a/spec/features/webauthn_spec.rb +++ b/spec/features/webauthn_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor # TODO: it_behaves_like 'hardware device for 2fa', 'WebAuthn' describe 'registration' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do gitlab_sign_in(user) @@ -58,7 +58,8 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor gitlab_sign_out # Second user - user = gitlab_sign_in(:user) + user = create(:user, :no_super_sidebar) + gitlab_sign_in(user) visit profile_account_path enable_two_factor_authentication webauthn_device_registration(webauthn_device: webauthn_device, name: 'My other device', password: user.password) @@ -125,7 +126,7 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor it_behaves_like 'hardware device for 2fa', 'WebAuthn' describe 'registration' do - let(:user) { create(:user) } + let(:user) { create(:user, :no_super_sidebar) } before do gitlab_sign_in(user) @@ -160,7 +161,8 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor gitlab_sign_out # Second user - user = gitlab_sign_in(:user) + user = create(:user, :no_super_sidebar) + gitlab_sign_in(user) user.update_attribute(:otp_required_for_login, true) visit profile_account_path manage_two_factor_authentication @@ -225,7 +227,7 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor describe 'authentication' do let(:otp_required_for_login) { true } - let(:user) { create(:user, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } + let(:user) { create(:user, :no_super_sidebar, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } let!(:webauthn_device) do add_webauthn_device(app_id, user) end @@ -254,7 +256,7 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor describe 'when a given WebAuthn device has already been registered by another user' do describe 'but not the current user' do - let(:other_user) { create(:user, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } + let(:other_user) { create(:user, :no_super_sidebar, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } it 'does not allow logging in with that particular device' do # Register other user with a different WebAuthn device @@ -275,7 +277,8 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor it "allows logging in with that particular device" do pending("support for passing credential options in FakeClient") # Register current user with the same WebAuthn device - current_user = gitlab_sign_in(:user) + current_user = create(:user, :no_super_sidebar) + gitlab_sign_in(current_user) visit profile_account_path manage_two_factor_authentication register_webauthn_device(webauthn_device) diff --git a/spec/features/whats_new_spec.rb b/spec/features/whats_new_spec.rb index 3668d90f2e9..c8bcf5f6ef0 100644 --- a/spec/features/whats_new_spec.rb +++ b/spec/features/whats_new_spec.rb @@ -3,9 +3,13 @@ require "spec_helper" RSpec.describe "renders a `whats new` dropdown item", feature_category: :onboarding do - let_it_be(:user) { create(:user) } + let_it_be(:user) { create(:user, :no_super_sidebar) } context 'when not logged in' do + before do + stub_feature_flags(super_sidebar_logged_out: false) + end + it 'and on SaaS it renders', :saas do visit user_path(user) |