diff options
Diffstat (limited to 'spec/features')
84 files changed, 1006 insertions, 722 deletions
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb index 9b74aa2ac5a..88b8fcd8d5e 100644 --- a/spec/features/admin/admin_deploy_keys_spec.rb +++ b/spec/features/admin/admin_deploy_keys_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'admin deploy keys' do +RSpec.describe 'admin deploy keys', :js do include Spec::Support::Helpers::ModalHelpers let_it_be(:admin) { create(:admin) } @@ -15,112 +15,81 @@ RSpec.describe 'admin deploy keys' do gitlab_enable_admin_mode_sign_in(admin) end - shared_examples 'renders deploy keys correctly' do - it 'show all public deploy keys' do - visit admin_deploy_keys_path + it 'show all public deploy keys' do + visit admin_deploy_keys_path - page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do - expect(page).to have_content(deploy_key.title) - expect(page).to have_content(another_deploy_key.title) - end + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do + expect(page).to have_content(deploy_key.title) + expect(page).to have_content(another_deploy_key.title) end + end - it 'shows all the projects the deploy key has write access' do - write_key = create(:deploy_keys_project, :write_access, deploy_key: deploy_key) + it 'shows all the projects the deploy key has write access' do + write_key = create(:deploy_keys_project, :write_access, deploy_key: deploy_key) - visit admin_deploy_keys_path + visit admin_deploy_keys_path - page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do - expect(page).to have_content(write_key.project.full_name) - end + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do + expect(page).to have_content(write_key.project.full_name) end + end - describe 'create a new deploy key' do - let(:new_ssh_key) { attributes_for(:key)[:key] } - - before do - visit admin_deploy_keys_path - click_link 'New deploy key' - end - - it 'creates a new deploy key' do - fill_in 'deploy_key_title', with: 'laptop' - fill_in 'deploy_key_key', with: new_ssh_key - click_button 'Create' - - expect(current_path).to eq admin_deploy_keys_path + describe 'create a new deploy key' do + let(:new_ssh_key) { attributes_for(:key)[:key] } - page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do - expect(page).to have_content('laptop') - end - end + before do + visit admin_deploy_keys_path + click_link 'New deploy key' end - describe 'update an existing deploy key' do - before do - visit admin_deploy_keys_path - page.within('tr', text: deploy_key.title) do - click_link(_('Edit deploy key')) - end - end + it 'creates a new deploy key' do + fill_in 'deploy_key_title', with: 'laptop' + fill_in 'deploy_key_key', with: new_ssh_key + click_button 'Create' - it 'updates an existing deploy key' do - fill_in 'deploy_key_title', with: 'new-title' - click_button 'Save changes' + expect(current_path).to eq admin_deploy_keys_path - expect(current_path).to eq admin_deploy_keys_path - - page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do - expect(page).to have_content('new-title') - end + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do + expect(page).to have_content('laptop') end end end - context 'when `admin_deploy_keys_vue` feature flag is enabled', :js do - it_behaves_like 'renders deploy keys correctly' - - describe 'remove an existing deploy key' do - before do - visit admin_deploy_keys_path + describe 'update an existing deploy key' do + before do + visit admin_deploy_keys_path + page.within('tr', text: deploy_key.title) do + click_link(_('Edit deploy key')) end + end - it 'removes an existing deploy key' do - accept_gl_confirm('Are you sure you want to delete this deploy key?', button_text: 'Delete') do - page.within('tr', text: deploy_key.title) do - click_button _('Delete deploy key') - end - end + it 'updates an existing deploy key' do + fill_in 'deploy_key_title', with: 'new-title' + click_button 'Save changes' - expect(current_path).to eq admin_deploy_keys_path - page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do - expect(page).not_to have_content(deploy_key.title) - end + expect(current_path).to eq admin_deploy_keys_path + + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do + expect(page).to have_content('new-title') end end end - context 'when `admin_deploy_keys_vue` feature flag is disabled' do + describe 'remove an existing deploy key' do before do - stub_feature_flags(admin_deploy_keys_vue: false) + visit admin_deploy_keys_path end - it_behaves_like 'renders deploy keys correctly' - - describe 'remove an existing deploy key' do - before do - visit admin_deploy_keys_path - end - - it 'removes an existing deploy key' do + it 'removes an existing deploy key' do + accept_gl_confirm('Are you sure you want to delete this deploy key?', button_text: 'Delete') do page.within('tr', text: deploy_key.title) do - click_link _('Remove deploy key') + click_button _('Delete deploy key') end + end - expect(current_path).to eq admin_deploy_keys_path - page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do - expect(page).not_to have_content(deploy_key.title) - end + expect(current_path).to eq admin_deploy_keys_path + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do + expect(page).not_to have_content(deploy_key.title) end end end diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 86d60b5d483..ba0870a53ae 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'admin issues labels' do + include Spec::Support::Helpers::ModalHelpers + let!(:bug_label) { Label.create!(title: 'bug', template: true) } let!(:feature_label) { Label.create!(title: 'feature', template: true) } @@ -59,7 +61,7 @@ RSpec.describe 'admin issues labels' do it 'creates new label' do fill_in 'Title', with: 'support' fill_in 'Background color', with: '#F95610' - click_button 'Save' + click_button 'Create label' page.within '.manage-labels-list' do expect(page).to have_content('support') @@ -69,7 +71,7 @@ RSpec.describe 'admin issues labels' do it 'does not creates label with invalid color' do fill_in 'Title', with: 'support' fill_in 'Background color', with: '#12' - click_button 'Save' + click_button 'Create label' page.within '.label-form' do expect(page).to have_content('Color must be a valid color code') @@ -79,7 +81,7 @@ RSpec.describe 'admin issues labels' do it 'does not creates label if label already exists' do fill_in 'Title', with: 'bug' fill_in 'Background color', with: '#F95610' - click_button 'Save' + click_button 'Create label' page.within '.label-form' do expect(page).to have_content 'Title has already been taken' @@ -93,11 +95,25 @@ RSpec.describe 'admin issues labels' do fill_in 'Title', with: 'fix' fill_in 'Background color', with: '#F15610' - click_button 'Save' + click_button 'Save changes' page.within '.manage-labels-list' do expect(page).to have_content('fix') end end + + it 'allows user to delete label', :js do + visit edit_admin_label_path(bug_label) + + click_button 'Delete' + + within_modal do + expect(page).to have_content("#{bug_label.title} will be permanently deleted. This cannot be undone.") + + click_link 'Delete label' + end + + expect(page).to have_content('Label was removed') + end end end diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index cc2d36221dc..ceb91b86876 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -21,12 +21,16 @@ RSpec.describe "Admin Runners" do context "when there are runners" do it 'has all necessary texts' do - create(:ci_runner, :instance, contacted_at: Time.now) + create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: Time.now) + create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: 1.week.ago) + create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: 1.year.ago) visit admin_runners_path expect(page).to have_text "Register an instance runner" - expect(page).to have_text "Online Runners 1" + expect(page).to have_text "Online runners 1" + expect(page).to have_text "Offline runners 2" + expect(page).to have_text "Stale runners 1" end it 'with an instance runner shows an instance badge' do @@ -131,6 +135,9 @@ RSpec.describe "Admin Runners" do it 'shows correct runner when description matches' do input_filtered_search_keys('runner-foo') + expect(page).to have_link('All 1') + expect(page).to have_link('Instance 1') + expect(page).to have_content("runner-foo") expect(page).not_to have_content("runner-bar") end @@ -138,71 +145,78 @@ RSpec.describe "Admin Runners" do it 'shows no runner when description does not match' do input_filtered_search_keys('runner-baz') + expect(page).to have_link('All 0') + expect(page).to have_link('Instance 0') + expect(page).to have_text 'No runners found' end end describe 'filter by status' do - it 'shows correct runner when status matches' do - create(:ci_runner, :instance, description: 'runner-active', active: true) - create(:ci_runner, :instance, description: 'runner-paused', active: false) + let!(:never_contacted) { create(:ci_runner, :instance, description: 'runner-never-contacted', contacted_at: nil) } + + before do + create(:ci_runner, :instance, description: 'runner-1', contacted_at: Time.now) + create(:ci_runner, :instance, description: 'runner-2', contacted_at: Time.now) + create(:ci_runner, :instance, description: 'runner-paused', active: false, contacted_at: Time.now) visit admin_runners_path + end - expect(page).to have_content 'runner-active' + it 'shows all runners' do + expect(page).to have_content 'runner-1' + expect(page).to have_content 'runner-2' expect(page).to have_content 'runner-paused' + expect(page).to have_content 'runner-never-contacted' + expect(page).to have_link('All 4') + end + + it 'shows correct runner when status matches' do input_filtered_search_filter_is_only('Status', 'Active') - expect(page).to have_content 'runner-active' + expect(page).to have_link('All 3') + + expect(page).to have_content 'runner-1' + expect(page).to have_content 'runner-2' + expect(page).to have_content 'runner-never-contacted' expect(page).not_to have_content 'runner-paused' end it 'shows no runner when status does not match' do - create(:ci_runner, :instance, description: 'runner-active', active: true) - create(:ci_runner, :instance, description: 'runner-paused', active: false) + input_filtered_search_filter_is_only('Status', 'Stale') - visit admin_runners_path - - input_filtered_search_filter_is_only('Status', 'Online') - - expect(page).not_to have_content 'runner-active' - expect(page).not_to have_content 'runner-paused' + expect(page).to have_link('All 0') expect(page).to have_text 'No runners found' end it 'shows correct runner when status is selected and search term is entered' do - create(:ci_runner, :instance, description: 'runner-a-1', active: true) - create(:ci_runner, :instance, description: 'runner-a-2', active: false) - create(:ci_runner, :instance, description: 'runner-b-1', active: true) - - visit admin_runners_path - input_filtered_search_filter_is_only('Status', 'Active') + input_filtered_search_keys('runner-1') - expect(page).to have_content 'runner-a-1' - expect(page).to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' - - input_filtered_search_keys('runner-a') + expect(page).to have_link('All 1') - expect(page).to have_content 'runner-a-1' - expect(page).not_to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + expect(page).to have_content 'runner-1' + expect(page).not_to have_content 'runner-2' + expect(page).not_to have_content 'runner-never-contacted' + expect(page).not_to have_content 'runner-paused' end - it 'shows correct runner when type is selected and search term is entered' do - create(:ci_runner, :instance, description: 'runner-connected', contacted_at: Time.now) - create(:ci_runner, :instance, description: 'runner-not-connected', contacted_at: nil) + it 'shows correct runner when status filter is entered' do + # use the string "Never" to avoid using space and trigger an early selection + input_filtered_search_filter_is_only('Status', 'Never') - visit admin_runners_path + expect(page).to have_link('All 1') - # use the string "Not" to avoid using space and trigger an early selection - input_filtered_search_filter_is_only('Status', 'Not') + expect(page).not_to have_content 'runner-1' + expect(page).not_to have_content 'runner-2' + expect(page).not_to have_content 'runner-paused' + expect(page).to have_content 'runner-never-contacted' - expect(page).not_to have_content 'runner-connected' - expect(page).to have_content 'runner-not-connected' + within "[data-testid='runner-row-#{never_contacted.id}']" do + expect(page).to have_selector '.badge', text: 'never contacted' + end end end @@ -215,6 +229,10 @@ RSpec.describe "Admin Runners" do it '"All" tab is selected by default' do visit admin_runners_path + expect(page).to have_link('All 2') + expect(page).to have_link('Group 1') + expect(page).to have_link('Project 1') + page.within('[data-testid="runner-type-tabs"]') do expect(page).to have_link('All', class: 'active') end @@ -373,9 +391,28 @@ RSpec.describe "Admin Runners" do it 'has all necessary texts including no runner message' do expect(page).to have_text "Register an instance runner" - expect(page).to have_text "Online Runners 0" + + expect(page).to have_text "Online runners 0" + expect(page).to have_text "Offline runners 0" + expect(page).to have_text "Stale runners 0" + expect(page).to have_text 'No runners found' end + + it 'shows tabs with total counts equal to 0' do + expect(page).to have_link('All 0') + expect(page).to have_link('Instance 0') + expect(page).to have_link('Group 0') + expect(page).to have_link('Project 0') + end + end + + context "when visiting outdated URLs" do + it 'updates NOT_CONNECTED runner status to NEVER_CONNECTED' do + visit admin_runners_path('status[]': 'NOT_CONNECTED') + + expect(page).to have_current_path(admin_runners_path('status[]': 'NEVER_CONTACTED') ) + end end describe 'runners registration' do @@ -422,7 +459,9 @@ RSpec.describe "Admin Runners" do before do click_on 'Reset registration token' - page.accept_alert + within_modal do + click_button('OK', match: :first) + end wait_for_requests end @@ -437,26 +476,29 @@ RSpec.describe "Admin Runners" do end end - describe "Runner show page" do + describe "Runner edit page" do let(:runner) { create(:ci_runner) } before do @project1 = create(:project) @project2 = create(:project) - visit admin_runner_path(runner) + visit edit_admin_runner_path(runner) + + wait_for_requests end describe 'runner page breadcrumbs' do - it 'contains the current runner token' do + it 'contains the current runner id and token' do page.within '[data-testid="breadcrumb-links"]' do - expect(page.find('h2')).to have_content(runner.short_sha) + expect(page).to have_link("##{runner.id} (#{runner.short_sha})") + expect(page.find('h2')).to have_content("Edit") end end end - describe 'runner page title', :js do - it 'contains the runner id' do - expect(find('.page-title')).to have_content("Runner ##{runner.id}") + describe 'runner header', :js do + it 'contains the runner status, type and id' do + expect(page).to have_content("never contacted shared Runner ##{runner.id} created") end end @@ -498,7 +540,7 @@ RSpec.describe "Admin Runners" do let(:runner) { create(:ci_runner, :project, projects: [@project1]) } before do - visit admin_runner_path(runner) + visit edit_admin_runner_path(runner) end it_behaves_like 'assignable runner' @@ -508,7 +550,7 @@ RSpec.describe "Admin Runners" do let(:runner) { create(:ci_runner, :project, projects: [@project1], locked: true) } before do - visit admin_runner_path(runner) + visit edit_admin_runner_path(runner) end it_behaves_like 'assignable runner' @@ -519,7 +561,7 @@ RSpec.describe "Admin Runners" do before do @project1.destroy! - visit admin_runner_path(runner) + visit edit_admin_runner_path(runner) end it_behaves_like 'assignable runner' @@ -530,7 +572,7 @@ RSpec.describe "Admin Runners" do let(:runner) { create(:ci_runner, :project, projects: [@project1]) } before do - visit admin_runner_path(runner) + visit edit_admin_runner_path(runner) end it 'removed specific runner from project' do @@ -567,6 +609,8 @@ RSpec.describe "Admin Runners" do page.find('input').send_keys(search_term) click_on 'Search' end + + wait_for_requests end def input_filtered_search_filter_is_only(filter, value) @@ -583,5 +627,7 @@ RSpec.describe "Admin Runners" do click_on 'Search' end + + wait_for_requests end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 29323c604ef..e136ab41966 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -275,7 +275,7 @@ RSpec.describe 'Admin updates settings' do it 'enable hiding third party offers' do page.within('.as-third-party-offers') do - check 'Do not display offers from third parties' + check 'Do not display content for customer experience improvement and offers from third parties' click_button 'Save changes' end @@ -530,6 +530,7 @@ RSpec.describe 'Admin updates settings' do it 'loads usage ping payload on click', :js do stub_usage_data_connections + stub_database_flavor_check page.within('#js-usage-settings') do expected_payload_content = /(?=.*"uuid")(?=.*"hostname")/m diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 2b627707ff2..95e3f5c70e5 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -57,4 +57,33 @@ RSpec.describe "Admin::Users" do expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0") end end + + describe 'prompt user about registration features' do + let(:message) { s_("RegistrationFeatures|Want to %{feature_title} for free?") % { feature_title: s_('RegistrationFeatures|send emails to users') } } + + it 'does not render registration features CTA when service ping is enabled' do + stub_application_setting(usage_ping_enabled: true) + + visit admin_users_path + + expect(page).not_to have_content(message) + end + + context 'with no license and service ping disabled' do + before do + stub_application_setting(usage_ping_enabled: false) + + if Gitlab.ee? + allow(License).to receive(:current).and_return(nil) + end + end + + it 'renders registration features CTA' do + visit admin_users_path + + expect(page).to have_content(message) + expect(page).to have_link(s_('RegistrationFeatures|Registration Features Program')) + end + end + end end diff --git a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb index 22a27b33671..793a5bced00 100644 --- a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb @@ -19,4 +19,19 @@ RSpec.describe 'User activates the instance-level Mattermost Slash Command integ expect(page).to have_link('Settings', href: edit_path) expect(page).to have_link('Projects using custom settings', href: overrides_path) end + + it 'does not render integration form element' do + expect(page).not_to have_selector('[data-testid="integration-form"]') + end + + context 'when `vue_integration_form` feature flag is disabled' do + before do + stub_feature_flags(vue_integration_form: false) + visit_instance_integration('Mattermost slash commands') + end + + it 'renders integration form element' do + expect(page).to have_selector('[data-testid="integration-form"]') + end + end end diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index ae940fecabe..0d053329627 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -125,6 +125,26 @@ RSpec.describe 'Admin::Users::User' do end end + context 'when a user is locked', time_travel_to: '2020-02-02 10:30:45 -0700' do + let_it_be(:locked_user) { create(:user, locked_at: DateTime.parse('2020-02-02 10:30:00 -0700')) } + + before do + visit admin_user_path(locked_user) + end + + it "displays `(Locked)` next to user's name" do + expect(page).to have_content("#{locked_user.name} (Locked)") + end + + it 'allows a user to be unlocked from the `User administration dropdown', :js do + accept_gl_confirm("Unlock user #{locked_user.name}?", button_text: 'Unlock') do + click_action_in_user_dropdown(locked_user.id, 'Unlock') + end + + expect(page).not_to have_content("#{locked_user.name} (Locked)") + end + end + describe 'Impersonation' do let_it_be(:another_user) { create(:user) } diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index fa943245fcb..473f51370b3 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -462,9 +462,9 @@ RSpec.describe 'Admin::Users' do visit projects_admin_user_path(user) end - it 'lists group projects' do + it 'lists groups' do within(:css, '.gl-mb-3 + .card') do - expect(page).to have_content 'Group projects' + expect(page).to have_content 'Groups' expect(page).to have_link group.name, href: admin_group_path(group) end end diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb index 25e474bb676..49375e4b37b 100644 --- a/spec/features/boards/board_filters_spec.rb +++ b/spec/features/boards/board_filters_spec.rb @@ -34,7 +34,9 @@ RSpec.describe 'Issue board filters', :js do it '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) + wait_for_requests + + expect_filtered_search_dropdown_results(filter_dropdown, 4) click_on user.username filter_submit.click diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 2f21961d1fc..d25cddea902 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -528,7 +528,7 @@ RSpec.describe 'Project issue boards', :js do end it 'does not allow dragging' do - expect(page).not_to have_selector('.user-can-drag') + expect(page).not_to have_selector('.gl-cursor-grab') end end diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 0bb8e0bcdc0..0e914ae19d1 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -6,9 +6,11 @@ RSpec.describe 'Project issue boards sidebar', :js do include BoardHelpers let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, :public) } + let_it_be(:group) { create(:group, :public) } + let_it_be(:project) { create(:project, :public, namespace: group) } let_it_be(:board) { create(:board, project: project) } - let_it_be(:list) { create(:list, board: board, position: 0) } + let_it_be(:label) { create(:label, project: project, name: 'Label') } + let_it_be(:list) { create(:list, board: board, label: label, position: 0) } let_it_be(:issue, reload: true) { create(:issue, project: project, relative_position: 1) } diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index 4378e88f7c1..e600a99e3b6 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -30,10 +30,10 @@ RSpec.describe 'Commits' do project.add_reporter(user) end - describe 'Commit builds with jobs_tab_feature flag off' do + describe 'Commit builds with jobs_tab_vue feature flag off' do before do stub_feature_flags(jobs_tab_vue: false) - visit pipeline_path(pipeline) + visit builds_project_pipeline_path(project, pipeline) end it { expect(page).to have_content pipeline.sha[0..7] } @@ -45,6 +45,23 @@ RSpec.describe 'Commits' do end end end + + describe 'Commit builds with jobs_tab_vue feature flag on', :js do + before do + visit builds_project_pipeline_path(project, pipeline) + + wait_for_requests + end + + it { expect(page).to have_content pipeline.sha[0..7] } + + it 'contains generic commit status build' do + page.within('[data-testid="jobs-tab-table"]') do + expect(page).to have_content "##{status.id}" # build id + expect(page).to have_content 'generic' # build name + end + end + end end context 'commit status is Ci Build' do @@ -103,6 +120,18 @@ RSpec.describe 'Commits' do end end + context 'Download artifacts with jobs_tab_vue feature flag on', :js do + before do + create(:ci_job_artifact, :archive, file: artifacts_file, job: build) + end + + it do + visit builds_project_pipeline_path(project, pipeline) + wait_for_requests + expect(page).to have_link('Download artifacts', href: download_project_job_artifacts_path(project, build, file_type: :archive)) + end + end + describe 'Cancel all builds' do it 'cancels commit', :js, :sidekiq_might_not_need_inline do visit pipeline_path(pipeline) @@ -141,6 +170,27 @@ RSpec.describe 'Commits' do end end + context "when logged as reporter and with jobs_tab_vue feature flag on", :js do + before do + project.add_reporter(user) + create(:ci_job_artifact, :archive, file: artifacts_file, job: build) + visit builds_project_pipeline_path(project, pipeline) + wait_for_requests + end + + it 'renders header' do + expect(page).to have_content pipeline.sha[0..7] + expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ') + expect(page).to have_content pipeline.user.name + expect(page).not_to have_link('Cancel running') + expect(page).not_to have_link('Retry') + end + + it do + expect(page).to have_link('Download artifacts') + end + end + context 'when accessing internal project with disallowed access', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/299575' do before do project.update!( diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index a9fb6a2ae7e..64181041be5 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -71,7 +71,7 @@ RSpec.describe 'Dashboard Issues' do find('#select2-drop-mask', visible: false) execute_script("$('#select2-drop-mask').remove();") - find('.new-project-item-link').click + find('.js-new-project-item-link').click expect(page).to have_current_path("#{project_path}/-/issues/new") diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb index 1ba16bf879a..9758454ab61 100644 --- a/spec/features/dashboard/milestones_spec.rb +++ b/spec/features/dashboard/milestones_spec.rb @@ -41,7 +41,7 @@ RSpec.describe 'Dashboard > Milestones' do first('.select2-result-label').click end - find('.new-project-item-link').click + find('.js-new-project-item-link').click expect(current_path).to eq(new_group_milestone_path(group)) end diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb index 7345bfa19e2..b00bdeac3b9 100644 --- a/spec/features/dashboard/todos/todos_spec.rb +++ b/spec/features/dashboard/todos/todos_spec.rb @@ -5,10 +5,11 @@ require 'spec_helper' RSpec.describe 'Dashboard Todos' do include DesignManagementTestHelpers - let_it_be(:user) { create(:user, username: 'john') } - let_it_be(:author) { create(:user) } + 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(:project) { create(:project, :public) } - let_it_be(:issue) { create(:issue, project: project, due_date: Date.today, title: "Fix bug") } + let_it_be(:issue) { create(:issue, project: project, due_date: Date.today, title: "Fix bug") } before_all do project.add_developer(user) @@ -23,6 +24,19 @@ RSpec.describe 'Dashboard Todos' do it 'shows "All done" message' do expect(page).to have_content 'Your To-Do List shows what to work on next' end + + context 'when user was assigned to an issue and marked it as done' do + before do + sign_in(user) + end + + it 'shows "Are you looking for things to do?" message' do + create(:todo, :assigned, :done, user: user, project: project, target: issue, author: user2) + visit dashboard_todos_path + + expect(page).to have_content 'Are you looking for things to do? Take a look at open issues, contribute to a merge request, or mention someone in a comment to automatically assign them a new to-do item.' + end + end end context 'when the todo references a merge request' do diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb index 9fa77d5917d..f6821ae66e8 100644 --- a/spec/features/dashboard/user_filters_projects_spec.rb +++ b/spec/features/dashboard/user_filters_projects_spec.rb @@ -168,7 +168,7 @@ RSpec.describe 'Dashboard > User filters projects' do sorting_dropdown.click - ['Last updated', 'Created date', 'Name', 'Stars'].each do |label| + ['Updated date', 'Created date', 'Name', 'Stars'].each do |label| expect(sorting_dropdown).to have_content(label) end end @@ -192,9 +192,9 @@ RSpec.describe 'Dashboard > User filters projects' do end end - context 'Sorting by Last updated' do + context 'Sorting by Updated date' do it 'sorts the project list' do - select_dropdown_option '#filtered-search-sorting-dropdown', 'Last updated' + select_dropdown_option '#filtered-search-sorting-dropdown', 'Updated date' expect_to_see_projects(desc_sorted_project_names) diff --git a/spec/features/graphiql_spec.rb b/spec/features/graphiql_spec.rb index 91f53b4bb7c..7729cdaa362 100644 --- a/spec/features/graphiql_spec.rb +++ b/spec/features/graphiql_spec.rb @@ -9,7 +9,7 @@ RSpec.describe 'GraphiQL' do end it 'has the correct graphQLEndpoint' do - expect(page.body).to include('var graphQLEndpoint = "/api/graphql";') + expect(page.body).to include('<div id="graphiql-container" data-graphql-endpoint-path="/api/graphql"') end end @@ -26,7 +26,7 @@ RSpec.describe 'GraphiQL' do end it 'has the correct graphQLEndpoint' do - expect(page.body).to include('var graphQLEndpoint = "/gitlab/root/api/graphql";') + expect(page.body).to include('<div id="graphiql-container" data-graphql-endpoint-path="/gitlab/root/api/graphql"') end end end diff --git a/spec/features/groups/dependency_proxy_for_containers_spec.rb b/spec/features/groups/dependency_proxy_for_containers_spec.rb index a4cd6d0f503..ae721e7b91f 100644 --- a/spec/features/groups/dependency_proxy_for_containers_spec.rb +++ b/spec/features/groups/dependency_proxy_for_containers_spec.rb @@ -81,28 +81,11 @@ RSpec.describe 'Group Dependency Proxy for containers', :js do let!(:dependency_proxy_blob) { create(:dependency_proxy_blob, group: group) } it_behaves_like 'responds with the file' - - context 'dependency_proxy_workhorse feature flag disabled' do - before do - stub_feature_flags({ dependency_proxy_workhorse: false }) - end - - it_behaves_like 'responds with the file' - end end end context 'when the blob must be downloaded' do it_behaves_like 'responds with the file' it_behaves_like 'caches the file' - - context 'dependency_proxy_workhorse feature flag disabled' do - before do - stub_feature_flags({ dependency_proxy_workhorse: false }) - end - - it_behaves_like 'responds with the file' - it_behaves_like 'caches the file' - end end end diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 1bac1bcdf5a..3fc1484826c 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -156,10 +156,10 @@ RSpec.describe 'Group issues page' do expect(page).to have_selector('.manual-ordering') end - it 'each issue item has a user-can-drag css applied' do + it 'each issue item has a gl-cursor-grab css applied' do visit issues_group_path(group, sort: 'relative_position') - expect(page).to have_selector('.issue.user-can-drag', count: 3) + expect(page).to have_selector('.issue.gl-cursor-grab', count: 3) end it 'issues should be draggable and persist order' do diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb index 2be7f61eeb9..8e6560af352 100644 --- a/spec/features/groups/labels/edit_spec.rb +++ b/spec/features/groups/labels/edit_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Edit group label' do + include Spec::Support::Helpers::ModalHelpers + let(:user) { create(:user) } let(:group) { create(:group) } let(:label) { create(:group_label, group: group) } @@ -20,4 +22,16 @@ RSpec.describe 'Edit group label' do expect(current_path).to eq(root_path) expect(label.reload.title).to eq('new label name') end + + it 'allows user to delete label', :js do + click_button 'Delete' + + within_modal do + expect(page).to have_content("#{label.title} will be permanently deleted from #{group.name}. This cannot be undone.") + + click_link 'Delete label' + end + + expect(page).to have_content("#{label.title} deleted permanently") + end end diff --git a/spec/features/groups/labels/sort_labels_spec.rb b/spec/features/groups/labels/sort_labels_spec.rb index b5657db23cb..df75ff7c3cb 100644 --- a/spec/features/groups/labels/sort_labels_spec.rb +++ b/spec/features/groups/labels/sort_labels_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'Sort labels', :js do expect(sort_options[1]).to eq('Name, descending') expect(sort_options[2]).to eq('Last created') expect(sort_options[3]).to eq('Oldest created') - expect(sort_options[4]).to eq('Last updated') + expect(sort_options[4]).to eq('Updated date') expect(sort_options[5]).to eq('Oldest updated') click_link 'Name, descending' diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb index 077f680629f..7541e54f014 100644 --- a/spec/features/groups/merge_requests_spec.rb +++ b/spec/features/groups/merge_requests_spec.rb @@ -67,7 +67,7 @@ RSpec.describe 'Group merge requests page' do end it 'shows projects only with merge requests feature enabled', :js do - find('.new-project-item-link').click + find('.js-new-project-item-link').click page.within('.select2-results') do expect(page).to have_content(project.name_with_namespace) diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb index da8032dc4dd..c5d2f5e6733 100644 --- a/spec/features/groups/navbar_spec.rb +++ b/spec/features/groups/navbar_spec.rb @@ -9,7 +9,8 @@ RSpec.describe 'Group navbar' do include_context 'group navbar structure' let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group) } + + let(:group) { create(:group) } before do insert_package_nav(_('Kubernetes')) @@ -40,7 +41,9 @@ RSpec.describe 'Group navbar' do it_behaves_like 'verified navigation bar' end - context 'when customer_relations feature flag is enabled' do + context 'when customer_relations feature and flag is enabled' do + let(:group) { create(:group, :crm_enabled) } + before do stub_feature_flags(customer_relations: true) diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb index 3c2ade6b274..26338b03349 100644 --- a/spec/features/groups/packages_spec.rb +++ b/spec/features/groups/packages_spec.rb @@ -42,6 +42,9 @@ RSpec.describe 'Group Packages' do let_it_be(:maven_package) { create(:maven_package, project: second_project, name: 'aaa', created_at: 2.days.ago, version: '2.0.0') } let_it_be(:packages) { [npm_package, maven_package] } + let(:package) { packages.first } + let(:package_details_path) { group_package_path(group, package) } + it_behaves_like 'packages list', check_project_name: true it_behaves_like 'package details link' diff --git a/spec/features/groups/settings/access_tokens_spec.rb b/spec/features/groups/settings/access_tokens_spec.rb new file mode 100644 index 00000000000..20787c4c2f5 --- /dev/null +++ b/spec/features/groups/settings/access_tokens_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Group > Settings > Access Tokens', :js do + let_it_be(:user) { create(:user) } + let_it_be(:bot_user) { create(:user, :project_bot) } + let_it_be(:group) { create(:group) } + let_it_be(:resource_settings_access_tokens_path) { group_settings_access_tokens_path(group) } + + before_all do + group.add_owner(user) + end + + before do + stub_feature_flags(bootstrap_confirmation_modals: false) + sign_in(user) + end + + def create_resource_access_token + group.add_maintainer(bot_user) + + create(:personal_access_token, user: bot_user) + end + + context 'when user is not a group owner' do + before do + group.add_maintainer(user) + end + + it_behaves_like 'resource access tokens missing access rights' + end + + describe 'token creation' do + it_behaves_like 'resource access tokens creation', 'group' + + context 'when token creation is not allowed' do + it_behaves_like 'resource access tokens creation disallowed', 'Group access token creation is disabled in this group. You can still use and manage existing tokens.' + end + end + + describe 'active tokens' do + let!(:resource_access_token) { create_resource_access_token } + + it_behaves_like 'active resource access tokens' + end + + describe 'inactive tokens' do + let!(:resource_access_token) { create_resource_access_token } + + it_behaves_like 'inactive resource access tokens', 'This group has no active access tokens.' + end +end diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 9c11b84fa8f..19f60ce55d3 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -171,6 +171,28 @@ RSpec.describe 'Group' do expect(page).not_to have_css('.recaptcha') end end + + describe 'showing personalization questions on group creation when it is enabled' do + before do + stub_application_setting(hide_third_party_offers: false) + visit new_group_path(anchor: 'create-group-pane') + end + + it 'renders personalization questions' do + expect(page).to have_content('Now, personalize your GitLab experience') + end + end + + describe 'not showing personalization questions on group creation when it is enabled' do + before do + stub_application_setting(hide_third_party_offers: true) + visit new_group_path(anchor: 'create-group-pane') + end + + it 'does not render personalization questions' do + expect(page).not_to have_content('Now, personalize your GitLab experience') + end + end end describe 'create a nested group', :js do diff --git a/spec/features/help_dropdown_spec.rb b/spec/features/help_dropdown_spec.rb new file mode 100644 index 00000000000..db98f58240d --- /dev/null +++ b/spec/features/help_dropdown_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe "Help Dropdown", :js do + let_it_be(:user) { create(:user) } + let_it_be(:admin) { create(:admin) } + + before do + stub_application_setting(version_check_enabled: true) + end + + context 'when logged in as non-admin' do + before do + sign_in(user) + visit root_path + end + + it 'does not render version data' do + page.within '.header-help' do + find('.header-help-dropdown-toggle').click + + expect(page).not_to have_text('Your GitLab Version') + expect(page).not_to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}") + expect(page).not_to have_selector('.version-check-badge') + expect(page).not_to have_text('Up to date') + end + end + end + + context 'when logged in as admin' do + before do + sign_in(admin) + gitlab_enable_admin_mode_sign_in(admin) + end + + describe 'does render version data' do + where(:response, :ui_text) do + [ + [{ "severity" => "success" }, 'Up to date'], + [{ "severity" => "warning" }, 'Update available'], + [{ "severity" => "danger" }, 'Update ASAP'] + ] + end + + with_them do + before do + allow_next_instance_of(VersionCheck) do |instance| + allow(instance).to receive(:response).and_return(response) + end + visit root_path + end + + it 'renders correct version badge variant' do + page.within '.header-help' do + find('.header-help-dropdown-toggle').click + + expect(page).to have_text('Your GitLab Version') + expect(page).to have_text("#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}") + expect(page).to have_selector('.version-check-badge') + expect(page).to have_text(ui_text) + end + end + end + end + end +end diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb index a1e2990202c..546257b9f10 100644 --- a/spec/features/help_pages_spec.rb +++ b/spec/features/help_pages_spec.rb @@ -28,21 +28,20 @@ RSpec.describe 'Help Pages' do end end - context 'in a production environment with version check enabled' do + describe 'with version check enabled' do + let_it_be(:user) { create(:user) } + before do stub_application_setting(version_check_enabled: true) + allow(User).to receive(:single_user).and_return(double(user, requires_usage_stats_consent?: false)) + allow(user).to receive(:can_read_all_resources?).and_return(true) - stub_rails_env('production') - allow(VersionCheck).to receive(:image_url).and_return('/version-check-url') - - sign_in(create(:user)) + sign_in(user) visit help_path end - it 'has a version check image' do - # Check `data-src` due to lazy image loading - expect(find('.js-version-status-badge', visible: false)['data-src']) - .to end_with('/version-check-url') + it 'renders the version check badge' do + expect(page).to have_selector('.js-gitlab-version-check') end end diff --git a/spec/features/issuables/sorting_list_spec.rb b/spec/features/issuables/sorting_list_spec.rb index f646cdbd71b..bc40fb713ac 100644 --- a/spec/features/issuables/sorting_list_spec.rb +++ b/spec/features/issuables/sorting_list_spec.rb @@ -54,10 +54,10 @@ RSpec.describe 'Sort Issuable List' do context 'in the "merge requests / merged" tab', :js do let(:issuable_type) { :merged_merge_request } - it 'is "last updated"' do + it 'is "updated date"' do visit_merge_requests_with_state(project, 'merged') - expect(page).to have_button 'Last updated' + expect(page).to have_button 'Updated date' expect(first_merge_request).to include(last_updated_issuable.title) expect(last_merge_request).to include(first_updated_issuable.title) end @@ -66,10 +66,10 @@ RSpec.describe 'Sort Issuable List' do context 'in the "merge requests / closed" tab', :js do let(:issuable_type) { :closed_merge_request } - it 'is "last updated"' do + it 'is "updated date"' do visit_merge_requests_with_state(project, 'closed') - expect(page).to have_button 'Last updated' + expect(page).to have_button 'Updated date' expect(first_merge_request).to include(last_updated_issuable.title) expect(last_merge_request).to include(first_updated_issuable.title) end @@ -95,7 +95,7 @@ RSpec.describe 'Sort Issuable List' do visit_merge_requests_with_state(project, 'open') click_button('Created date') - click_link('Last updated') + click_link('Updated date') expect(first_merge_request).to include(last_updated_issuable.title) expect(last_merge_request).to include(first_updated_issuable.title) @@ -152,10 +152,10 @@ RSpec.describe 'Sort Issuable List' do context 'in the "issues / closed" tab', :js do let(:issuable_type) { :closed_issue } - it 'is "last updated"' do + it 'is "updated date"' do visit_issues_with_state(project, 'closed') - expect(page).to have_button 'Last updated' + expect(page).to have_button 'Updated date' expect(first_issue).to include(last_updated_issuable.title) expect(last_issue).to include(first_updated_issuable.title) end @@ -195,7 +195,7 @@ RSpec.describe 'Sort Issuable List' do visit_issues_with_state(project, 'opened') click_button('Created date') - click_on('Last updated') + click_on('Updated date') expect(page).to have_css('.issue:first-child', text: last_updated_issuable.title) expect(page).to have_css('.issue:last-child', text: first_updated_issuable.title) diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 9da6694c681..868946814c3 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -8,10 +8,9 @@ RSpec.describe 'Issue Sidebar' do let_it_be(:group) { create(:group, :nested) } let_it_be(:project) { create(:project, :public, namespace: group) } let_it_be(:user) { create(:user) } - let_it_be(:label) { create(:label, project: project, title: 'bug') } - let_it_be(:issue) { create(:labeled_issue, project: project, labels: [label]) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:label) { create(:label, project: project, name: 'Label') } let_it_be(:mock_date) { Date.today.at_beginning_of_month + 2.days } - let_it_be(:xss_label) { create(:label, project: project, title: '<script>alert("xss");</script>') } before do stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") @@ -223,14 +222,6 @@ RSpec.describe 'Issue Sidebar' do restore_window_size open_issue_sidebar end - - it 'escapes XSS when viewing issue labels' do - page.within('.block.labels') do - click_on 'Edit' - - expect(page).to have_content '<script>alert("xss");</script>' - end - end end context 'editing issue milestone', :js do @@ -242,62 +233,7 @@ RSpec.describe 'Issue Sidebar' do end context 'editing issue labels', :js do - before do - issue.update!(labels: [label]) - page.within('.block.labels') do - click_on 'Edit' - end - end - - it 'shows the current set of labels' do - page.within('.issuable-show-labels') do - expect(page).to have_content label.title - end - end - - it 'shows option to create a project label' do - page.within('.block.labels') do - expect(page).to have_content 'Create project' - end - end - - context 'creating a project label', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27992' do - before do - page.within('.block.labels') do - click_link 'Create project' - end - end - - it 'shows dropdown switches to "create label" section' do - page.within('.block.labels') do - expect(page).to have_content 'Create project label' - end - end - - it 'adds new label' do - page.within('.block.labels') do - fill_in 'new_label_name', with: 'wontfix' - page.find('.suggest-colors a', match: :first).click - page.find('button', text: 'Create').click - - page.within('.dropdown-page-one') do - expect(page).to have_content 'wontfix' - end - end - end - - it 'shows error message if label title is taken' do - page.within('.block.labels') do - fill_in 'new_label_name', with: label.title - page.find('.suggest-colors a', match: :first).click - page.find('button', text: 'Create').click - - page.within('.dropdown-page-two') do - expect(page).to have_content 'Title has already been taken' - end - end - end - end + it_behaves_like 'labels sidebar widget' end context 'interacting with collapsed sidebar', :js do diff --git a/spec/features/issues/service_desk_spec.rb b/spec/features/issues/service_desk_spec.rb index 0a879fdd4d4..cc0d35afd60 100644 --- a/spec/features/issues/service_desk_spec.rb +++ b/spec/features/issues/service_desk_spec.rb @@ -9,8 +9,6 @@ RSpec.describe 'Service Desk Issue Tracker', :js do let_it_be(:support_bot) { User.support_bot } before do - stub_feature_flags(vue_issuables_list: true) - # The following two conditions equate to Gitlab::ServiceDesk.supported == true allow(Gitlab::IncomingEmail).to receive(:enabled?).and_return(true) allow(Gitlab::IncomingEmail).to receive(:supports_wildcard?).and_return(true) diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb index 44c23813e3c..625303f89e4 100644 --- a/spec/features/issues/user_bulk_edits_issues_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_spec.rb @@ -104,6 +104,26 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do end end + describe 'select all issues' do + let!(:issue_2) { create(:issue, project: project) } + + before do + stub_feature_flags(vue_issues_list: true) + end + + it 'after selecting all issues, unchecking one issue only unselects that one issue' do + visit project_issues_path(project) + + click_button 'Edit issues' + check 'Select all' + uncheck issue.title + + expect(page).to have_unchecked_field 'Select all' + expect(page).to have_unchecked_field issue.title + expect(page).to have_checked_field issue_2.title + end + end + def create_closed create(:issue, project: project, state: :closed) end diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb index 09d3ad15641..5d03aa1fc2b 100644 --- a/spec/features/issues/user_comments_on_issue_spec.rb +++ b/spec/features/issues/user_comments_on_issue_spec.rb @@ -11,6 +11,7 @@ RSpec.describe "User comments on issue", :js do before do stub_feature_flags(tribute_autocomplete: false) + stub_feature_flags(sandboxed_mermaid: false) project.add_guest(user) sign_in(user) @@ -49,7 +50,7 @@ RSpec.describe "User comments on issue", :js do add_note(comment) - expect(page.find('svg.mermaid')).to have_content html_content + expect(page.find('svg.mermaid')).not_to have_content 'javascript' within('svg.mermaid') { expect(page).not_to have_selector('img') } end diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb index 6e8b3e4fb7c..875b0a60634 100644 --- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb +++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb @@ -217,7 +217,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do # Javascript debounces AJAX calls. # So we have to wait until AJAX requests are started. - # Details are in app/assets/javascripts/create_merge_request_dropdown.js + # Details are in app/assets/javascripts/issues/create_merge_request_dropdown.js # this.refDebounce = _.debounce(...) sleep 0.5 diff --git a/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb b/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb new file mode 100644 index 00000000000..1fa8f533869 --- /dev/null +++ b/spec/features/issues/user_scrolls_to_deeplinked_note_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User scrolls to deep-linked note' do + let_it_be(:project) { create(:project, :public, :repository) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:comment_1) { create(:note_on_issue, noteable: issue, project: project, note: 'written first') } + let_it_be(:comments) { create_list(:note_on_issue, 20, noteable: issue, project: project, note: 'spacer note') } + + context 'on issue page', :js do + it 'on comment' do + visit project_issue_path(project, issue, anchor: "note_#{comment_1.id}") + + wait_for_requests + + expect(first_comment).to have_content(comment_1.note) + + bottom_of_title = find('.issue-sticky-header.gl-fixed').evaluate_script("this.getBoundingClientRect().bottom;") + top = first_comment.evaluate_script("this.getBoundingClientRect().top;") + + expect(top).to be_within(1).of(bottom_of_title) + end + end + + def all_comments + all('.timeline > .note.timeline-entry') + end + + def first_comment + all_comments.first + end +end diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb index 9f8cd2a769d..669c7c45411 100644 --- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb +++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb @@ -8,8 +8,6 @@ RSpec.describe 'New issue breadcrumb' do let(:user) { project.creator } before do - stub_feature_flags(vue_issuables_list: false) - sign_in(user) visit(new_project_issue_path(project)) end diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb index d3aaf339421..0e5a20fe24a 100644 --- a/spec/features/markdown/copy_as_gfm_spec.rb +++ b/spec/features/markdown/copy_as_gfm_spec.rb @@ -7,6 +7,10 @@ RSpec.describe 'Copy as GFM', :js do include RepoHelpers include ActionView::Helpers::JavaScriptHelper + before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350454 + end + describe 'Copying rendered GFM' do before do @feat = MarkdownFeature.new diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb index e080c7ffb3f..6a91d4e03c1 100644 --- a/spec/features/markdown/mermaid_spec.rb +++ b/spec/features/markdown/mermaid_spec.rb @@ -5,6 +5,10 @@ require 'spec_helper' RSpec.describe 'Mermaid rendering', :js do let_it_be(:project) { create(:project, :public) } + before do + stub_feature_flags(sandboxed_mermaid: false) + end + it 'renders Mermaid diagrams correctly' do description = <<~MERMAID ```mermaid diff --git a/spec/features/markdown/sandboxed_mermaid_spec.rb b/spec/features/markdown/sandboxed_mermaid_spec.rb new file mode 100644 index 00000000000..f118fb3db66 --- /dev/null +++ b/spec/features/markdown/sandboxed_mermaid_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Sandboxed Mermaid rendering', :js do + let_it_be(:project) { create(:project, :public) } + + before do + stub_feature_flags(sandboxed_mermaid: true) + end + + it 'includes mermaid frame correctly' do + description = <<~MERMAID + ```mermaid + graph TD; + A-->B; + A-->C; + B-->D; + C-->D; + ``` + MERMAID + + issue = create(:issue, project: project, description: description) + + visit project_issue_path(project, issue) + + wait_for_requests + + expected = %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts" frameborder="0" scrolling="no") + expect(page.html).to include(expected) + 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 0117cf01e53..8761ee89463 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -96,7 +96,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do context 'view merge request with external CI service' do before do - create(:service, project: project, + create(:integration, project: project, active: true, type: 'DroneCiService', category: 'ci') diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb index 31b2b2d15aa..322ccc6a0c0 100644 --- a/spec/features/password_reset_spec.rb +++ b/spec/features/password_reset_spec.rb @@ -44,8 +44,8 @@ RSpec.describe 'Password reset' do visit(edit_user_password_path(reset_password_token: token)) - fill_in 'New password', with: 'hello1234' - fill_in 'Confirm new password', with: 'hello1234' + fill_in 'New password', with: "new" + Gitlab::Password.test_default + fill_in 'Confirm new password', with: "new" + Gitlab::Password.test_default click_button 'Change your password' diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 24ba55994ae..34eb07d78f1 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -29,7 +29,7 @@ RSpec.describe 'Profile account page', :js do it 'deletes user', :js, :sidekiq_might_not_need_inline do click_button 'Delete account' - fill_in 'password', with: '12345678' + fill_in 'password', with: Gitlab::Password.test_default page.within '.modal' do click_button 'Delete account' @@ -62,66 +62,33 @@ RSpec.describe 'Profile account page', :js do end end - describe 'when I reset feed token' do - it 'resets feed token with `hide_access_tokens` feature flag enabled' do - visit profile_personal_access_tokens_path + it 'allows resetting of feed token' do + visit profile_personal_access_tokens_path - within('[data-testid="feed-token-container"]') do - previous_token = find_field('Feed token').value + within('[data-testid="feed-token-container"]') do + previous_token = find_field('Feed token').value - accept_confirm { click_link('reset this token') } + accept_confirm { click_link('reset this token') } - click_button('Click to reveal') + click_button('Click to reveal') - expect(find_field('Feed token').value).not_to eq(previous_token) - end - end - - it 'resets feed token with `hide_access_tokens` feature flag disabled' do - stub_feature_flags(hide_access_tokens: false) - visit profile_personal_access_tokens_path - - within('.feed-token-reset') do - previous_token = find("#feed_token").value - - accept_confirm { find('[data-testid="reset_feed_token_link"]').click } - - expect(find('#feed_token').value).not_to eq(previous_token) - end + expect(find_field('Feed token').value).not_to eq(previous_token) end end - describe 'when I reset incoming email token' do - before do - allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) - stub_feature_flags(bootstrap_confirmation_modals: false) - end - - it 'resets incoming email token with `hide_access_tokens` feature flag enabled' do - visit profile_personal_access_tokens_path - - within('[data-testid="incoming-email-token-container"]') do - previous_token = find_field('Incoming email token').value - - accept_confirm { click_link('reset this token') } + it 'allows resetting of incoming email token' do + allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) - click_button('Click to reveal') + visit profile_personal_access_tokens_path - expect(find_field('Incoming email token').value).not_to eq(previous_token) - end - end + within('[data-testid="incoming-email-token-container"]') do + previous_token = find_field('Incoming email token').value - it 'resets incoming email token with `hide_access_tokens` feature flag disabled' do - stub_feature_flags(hide_access_tokens: false) - visit profile_personal_access_tokens_path + accept_confirm { click_link('reset this token') } - within('.incoming-email-token-reset') do - previous_token = find('#incoming_email_token').value + click_button('Click to reveal') - accept_confirm { find('[data-testid="reset_email_token_link"]').click } - - expect(find('#incoming_email_token').value).not_to eq(previous_token) - end + expect(find_field('Incoming email token').value).not_to eq(previous_token) end end diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb index 6270fa7347d..b392d8dfa8e 100644 --- a/spec/features/profiles/chat_names_spec.rb +++ b/spec/features/profiles/chat_names_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Profile > Chat' do let(:user) { create(:user) } - let(:integration) { create(:service) } + let(:integration) { create(:integration) } before do sign_in(user) diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb index 8f05de60be9..24917412826 100644 --- a/spec/features/profiles/emails_spec.rb +++ b/spec/features/profiles/emails_spec.rb @@ -44,7 +44,7 @@ RSpec.describe 'Profile > Emails' do end it 'does not add an invalid email' do - fill_in('Email', with: 'test.@example.com') + fill_in('Email', with: 'test@@example.com') click_button('Add email address') email = user.emails.find_by(email: email) diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb index c1e2d19ad9a..b9e59a0239b 100644 --- a/spec/features/profiles/keys_spec.rb +++ b/spec/features/profiles/keys_spec.rb @@ -32,10 +32,10 @@ RSpec.describe 'Profile > SSH Keys' do expect(find('.breadcrumbs-sub-title')).to have_link(attrs[:title]) end - it 'shows a confirmable warning if the key does not start with ssh-' do + it 'shows a confirmable warning if the key begins with an algorithm name that is unsupported' do attrs = attributes_for(:key) - fill_in('Key', with: 'invalid-key') + fill_in('Key', with: 'unsupported-ssh-rsa key') fill_in('Title', with: attrs[:title]) click_button('Add key') diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb index 7059697354d..25fe43617fd 100644 --- a/spec/features/profiles/password_spec.rb +++ b/spec/features/profiles/password_spec.rb @@ -39,7 +39,7 @@ RSpec.describe 'Profile > Password' do describe 'User puts the same passwords in the field and in the confirmation' do it 'shows a success message' do - fill_passwords('mypassword', 'mypassword') + fill_passwords(Gitlab::Password.test_default, Gitlab::Password.test_default) page.within('.flash-notice') do expect(page).to have_content('Password was successfully updated. Please sign in again.') @@ -79,7 +79,7 @@ RSpec.describe 'Profile > Password' do end context 'Change password' do - let(:new_password) { '22233344' } + let(:new_password) { "new" + Gitlab::Password.test_default } before do sign_in(user) @@ -170,8 +170,8 @@ RSpec.describe 'Profile > Password' do expect(current_path).to eq new_profile_password_path fill_in :user_password, with: user.password - fill_in :user_new_password, with: '12345678' - fill_in :user_password_confirmation, with: '12345678' + fill_in :user_new_password, with: Gitlab::Password.test_default + fill_in :user_password_confirmation, with: Gitlab::Password.test_default click_button 'Set new password' expect(current_path).to eq new_user_session_path diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 135a940807e..f1e5658cd7b 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -132,7 +132,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do describe "feed token" do context "when enabled" do - it "displays feed token with `hide_access_tokens` feature flag enabled" do + it "displays feed token" do allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false) visit profile_personal_access_tokens_path @@ -143,15 +143,6 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do expect(page).to have_content(feed_token_description) end end - - it "displays feed token with `hide_access_tokens` feature flag disabled" do - stub_feature_flags(hide_access_tokens: false) - allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false) - visit profile_personal_access_tokens_path - - expect(page).to have_field('Feed token', with: user.feed_token) - expect(page).to have_content(feed_token_description) - end end context "when disabled" do diff --git a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb index 1a368676a5e..11e2d24c36a 100644 --- a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb +++ b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb @@ -34,26 +34,23 @@ RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do end it 'changes fragment hash if line number clicked' do - ending_fragment = "L5" - visit_blob find('#L3').click - find("##{ending_fragment}").click + find("#L5").click - expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment))) + expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: "LC5"))) end it 'with initial fragment hash, changes fragment hash if line number clicked' do fragment = "L1" - ending_fragment = "L5" visit_blob(fragment) find('#L3').click - find("##{ending_fragment}").click + find("#L5").click - expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment))) + expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: "LC5"))) end end @@ -73,26 +70,23 @@ RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do end it 'changes fragment hash if line number clicked' do - ending_fragment = "L5" - visit_blob find('#L3').click - find("##{ending_fragment}").click + find("#L5").click - expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment))) + expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: "LC5"))) end it 'with initial fragment hash, changes fragment hash if line number clicked' do fragment = "L1" - ending_fragment = "L5" visit_blob(fragment) find('#L3').click - find("##{ending_fragment}").click + find("#L5").click - expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment))) + expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: "LC5"))) end end end diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index 9d05c985af1..62994d19fc0 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -29,6 +29,10 @@ RSpec.describe 'File blob', :js do ).execute end + before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350455 + end + context 'Ruby file' do before do visit_blob('files/ruby/popen.rb') diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb index 8fc5c3d2e1b..0d08e7ea10d 100644 --- a/spec/features/projects/branches/user_deletes_branch_spec.rb +++ b/spec/features/projects/branches/user_deletes_branch_spec.rb @@ -32,28 +32,4 @@ RSpec.describe "User deletes branch", :js do expect(page).to have_content('Branch was deleted') end - - context 'when the feature flag :delete_branch_confirmation_modals is disabled' do - before do - stub_feature_flags(bootstrap_confirmation_modals: false) - stub_feature_flags(delete_branch_confirmation_modals: false) - end - - it "deletes branch" do - visit(project_branches_path(project)) - - branch_search = find('input[data-testid="branch-search"]') - - branch_search.set('improve/awesome') - branch_search.native.send_keys(:enter) - - page.within(".js-branch-improve\\/awesome") do - accept_alert { click_link(title: 'Delete branch') } - end - - wait_for_requests - - expect(page).to have_css(".js-branch-improve\\/awesome", visible: :hidden) - end - end end diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 2725c6a91be..363d08da024 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -117,7 +117,7 @@ RSpec.describe 'Branches' do it 'sorts the branches by name', :js do visit project_branches_filtered_path(project, state: 'all') - click_button "Last updated" # Open sorting dropdown + click_button "Updated date" # Open sorting dropdown within '[data-testid="branches-dropdown"]' do find('p', text: 'Name').click end @@ -128,7 +128,7 @@ RSpec.describe 'Branches' do it 'sorts the branches by oldest updated', :js do visit project_branches_filtered_path(project, state: 'all') - click_button "Last updated" # Open sorting dropdown + click_button "Updated date" # Open sorting dropdown within '[data-testid="branches-dropdown"]' do find('p', text: 'Oldest updated').click end @@ -175,26 +175,6 @@ RSpec.describe 'Branches' do expect(page).not_to have_content('fix') expect(all('.all-branches').last).to have_selector('li', count: 0) end - - context 'when the delete_branch_confirmation_modals feature flag is disabled' do - it 'removes branch after confirmation', :js do - stub_feature_flags(delete_branch_confirmation_modals: false) - stub_feature_flags(bootstrap_confirmation_modals: false) - - visit project_branches_filtered_path(project, state: 'all') - - search_for_branch('fix') - - expect(page).to have_content('fix') - expect(find('.all-branches')).to have_selector('li', count: 1) - accept_confirm do - within('.js-branch-item', match: :first) { click_link(title: 'Delete branch') } - end - - expect(page).not_to have_content('fix') - expect(find('.all-branches')).to have_selector('li', count: 0) - end - end end context 'on project with 0 branch' do diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index 6e88cbf52b5..0c9db24f1d8 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -219,7 +219,7 @@ RSpec.describe 'Gcp Cluster', :js do it 'user does not see the offer' do page.within('.as-third-party-offers') do click_button 'Expand' - check 'Do not display offers from third parties' + check 'Do not display content for customer experience improvement and offers from third parties' click_button 'Save changes' end diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index bcbf2f46f79..d88ff5c1aa5 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -342,24 +342,6 @@ RSpec.describe 'Environment' do expect(page).not_to have_button('Stop') end - context 'when the feature flag :delete_branch_confirmation_modals is disabled' do - before do - stub_feature_flags(delete_branch_confirmation_modals: false) - end - - it 'user deletes the branch with running environment' do - visit project_branches_filtered_path(project, state: 'all', search: 'feature') - - remove_branch_with_hooks(project, user, 'feature') do - within('.js-branch-feature') { click_link(title: 'Delete branch') } - end - - visit_environment(environment) - - expect(page).not_to have_button('Stop') - end - end - ## # This is a workaround for problem described in #24543 # diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index a7e773dda2d..23fcc1fe444 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Edit Project Settings' do # disable by clicking toggle toggle_feature_off("project[project_feature_attributes][#{tool_name}_access_level]") page.within('.sharing-permissions') do - find('input[value="Save changes"]').click + find('[data-testid="project-features-save-button"]').click end wait_for_requests expect(page).not_to have_selector(".shortcuts-#{shortcut_name}") @@ -32,7 +32,7 @@ RSpec.describe 'Edit Project Settings' do # re-enable by clicking toggle again toggle_feature_on("project[project_feature_attributes][#{tool_name}_access_level]") page.within('.sharing-permissions') do - find('input[value="Save changes"]').click + find('[data-testid="project-features-save-button"]').click end wait_for_requests expect(page).to have_selector(".shortcuts-#{shortcut_name}") diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb index 4e9e129042c..508dec70db6 100644 --- a/spec/features/projects/files/user_browses_files_spec.rb +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -340,6 +340,7 @@ RSpec.describe "User browses files" do let(:newrev) { project.repository.commit('master').sha } before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350456 create_file_in_repo(project, 'master', 'master', filename, 'Test file') path = File.join('master', filename) @@ -355,6 +356,7 @@ RSpec.describe "User browses files" do context "when browsing a raw file" do before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350456 path = File.join(RepoHelpers.sample_commit.id, RepoHelpers.sample_blob.path) visit(project_blob_path(project, path)) diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb index 3be5ab64834..17699847704 100644 --- a/spec/features/projects/files/user_browses_lfs_files_spec.rb +++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb @@ -35,7 +35,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do expect(page).to have_content 'version https://git-lfs.github.com/spec/v1' expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897' expect(page).to have_content 'size 1575078' - expect(page).not_to have_content 'Download (1.5 MB)' + expect(page).not_to have_content 'Download (1.50 MiB)' end end @@ -56,7 +56,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do click_link('lfs') click_link('lfs_object.iso') - expect(page).to have_content('Download (1.5 MB)') + expect(page).to have_content('Download (1.50 MiB)') expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1') expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897') expect(page).not_to have_content('size 1575078') @@ -88,7 +88,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do it 'does not show single file edit link' do page.within('.content') do expect(page).to have_selector(:link_or_button, 'Web IDE') - expect(page).not_to have_selector(:link_or_button, 'Edit') + expect(page).not_to have_css('button[data-testid="edit"') end end end diff --git a/spec/features/projects/files/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb index b6e300e9e59..c508b2ddba9 100644 --- a/spec/features/projects/files/user_deletes_files_spec.rb +++ b/spec/features/projects/files/user_deletes_files_spec.rb @@ -15,6 +15,7 @@ RSpec.describe 'Projects > Files > User deletes files', :js do let(:user) { create(:user) } before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/349953 sign_in(user) end diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb index 453cc14c267..2b4ac3dc1d8 100644 --- a/spec/features/projects/files/user_edits_files_spec.rb +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -150,7 +150,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do expect_fork_prompt - click_link_or_button('Fork project') + click_link_or_button('Fork') expect_fork_status @@ -169,7 +169,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do expect_fork_prompt - click_link_or_button('Fork project') + click_link_or_button('Fork') expect_fork_status @@ -183,7 +183,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do click_link_or_button('Edit') expect_fork_prompt - click_link_or_button('Fork project') + click_link_or_button('Fork') find('.file-editor', match: :first) @@ -214,7 +214,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do click_link('.gitignore') click_link_or_button('Edit') - expect(page).not_to have_link('Fork project') + expect(page).not_to have_link('Fork') find('#editor') set_editor_value('*.rbca') diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb index c9b472260bd..fe9520fffc8 100644 --- a/spec/features/projects/files/user_replaces_files_spec.rb +++ b/spec/features/projects/files/user_replaces_files_spec.rb @@ -17,6 +17,7 @@ RSpec.describe 'Projects > Files > User replaces files', :js do let(:user) { create(:user) } before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/349953 sign_in(user) end diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 3afd1937652..2fbec4e22f4 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -10,12 +10,11 @@ RSpec.describe 'Import/Export - project import integration test', :js do let(:export_path) { "#{Dir.tmpdir}/import_file_spec" } before do - stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false) stub_uploads_object_storage(FileUploader) allow_next_instance_of(Gitlab::ImportExport) do |instance| allow(instance).to receive(:storage_path).and_return(export_path) end - gitlab_sign_in(user) + sign_in(user) end after do diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb index 7a035248440..50010950f0e 100644 --- a/spec/features/projects/integrations/user_activates_jira_spec.rb +++ b/spec/features/projects/integrations/user_activates_jira_spec.rb @@ -20,7 +20,7 @@ RSpec.describe 'User activates Jira', :js do it 'activates the Jira service' do expect(page).to have_content('Jira settings saved and active.') - expect(current_path).to eq(edit_project_service_path(project, :jira)) + expect(current_path).to eq(edit_project_integration_path(project, :jira)) end unless Gitlab.ee? @@ -41,7 +41,7 @@ RSpec.describe 'User activates Jira', :js do fill_in 'service_password', with: 'password' click_test_integration - page.within('.service-settings') do + page.within('[data-testid="integration-settings-form"]') do expect(page).to have_content('This field is required.') end end @@ -55,7 +55,7 @@ RSpec.describe 'User activates Jira', :js do click_test_then_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(current_path).to eq(edit_project_service_path(project, :jira)) + expect(current_path).to eq(edit_project_integration_path(project, :jira)) end end end @@ -72,7 +72,7 @@ RSpec.describe 'User activates Jira', :js do it 'saves but does not activate the Jira service' do expect(page).to have_content('Jira settings saved, but not active.') - expect(current_path).to eq(edit_project_service_path(project, :jira)) + expect(current_path).to eq(edit_project_integration_path(project, :jira)) end it 'does not show the Jira link in the menu' do diff --git a/spec/features/projects/labels/sort_labels_spec.rb b/spec/features/projects/labels/sort_labels_spec.rb index 83559b816d2..26b3d08253c 100644 --- a/spec/features/projects/labels/sort_labels_spec.rb +++ b/spec/features/projects/labels/sort_labels_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'Sort labels', :js do expect(sort_options[1]).to eq('Name, descending') expect(sort_options[2]).to eq('Last created') expect(sort_options[3]).to eq('Oldest created') - expect(sort_options[4]).to eq('Last updated') + expect(sort_options[4]).to eq('Updated date') expect(sort_options[5]).to eq('Oldest updated') click_link 'Name, descending' diff --git a/spec/features/projects/labels/user_edits_labels_spec.rb b/spec/features/projects/labels/user_edits_labels_spec.rb index 8300a1a8542..999c238c7b3 100644 --- a/spec/features/projects/labels/user_edits_labels_spec.rb +++ b/spec/features/projects/labels/user_edits_labels_spec.rb @@ -3,6 +3,8 @@ require "spec_helper" RSpec.describe "User edits labels" do + include Spec::Support::Helpers::ModalHelpers + let_it_be(:project) { create(:project_empty_repo, :public) } let_it_be(:label) { create(:label, project: project) } let_it_be(:user) { create(:user) } @@ -24,4 +26,16 @@ RSpec.describe "User edits labels" do expect(page).to have_content(new_title).and have_no_content(label.title) end end + + it 'allows user to delete label', :js do + click_button 'Delete' + + within_modal do + expect(page).to have_content("#{label.title} will be permanently deleted from #{project.name}. This cannot be undone.") + + click_link 'Delete label' + end + + expect(page).to have_content('Label was removed') + end end diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 4dedd5689de..f1786c1be40 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -6,10 +6,6 @@ RSpec.describe 'New project', :js do include Select2Helper include Spec::Support::Helpers::Features::TopNavSpecHelpers - before do - stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false) - end - context 'as a user' do let(:user) { create(:user) } @@ -179,7 +175,7 @@ RSpec.describe 'New project', :js do it 'does not show the initialize with Readme checkbox on "Import project" tab' do visit new_project_path click_link 'Import project' - first('.js-import-git-toggle-button').click + click_button 'Repo by URL' page.within '#import-project-pane' do expect(page).not_to have_css('input#project_initialize_with_readme') @@ -196,9 +192,7 @@ RSpec.describe 'New project', :js do end it 'selects the user namespace' do - page.within('#blank-project-pane') do - expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username) - end + expect(page).to have_button user.username end end @@ -212,9 +206,7 @@ RSpec.describe 'New project', :js do end it 'selects the group namespace' do - page.within('#blank-project-pane') do - expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name) - end + expect(page).to have_button group.name end end @@ -229,9 +221,7 @@ RSpec.describe 'New project', :js do end it 'selects the group namespace' do - page.within('#blank-project-pane') do - expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path) - end + expect(page).to have_button subgroup.full_path end end @@ -249,22 +239,30 @@ RSpec.describe 'New project', :js do end it 'enables the correct visibility options' do - select2(user.namespace_id, from: '#project_namespace_id') + click_button public_group.full_path + click_button user.username + expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled - select2(public_group.id, from: '#project_namespace_id') + click_button user.username + click_button public_group.full_path + expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled - select2(internal_group.id, from: '#project_namespace_id') + click_button public_group.full_path + click_button internal_group.full_path + expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled - select2(private_group.id, from: '#project_namespace_id') + click_button internal_group.full_path + click_button private_group.full_path + expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled @@ -355,9 +353,7 @@ RSpec.describe 'New project', :js do end it 'selects the group namespace' do - page.within('#blank-project-pane') do - expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path) - end + expect(page).to have_button group.full_path end end end diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb index 7fcc8200b1c..8180f6b9aff 100644 --- a/spec/features/projects/packages_spec.rb +++ b/spec/features/projects/packages_spec.rb @@ -35,6 +35,9 @@ RSpec.describe 'Packages' do let_it_be(:maven_package) { create(:maven_package, project: project, name: 'aaa', created_at: 2.days.ago, version: '2.0.0') } let_it_be(:packages) { [npm_package, maven_package] } + let(:package) { packages.first } + let(:package_details_path) { project_package_path(project, package) } + it_behaves_like 'packages list' it_behaves_like 'package details link' diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 6ddc8e43762..5176a7ec5a1 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -1020,6 +1020,103 @@ RSpec.describe 'Pipeline', :js do end end + describe 'GET /:project/-/pipelines/:id/builds with jobs_tab_vue feature flag turned on' do + include_context 'pipeline builds' + + let_it_be(:project) { create(:project, :repository) } + + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } + + before do + visit builds_project_pipeline_path(project, pipeline) + end + + it 'shows a list of jobs' do + expect(page).to have_content('Test') + expect(page).to have_content(build_passed.id) + expect(page).to have_content('Deploy') + expect(page).to have_content(build_failed.id) + expect(page).to have_content(build_running.id) + expect(page).to have_content(build_external.id) + expect(page).to have_content('Retry') + expect(page).to have_content('Cancel running') + expect(page).to have_button('Play') + end + + it 'shows jobs tab pane as active' do + expect(page).to have_css('#js-tab-builds.active') + end + + context 'page tabs' do + it 'shows Pipeline, Jobs and DAG tabs with link' do + expect(page).to have_link('Pipeline') + expect(page).to have_link('Jobs') + expect(page).to have_link('Needs') + end + + it 'shows counter in Jobs tab' do + expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s) + end + + it 'shows Jobs tab as active' do + expect(page).to have_css('li.js-builds-tab-link .active') + end + end + + context 'retrying jobs' do + it { expect(page).not_to have_content('retried') } + + context 'when retrying' do + before do + find('[data-testid="retry"]', match: :first).click + end + + it 'does not show a "Retry" button', :sidekiq_might_not_need_inline do + expect(page).not_to have_content('Retry') + end + end + end + + context 'canceling jobs' do + it { expect(page).not_to have_selector('.ci-canceled') } + + context 'when canceling' do + before do + click_on 'Cancel running' + end + + it 'does not show a "Cancel running" button', :sidekiq_might_not_need_inline do + expect(page).not_to have_content('Cancel running') + end + end + end + + context 'playing manual job' do + before do + within '[data-testid="jobs-tab-table"]' do + click_button('Play') + + wait_for_requests + end + end + + it { expect(build_manual.reload).to be_pending } + end + + context 'when user unschedules a delayed job' do + before do + within '[data-testid="jobs-tab-table"]' do + click_button('Unschedule') + end + end + + it 'unschedules the delayed job and shows play button as a manual job' do + expect(page).to have_button('Play') + expect(page).not_to have_button('Unschedule') + end + end + end + describe 'GET /:project/-/pipelines/:id/failures' do let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: '1234') } let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) } diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb index 019d50a497b..27c23e7beb5 100644 --- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb +++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'User activates issue tracker', :js do it 'activates the service' do expect(page).to have_content("#{tracker} settings saved and active.") - expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) + expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_'))) end it 'shows the link in the menu' do @@ -58,7 +58,7 @@ RSpec.describe 'User activates issue tracker', :js do end expect(page).to have_content("#{tracker} settings saved and active.") - expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) + expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_'))) end end end @@ -73,7 +73,7 @@ RSpec.describe 'User activates issue tracker', :js do it 'saves but does not activate the service' do expect(page).to have_content("#{tracker} settings saved, but not active.") - expect(current_path).to eq(edit_project_service_path(project, tracker.parameterize(separator: '_'))) + expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_'))) end it 'does not show the external tracker link in the menu' do diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb index b2ca0424b6d..74919a99f04 100644 --- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do let(:mattermost_enabled) { true } describe 'activation' do - let(:edit_path) { edit_project_service_path(project, :mattermost_slash_commands) } + let(:edit_path) { edit_project_integration_path(project, :mattermost_slash_commands) } include_examples 'user activates the Mattermost Slash Command integration' end diff --git a/spec/features/projects/services/user_activates_slack_notifications_spec.rb b/spec/features/projects/services/user_activates_slack_notifications_spec.rb index d5fe8b083ba..38b6ad84c77 100644 --- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb +++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'User activates Slack notifications', :js do pipeline_channel: 6, wiki_page_channel: 7) - visit(edit_project_service_path(project, integration)) + visit(edit_project_integration_path(project, integration)) end it 'filters events by channel' do diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb index bc84ccaa432..d46d1f739b7 100644 --- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Slack slash commands', :js do click_active_checkbox click_on 'Save' - expect(current_path).to eq(edit_project_service_path(project, :slack_slash_commands)) + expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands)) expect(page).to have_content('Slack slash commands settings saved, but not active.') end @@ -32,7 +32,7 @@ RSpec.describe 'Slack slash commands', :js do fill_in 'Token', with: 'token' click_on 'Save' - expect(current_path).to eq(edit_project_service_path(project, :slack_slash_commands)) + expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands)) expect(page).to have_content('Slack slash commands settings saved and active.') end diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb index d8de9e0449e..122bf267021 100644 --- a/spec/features/projects/settings/access_tokens_spec.rb +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do let_it_be(:bot_user) { create(:user, :project_bot) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } + let_it_be(:resource_settings_access_tokens_path) { project_settings_access_tokens_path(project) } before_all do project.add_maintainer(user) @@ -17,78 +18,25 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do sign_in(user) end - def create_project_access_token + def create_resource_access_token project.add_maintainer(bot_user) create(:personal_access_token, user: bot_user) end - def active_project_access_tokens - find('.table.active-tokens') - end - - def no_project_access_tokens_message - find('.settings-message') - end - - def created_project_access_token - find('#created-personal-access-token').value - end - context 'when user is not a project maintainer' do before do project.add_developer(user) end - it 'does not show project access token page' do - visit project_settings_access_tokens_path(project) - - expect(page).to have_content("Page Not Found") - end + it_behaves_like 'resource access tokens missing access rights' end describe 'token creation' do - it 'allows creation of a project access token' do - name = 'My project access token' - - visit project_settings_access_tokens_path(project) - fill_in 'Token name', with: name - - # Set date to 1st of next month - find_field('Expiration date').click - find('.pika-next').click - click_on '1' - - # Scopes - check 'api' - check 'read_api' - - click_on 'Create project access token' - - expect(active_project_access_tokens).to have_text(name) - expect(active_project_access_tokens).to have_text('in') - expect(active_project_access_tokens).to have_text('api') - expect(active_project_access_tokens).to have_text('read_api') - expect(active_project_access_tokens).to have_text('Maintainer') - expect(created_project_access_token).not_to be_empty - end + it_behaves_like 'resource access tokens creation', 'project' context 'when token creation is not allowed' do - before do - group.namespace_settings.update_column(:resource_access_token_creation_allowed, false) - end - - it 'does not show project access token creation form' do - visit project_settings_access_tokens_path(project) - - expect(page).not_to have_selector('#new_project_access_token') - end - - it 'shows project access token creation disabled text' do - visit project_settings_access_tokens_path(project) - - expect(page).to have_text('Project access token creation is disabled in this group. You can still use and manage existing tokens.') - end + it_behaves_like 'resource access tokens creation disallowed', 'Project access token creation is disabled in this group. You can still use and manage existing tokens.' context 'with a project in a personal namespace' do let(:personal_project) { create(:project) } @@ -97,113 +45,25 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do personal_project.add_maintainer(user) end - it 'shows project access token creation form and text' do + it 'shows access token creation form and text' do visit project_settings_access_tokens_path(personal_project) - expect(page).to have_selector('#new_project_access_token') + expect(page).to have_selector('#new_resource_access_token') expect(page).to have_text('Generate project access tokens scoped to this project for your applications that need access to the GitLab API.') end end - - context 'group settings link' do - context 'when user is not a group owner' do - before do - group.add_developer(user) - end - - it 'does not show group settings link' do - visit project_settings_access_tokens_path(project) - - expect(page).not_to have_link('group settings', href: edit_group_path(group)) - end - end - - context 'with nested groups' do - let(:subgroup) { create(:group, parent: group) } - - context 'when user is not a top level group owner' do - before do - subgroup.add_owner(user) - end - - it 'does not show group settings link' do - visit project_settings_access_tokens_path(project) - - expect(page).not_to have_link('group settings', href: edit_group_path(group)) - end - end - end - - context 'when user is a group owner' do - before do - group.add_owner(user) - end - - it 'shows group settings link' do - visit project_settings_access_tokens_path(project) - - expect(page).to have_link('group settings', href: edit_group_path(group)) - end - end - end end end describe 'active tokens' do - let!(:project_access_token) { create_project_access_token } + let!(:resource_access_token) { create_resource_access_token } - it 'shows active project access tokens' do - visit project_settings_access_tokens_path(project) - - expect(active_project_access_tokens).to have_text(project_access_token.name) - end - - context 'when User#time_display_relative is false' do - before do - user.update!(time_display_relative: false) - end - - it 'shows absolute times for expires_at' do - visit project_settings_access_tokens_path(project) - - expect(active_project_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %-d')) - end - end + it_behaves_like 'active resource access tokens' end describe 'inactive tokens' do - let!(:project_access_token) { create_project_access_token } - - no_active_tokens_text = 'This project has no active access tokens.' + let!(:resource_access_token) { create_resource_access_token } - it 'allows revocation of an active token' do - visit project_settings_access_tokens_path(project) - accept_confirm { click_on 'Revoke' } - - expect(page).to have_selector('.settings-message') - expect(no_project_access_tokens_message).to have_text(no_active_tokens_text) - end - - it 'removes expired tokens from active section' do - project_access_token.update!(expires_at: 5.days.ago) - visit project_settings_access_tokens_path(project) - - expect(page).to have_selector('.settings-message') - expect(no_project_access_tokens_message).to have_text(no_active_tokens_text) - end - - context 'when resource access token creation is not allowed' do - before do - group.namespace_settings.update_column(:resource_access_token_creation_allowed, false) - end - - it 'allows revocation of an active token' do - visit project_settings_access_tokens_path(project) - accept_confirm { click_on 'Revoke' } - - expect(page).to have_selector('.settings-message') - expect(no_project_access_tokens_message).to have_text(no_active_tokens_text) - end - end + it_behaves_like 'inactive resource access tokens', 'This project has no active access tokens.' end end diff --git a/spec/features/projects/settings/project_settings_spec.rb b/spec/features/projects/settings/project_settings_spec.rb index 71b319d192c..b67caa5a5f9 100644 --- a/spec/features/projects/settings/project_settings_spec.rb +++ b/spec/features/projects/settings/project_settings_spec.rb @@ -47,7 +47,7 @@ RSpec.describe 'Projects settings' do # disable by clicking toggle forking_enabled_button.click page.within('.sharing-permissions') do - find('input[value="Save changes"]').click + find('[data-testid="project-features-save-button"]').click end wait_for_requests @@ -77,7 +77,7 @@ RSpec.describe 'Projects settings' do expect(default_award_emojis_input.value).to eq('false') page.within('.sharing-permissions') do - find('input[value="Save changes"]').click + find('[data-testid="project-features-save-button"]').click end wait_for_requests diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb index 862bae45fc6..77be351f3d8 100644 --- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb +++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb @@ -54,7 +54,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do within('.sharing-permissions-form') do find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click - find('input[value="Save changes"]').send_keys(:return) + find('[data-testid="project-features-save-button"]').send_keys(:return) end expect(page).not_to have_content 'Pipelines must succeed' @@ -74,7 +74,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do within('.sharing-permissions-form') do find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .gl-toggle').click - find('input[value="Save changes"]').send_keys(:return) + find('[data-testid="project-features-save-button"]').send_keys(:return) end expect(page).to have_content 'Pipelines must succeed' @@ -95,7 +95,7 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do within('.sharing-permissions-form') do find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .gl-toggle').click - find('input[value="Save changes"]').send_keys(:return) + find('[data-testid="project-features-save-button"]').send_keys(:return) end expect(page).to have_content 'Pipelines must succeed' diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb index dc551158895..89f6b4237a4 100644 --- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb +++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb @@ -316,7 +316,7 @@ RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do visit project_path(project) page.within('.project-buttons') do - expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project)) + expect(page).to have_link('Add Kubernetes cluster', href: project_clusters_path(project)) end end diff --git a/spec/features/projects/user_changes_project_visibility_spec.rb b/spec/features/projects/user_changes_project_visibility_spec.rb index 345d16982fd..68fed9b8a74 100644 --- a/spec/features/projects/user_changes_project_visibility_spec.rb +++ b/spec/features/projects/user_changes_project_visibility_spec.rb @@ -5,14 +5,6 @@ require 'spec_helper' RSpec.describe 'User changes public project visibility', :js do include ProjectForksHelper - before do - fork_project(project, project.owner) - - sign_in(project.owner) - - visit edit_project_path(project) - end - shared_examples 'changing visibility to private' do it 'requires confirmation' do visibility_select = first('.project-feature-controls .select-control') @@ -22,7 +14,7 @@ RSpec.describe 'User changes public project visibility', :js do click_button 'Save changes' end - find('.js-legacy-confirm-danger-input').send_keys(project.path_with_namespace) + fill_in 'confirm_name_input', with: project.path_with_namespace page.within '.modal' do click_button 'Reduce project visibility' @@ -34,15 +26,85 @@ RSpec.describe 'User changes public project visibility', :js do end end - context 'when a project is public' do + shared_examples 'does not require confirmation' do + it 'saves without confirmation' do + visibility_select = first('.project-feature-controls .select-control') + visibility_select.select('Private') + + page.within('#js-shared-permissions') do + click_button 'Save changes' + end + + wait_for_requests + + expect(project.reload).to be_private + end + end + + context 'when the project has forks' do + before do + fork_project(project, project.owner) + + sign_in(project.owner) + + visit edit_project_path(project) + end + + context 'when a project is public' do + let(:project) { create(:project, :empty_repo, :public) } + + it_behaves_like 'changing visibility to private' + end + + context 'when the project is internal' do + let(:project) { create(:project, :empty_repo, :internal) } + + it_behaves_like 'changing visibility to private' + end + + context 'when the visibility level is untouched' do + let(:project) { create(:project, :empty_repo, :public) } + + it 'saves without confirmation' do + expect(page).to have_selector('.js-emails-disabled', visible: true) + find('.js-emails-disabled input[type="checkbox"]').click + + page.within('#js-shared-permissions') do + click_button 'Save changes' + end + + wait_for_requests + + expect(project.reload).to be_public + end + end + end + + context 'when the project is not forked' do let(:project) { create(:project, :empty_repo, :public) } - it_behaves_like 'changing visibility to private' + before do + sign_in(project.owner) + + visit edit_project_path(project) + end + + it_behaves_like 'does not require confirmation' end - context 'when the project is internal' do - let(:project) { create(:project, :empty_repo, :internal) } + context 'with unlink_fork_network_upon_visibility_decrease = false' do + let(:project) { create(:project, :empty_repo, :public) } + + before do + stub_feature_flags(unlink_fork_network_upon_visibility_decrease: false) + + fork_project(project, project.owner) + + sign_in(project.owner) + + visit edit_project_path(project) + end - it_behaves_like 'changing visibility to private' + it_behaves_like 'does not require confirmation' end end diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb index 17c65e645f4..c4e2e3353a4 100644 --- a/spec/features/projects/user_creates_project_spec.rb +++ b/spec/features/projects/user_creates_project_spec.rb @@ -6,7 +6,6 @@ RSpec.describe 'User creates a project', :js do let(:user) { create(:user) } before do - stub_feature_flags(paginatable_namespace_drop_down_for_project_creation: false) sign_in(user) create(:personal_key, user: user) end @@ -44,9 +43,7 @@ RSpec.describe 'User creates a project', :js do expect(page).to have_checked_field 'Initialize repository with a README' expect(page).to have_checked_field 'Enable Static Application Security Testing (SAST)' - page.within('#content-body') do - click_button('Create project') - end + click_button('Create project') project = Project.last @@ -96,12 +93,10 @@ RSpec.describe 'User creates a project', :js do fill_in :project_name, with: 'A Subgroup Project' fill_in :project_path, with: 'a-subgroup-project' - page.find('.js-select-namespace').click - page.find("div[role='option']", text: subgroup.full_path).click + click_button user.username + click_button subgroup.full_path - page.within('#content-body') do - click_button('Create project') - end + click_button('Create project') expect(page).to have_content("Project 'A Subgroup Project' was successfully created") @@ -125,8 +120,8 @@ RSpec.describe 'User creates a project', :js do fill_in :project_name, with: 'a-new-project' fill_in :project_path, with: 'a-new-project' - page.find('.js-select-namespace').click - page.find("div[role='option']", text: group.full_path).click + click_button user.username + click_button group.full_path page.within('#content-body') do click_button('Create project') diff --git a/spec/features/projects/user_sorts_projects_spec.rb b/spec/features/projects/user_sorts_projects_spec.rb index 6a5ed49f1a6..71e43467a39 100644 --- a/spec/features/projects/user_sorts_projects_spec.rb +++ b/spec/features/projects/user_sorts_projects_spec.rb @@ -41,10 +41,10 @@ RSpec.describe 'User sorts projects and order persists' do sign_in(user) visit(explore_projects_path) find('#sort-projects-dropdown').click - first(:link, 'Last updated').click + first(:link, 'Updated date').click end - it_behaves_like "sort order persists across all views", "Last updated", "Last updated" + it_behaves_like "sort order persists across all views", 'Updated date', 'Updated date' end context 'from dashboard projects' do diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb index d220db01c24..94085b075aa 100644 --- a/spec/features/projects/view_on_env_spec.rb +++ b/spec/features/projects/view_on_env_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'View on environment', :js do let(:user) { project.creator } before do + stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350457 project.add_maintainer(user) end @@ -48,26 +49,6 @@ RSpec.describe 'View on environment', :js do let(:environment) { create(:environment, project: project, name: 'review/feature', external_url: 'http://feature.review.example.com') } let!(:deployment) { create(:deployment, :success, environment: environment, ref: branch_name, sha: sha) } - context 'when visiting the diff of a merge request for the branch' do - let(:merge_request) { create(:merge_request, :simple, source_project: project, source_branch: branch_name) } - - before do - sign_in(user) - - visit diffs_project_merge_request_path(project, merge_request) - - wait_for_requests - end - - it 'has a "View on env" button' do - within '.diffs' do - text = 'View on feature.review.example.com' - url = 'http://feature.review.example.com/ruby/feature' - expect(page).to have_selector("a[title='#{text}'][href='#{url}']") - end - end - end - context 'when visiting a comparison for the branch' do before do sign_in(user) diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index 15ec11c256f..4278efc5a8f 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -29,21 +29,6 @@ RSpec.describe 'Protected Branches', :js do expect(page).to have_button('Only a project maintainer or owner can delete a protected branch', disabled: true) end - - context 'when feature flag :delete_branch_confirmation_modals is disabled' do - before do - stub_feature_flags(delete_branch_confirmation_modals: false) - end - - it 'does not allow developer to remove protected branch' do - visit project_branches_path(project) - - find('input[data-testid="branch-search"]').set('fix') - find('input[data-testid="branch-search"]').native.send_keys(:enter) - - expect(page).to have_selector('button[data-testid="remove-protected-branch"][disabled]') - end - end end end @@ -79,32 +64,6 @@ RSpec.describe 'Protected Branches', :js do expect(page).to have_content('No branches to show') end - - context 'when the feature flag :delete_branch_confirmation_modals is disabled' do - before do - stub_feature_flags(delete_branch_confirmation_modals: false) - end - - it 'removes branch after modal confirmation' do - visit project_branches_path(project) - - find('input[data-testid="branch-search"]').set('fix') - find('input[data-testid="branch-search"]').native.send_keys(:enter) - - expect(page).to have_content('fix') - expect(find('.all-branches')).to have_selector('li', count: 1) - page.find('[data-target="#modal-delete-branch"]').click - - expect(page).to have_css('.js-delete-branch[disabled]') - fill_in 'delete_branch_input', with: 'fix' - click_link 'Delete protected branch' - - find('input[data-testid="branch-search"]').set('fix') - find('input[data-testid="branch-search"]').native.send_keys(:enter) - - expect(page).to have_content('No branches to show') - end - end end end diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index 22de77f7cd0..49c468976b9 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -268,10 +268,27 @@ RSpec.describe 'Runners' do it 'group runners are not available' do visit project_runners_path(project) + expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.' + expect(page).to have_content 'Ask your group owner to set up a group runner' + end + end + end + + context 'as project maintainer and group owner' do + before do + group.add_owner(user) + end + + context 'project with a group but no group runner' do + let(:project) { create :project, group: group } + + it 'group runners are 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 'Group maintainers can register group runners in the group\'s CI/CD settings.' - expect(page).not_to have_content 'Ask your group maintainer to set up a group runner' + expect(page).to have_content 'Group owners can register group runners in the group\'s CI/CD settings.' + expect(page).not_to have_content 'Ask your group owner to set up a group runner' end end end @@ -296,8 +313,8 @@ RSpec.describe 'Runners' do expect(page).to have_content 'This group does not have any group runners yet.' - expect(page).not_to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.' - expect(page).to have_content 'Ask your group maintainer to set up a group runner.' + expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.' + expect(page).to have_content 'Ask your group owner to set up a group runner.' end end diff --git a/spec/features/user_sees_marketing_header_spec.rb b/spec/features/user_sees_marketing_header_spec.rb new file mode 100644 index 00000000000..31f088ce010 --- /dev/null +++ b/spec/features/user_sees_marketing_header_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe 'User sees experimental lmarketing header' do + let_it_be(:project) { create(:project, :public) } + + context 'when not logged in' do + context 'when experiment candidate' do + it 'shows marketing header links', :aggregate_failures do + stub_experiments(logged_out_marketing_header: :candidate) + + visit project_path(project) + + expect(page).to have_text "About GitLab" + expect(page).to have_text "Pricing" + expect(page).to have_text "Talk to an expert" + expect(page).to have_text "Sign up now" + expect(page).to have_text "Login" + end + end + + context 'when experiment candidate (trial focused variant)' do + it 'shows marketing header links', :aggregate_failures do + stub_experiments(logged_out_marketing_header: :trial_focused) + + visit project_path(project) + + expect(page).to have_text "About GitLab" + expect(page).to have_text "Pricing" + expect(page).to have_text "Talk to an expert" + expect(page).to have_text "Get a free trial" + expect(page).to have_text "Sign up" + expect(page).to have_text "Login" + end + end + + context 'when experiment control' do + it 'does not show marketing header links', :aggregate_failures do + stub_experiments(logged_out_marketing_header: :control) + + visit project_path(project) + + expect(page).not_to have_text "About GitLab" + expect(page).not_to have_text "Pricing" + expect(page).not_to have_text "Talk to an expert" + expect(page).not_to have_text "Sign up now" + expect(page).not_to have_text "Login" + expect(page).not_to have_text "Get a free trial" + expect(page).not_to have_text "Sign up" + expect(page).to have_text "Sign in / Register" + end + end + end + + context 'when logged in' do + it 'does not show marketing header links', :aggregate_failures do + sign_in(create(:user)) + + stub_experiments(logged_out_marketing_header: :candidate) + + visit project_path(project) + + expect(page).not_to have_text "About GitLab" + expect(page).not_to have_text "Pricing" + expect(page).not_to have_text "Talk to an expert" + end + end +end diff --git a/spec/features/user_sorts_things_spec.rb b/spec/features/user_sorts_things_spec.rb index 6eaa620b538..8e6f6a96bd2 100644 --- a/spec/features/user_sorts_things_spec.rb +++ b/spec/features/user_sorts_things_spec.rb @@ -21,7 +21,7 @@ RSpec.describe "User sorts things" do end it "issues -> project home page -> issues" do - sort_option = "Last updated" + sort_option = 'Updated date' visit(project_issues_path(project)) @@ -34,7 +34,7 @@ RSpec.describe "User sorts things" do end it "issues -> merge requests" do - sort_option = "Last updated" + sort_option = 'Updated date' visit(project_issues_path(project)) @@ -46,7 +46,7 @@ RSpec.describe "User sorts things" do end it "merge requests -> dashboard merge requests" do - sort_option = "Last updated" + sort_option = 'Updated date' visit(project_merge_requests_path(project)) diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb index 6b21412ae3d..f9b23626397 100644 --- a/spec/features/users/anonymous_sessions_spec.rb +++ b/spec/features/users/anonymous_sessions_spec.rb @@ -9,7 +9,7 @@ RSpec.describe 'Session TTLs', :clean_gitlab_redis_shared_state do visit new_user_session_path # The session key only gets created after a post fill_in 'user_login', with: 'non-existant@gitlab.org' - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' expect(page).to have_content('Invalid login or password') diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 7ef11194ff9..2780549eea1 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -49,15 +49,15 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do expect(current_path).to eq edit_user_password_path expect(page).to have_content('Please create a password for your new account.') - fill_in 'user_password', with: 'password' - fill_in 'user_password_confirmation', with: 'password' + fill_in 'user_password', with: Gitlab::Password.test_default + fill_in 'user_password_confirmation', with: Gitlab::Password.test_default click_button 'Change your password' expect(current_path).to eq new_user_session_path expect(page).to have_content(I18n.t('devise.passwords.updated_not_active')) fill_in 'user_login', with: user.username - fill_in 'user_password', with: 'password' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' expect_single_session_with_authenticated_ttl @@ -210,7 +210,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do end it 'does not allow sign-in if the user password is updated before entering a one-time code' do - user.update!(password: 'new_password') + user.update!(password: "new" + Gitlab::Password.test_default) enter_code(user.current_otp) @@ -447,7 +447,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do visit new_user_session_path fill_in 'user_login', with: user.email - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' expect(current_path).to eq(new_profile_password_path) @@ -456,7 +456,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do end context 'with invalid username and password' do - let(:user) { create(:user, password: 'not-the-default') } + let(:user) { create(:user, password: "not" + Gitlab::Password.test_default) } it 'blocks invalid login' do expect(authentication_metrics) @@ -767,7 +767,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do visit new_user_session_path fill_in 'user_login', with: user.email - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' @@ -788,7 +788,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do visit new_user_session_path fill_in 'user_login', with: user.email - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' @@ -809,7 +809,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do visit new_user_session_path fill_in 'user_login', with: user.email - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' @@ -844,7 +844,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do visit new_user_session_path fill_in 'user_login', with: user.email - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' fill_in 'user_otp_attempt', with: user.reload.current_otp @@ -870,7 +870,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do visit new_user_session_path fill_in 'user_login', with: user.email - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default click_button 'Sign in' expect_to_be_on_terms_page @@ -878,7 +878,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do expect(current_path).to eq(new_profile_password_path) - fill_in 'user_password', with: '12345678' + fill_in 'user_password', with: Gitlab::Password.test_default fill_in 'user_new_password', with: 'new password' fill_in 'user_password_confirmation', with: 'new password' click_button 'Set new password' |