diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-18 13:16:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-18 13:16:36 +0000 |
commit | 311b0269b4eb9839fa63f80c8d7a58f32b8138a0 (patch) | |
tree | 07e7870bca8aed6d61fdcc810731c50d2c40af47 /spec/features | |
parent | 27909cef6c4170ed9205afa7426b8d3de47cbb0c (diff) | |
download | gitlab-ce-311b0269b4eb9839fa63f80c8d7a58f32b8138a0.tar.gz |
Add latest changes from gitlab-org/gitlab@14-5-stable-eev14.5.0-rc42
Diffstat (limited to 'spec/features')
112 files changed, 1194 insertions, 392 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb index cb69eac8035..0785c736cfb 100644 --- a/spec/features/admin/admin_appearance_spec.rb +++ b/spec/features/admin/admin_appearance_spec.rb @@ -94,7 +94,7 @@ RSpec.describe 'Admin Appearance' do sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' expect_custom_new_project_appearance(appearance) end diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb index c326d0fd741..53caf0fac33 100644 --- a/spec/features/admin/admin_deploy_keys_spec.rb +++ b/spec/features/admin/admin_deploy_keys_spec.rb @@ -3,11 +3,13 @@ require 'spec_helper' RSpec.describe 'admin deploy keys' do + let_it_be(:admin) { create(:admin) } + let!(:deploy_key) { create(:deploy_key, public: true) } let!(:another_deploy_key) { create(:another_deploy_key, public: true) } before do - admin = create(:admin) + stub_feature_flags(admin_deploy_keys_vue: false) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) end @@ -15,7 +17,7 @@ RSpec.describe 'admin deploy keys' do it 'show all public deploy keys' do visit admin_deploy_keys_path - page.within(find('.deploy-keys-list', match: :first)) do + 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 @@ -26,7 +28,7 @@ RSpec.describe 'admin deploy keys' do visit admin_deploy_keys_path - page.within(find('.deploy-keys-list', match: :first)) do + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do expect(page).to have_content(write_key.project.full_name) end end @@ -46,7 +48,7 @@ RSpec.describe 'admin deploy keys' do expect(current_path).to eq admin_deploy_keys_path - page.within(find('.deploy-keys-list', match: :first)) do + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do expect(page).to have_content('laptop') end end @@ -64,7 +66,7 @@ RSpec.describe 'admin deploy keys' do expect(current_path).to eq admin_deploy_keys_path - page.within(find('.deploy-keys-list', match: :first)) do + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do expect(page).to have_content('new-title') end end @@ -79,9 +81,23 @@ RSpec.describe 'admin deploy keys' do find('tr', text: deploy_key.title).click_link('Remove') expect(current_path).to eq admin_deploy_keys_path - page.within(find('.deploy-keys-list', match: :first)) do + page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do expect(page).not_to have_content(deploy_key.title) end end end + + context 'when `admin_deploy_keys_vue` feature flag is enabled', :js do + before do + stub_feature_flags(admin_deploy_keys_vue: true) + + visit admin_deploy_keys_path + end + + it 'renders the Vue app', :aggregate_failures do + expect(page).to have_content('Public deploy keys') + expect(page).to have_selector('[data-testid="deploy-keys-list"]') + expect(page).to have_link('New deploy key', href: new_admin_deploy_key_path) + end + end end diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb index 1f34c4ed17c..f65e85b4cb6 100644 --- a/spec/features/admin/admin_disables_two_factor_spec.rb +++ b/spec/features/admin/admin_disables_two_factor_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin disables 2FA for a user' do it 'successfully', :js do + stub_feature_flags(bootstrap_confirmation_modals: false) admin = create(:admin) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 8315b8f44b0..8d4e7a7442c 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -252,6 +252,7 @@ RSpec.describe 'Admin Groups' do describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do it 'removes admin from the group' do + stub_feature_flags(bootstrap_confirmation_modals: false) group.add_user(current_user, Gitlab::Access::DEVELOPER) visit group_group_members_path(group) diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index a501efd82ed..32e4d18227e 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -79,6 +79,7 @@ RSpec.describe 'Admin::Hooks' do let(:hook_url) { generate(:url) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) create(:system_hook, url: hook_url) end diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 08d81906d9f..65de1160cfd 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -14,6 +14,7 @@ RSpec.describe 'admin issues labels' do describe 'list' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit admin_labels_path end diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb index b6437fce540..4cf290293bd 100644 --- a/spec/features/admin/admin_manage_applications_spec.rb +++ b/spec/features/admin/admin_manage_applications_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'admin manage applications' do let_it_be(:new_application_path) { new_admin_application_path } let_it_be(:applications_path) { admin_applications_path } + let_it_be(:index_path) { admin_applications_path } before do admin = create(:admin) diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 8053be89ffc..7e2751daefa 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -24,40 +24,37 @@ RSpec.describe "Admin Runners" do visit admin_runners_path - expect(page).to have_text "Set up a shared runner manually" + expect(page).to have_text "Register an instance runner" expect(page).to have_text "Runners currently online: 1" end - it 'with an instance runner shows an instance badge and no project count' do + it 'with an instance runner shows an instance badge' do runner = create(:ci_runner, :instance) visit admin_runners_path within "[data-testid='runner-row-#{runner.id}']" do expect(page).to have_selector '.badge', text: 'shared' - expect(page).to have_text 'n/a' end end - it 'with a group runner shows a group badge and no project count' do + it 'with a group runner shows a group badge' do runner = create(:ci_runner, :group, groups: [group]) visit admin_runners_path within "[data-testid='runner-row-#{runner.id}']" do expect(page).to have_selector '.badge', text: 'group' - expect(page).to have_text 'n/a' end end - it 'with a project runner shows a project badge and project count' do + it 'with a project runner shows a project badge' do runner = create(:ci_runner, :project, projects: [project]) visit admin_runners_path within "[data-testid='runner-row-#{runner.id}']" do expect(page).to have_selector '.badge', text: 'specific' - expect(page).to have_text '1' end end @@ -69,6 +66,13 @@ RSpec.describe "Admin Runners" do visit admin_runners_path end + it 'runner types tabs have total counts and can be selected' do + expect(page).to have_link('All 2') + expect(page).to have_link('Instance 2') + expect(page).to have_link('Group 0') + expect(page).to have_link('Project 0') + end + it 'shows runners' do expect(page).to have_content("runner-foo") expect(page).to have_content("runner-bar") @@ -137,6 +141,19 @@ RSpec.describe "Admin Runners" do expect(page).not_to have_content 'runner-b-1' expect(page).not_to have_content 'runner-a-2' 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) + + visit admin_runners_path + + # 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-connected' + expect(page).to have_content 'runner-not-connected' + end end describe 'filter by type' do @@ -145,13 +162,25 @@ RSpec.describe "Admin Runners" do create(:ci_runner, :group, description: 'runner-group', groups: [group]) end + it '"All" tab is selected by default' do + visit admin_runners_path + + page.within('[data-testid="runner-type-tabs"]') do + expect(page).to have_link('All', class: 'active') + end + end + it 'shows correct runner when type matches' do visit admin_runners_path expect(page).to have_content 'runner-project' expect(page).to have_content 'runner-group' - input_filtered_search_filter_is_only('Type', 'project') + page.within('[data-testid="runner-type-tabs"]') do + click_on('Project') + + expect(page).to have_link('Project', class: 'active') + end expect(page).to have_content 'runner-project' expect(page).not_to have_content 'runner-group' @@ -160,7 +189,11 @@ RSpec.describe "Admin Runners" do it 'shows no runner when type does not match' do visit admin_runners_path - input_filtered_search_filter_is_only('Type', 'instance') + page.within('[data-testid="runner-type-tabs"]') do + click_on 'Instance' + + expect(page).to have_link('Instance', class: 'active') + end expect(page).not_to have_content 'runner-project' expect(page).not_to have_content 'runner-group' @@ -173,7 +206,9 @@ RSpec.describe "Admin Runners" do visit admin_runners_path - input_filtered_search_filter_is_only('Type', 'project') + page.within('[data-testid="runner-type-tabs"]') do + click_on 'Project' + end expect(page).to have_content 'runner-project' expect(page).to have_content 'runner-2-project' @@ -185,6 +220,26 @@ RSpec.describe "Admin Runners" do expect(page).not_to have_content 'runner-2-project' expect(page).not_to have_content 'runner-group' end + + it 'maintains the same filter when switching between runner types' do + create(:ci_runner, :project, description: 'runner-paused-project', active: false, projects: [project]) + + visit admin_runners_path + + input_filtered_search_filter_is_only('Status', 'Active') + + expect(page).to have_content 'runner-project' + expect(page).to have_content 'runner-group' + expect(page).not_to have_content 'runner-paused-project' + + page.within('[data-testid="runner-type-tabs"]') do + click_on 'Project' + end + + expect(page).to have_content 'runner-project' + expect(page).not_to have_content 'runner-group' + expect(page).not_to have_content 'runner-paused-project' + end end describe 'filter by tag' do @@ -267,29 +322,55 @@ RSpec.describe "Admin Runners" do end it 'has all necessary texts including no runner message' do - expect(page).to have_text "Set up a shared runner manually" + expect(page).to have_text "Register an instance runner" expect(page).to have_text "Runners currently online: 0" expect(page).to have_text 'No runners found' end end - describe 'runners registration token' do + describe 'runners registration' do let!(:token) { Gitlab::CurrentSettings.runners_registration_token } before do visit admin_runners_path + + click_on 'Register an instance runner' + end + + describe 'show registration instructions' do + before do + click_on 'Show runner installation and registration instructions' + + wait_for_requests + end + + it 'opens runner installation modal' do + expect(page).to have_text "Install a runner" + + expect(page).to have_text "Environment" + expect(page).to have_text "Architecture" + expect(page).to have_text "Download and install binary" + end + + it 'dismisses runner installation modal' do + page.within('[role="dialog"]') do + click_button('Close', match: :first) + end + + expect(page).not_to have_text "Install a runner" + end end it 'has a registration token' do click_on 'Click to reveal' - expect(page.find('[data-testid="registration-token"]')).to have_content(token) + expect(page.find('[data-testid="token-value"]')).to have_content(token) end describe 'reset registration token' do - let(:page_token) { find('[data-testid="registration-token"]').text } + let(:page_token) { find('[data-testid="token-value"]').text } before do - click_button 'Reset registration token' + click_on 'Reset registration token' page.accept_alert @@ -297,6 +378,8 @@ RSpec.describe "Admin Runners" do end it 'changes registration token' do + click_on 'Register an instance runner' + click_on 'Click to reveal' expect(page_token).not_to eq token end diff --git a/spec/features/admin/admin_sees_project_statistics_spec.rb b/spec/features/admin/admin_sees_project_statistics_spec.rb index 3433cc01b8e..9d9217c4574 100644 --- a/spec/features/admin/admin_sees_project_statistics_spec.rb +++ b/spec/features/admin/admin_sees_project_statistics_spec.rb @@ -16,7 +16,7 @@ RSpec.describe "Admin > Admin sees project statistics" do let(:project) { create(:project, :repository) } it "shows project statistics" do - expect(page).to have_content("Storage: 0 Bytes (Repository: 0 Bytes / Wikis: 0 Bytes / Build Artifacts: 0 Bytes / LFS: 0 Bytes / Snippets: 0 Bytes / Packages: 0 Bytes / Uploads: 0 Bytes)") + expect(page).to have_content("Storage: 0 Bytes (Repository: 0 Bytes / Wikis: 0 Bytes / Build Artifacts: 0 Bytes / Pipeline Artifacts: 0 Bytes / LFS: 0 Bytes / Snippets: 0 Bytes / Packages: 0 Bytes / Uploads: 0 Bytes)") end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 1c50a7f891f..0a39baca259 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -491,22 +491,22 @@ RSpec.describe 'Admin updates settings' do group = create(:group) page.within('.as-performance-bar') do - check 'Allow non-administrators to access to the performance bar' + check 'Allow non-administrators access to the performance bar' fill_in 'Allow access to members of the following group', with: group.path click_on 'Save changes' end expect(page).to have_content "Application settings saved successfully" - expect(find_field('Allow non-administrators to access to the performance bar')).to be_checked + expect(find_field('Allow non-administrators access to the performance bar')).to be_checked expect(find_field('Allow access to members of the following group').value).to eq group.path page.within('.as-performance-bar') do - uncheck 'Allow non-administrators to access to the performance bar' + uncheck 'Allow non-administrators access to the performance bar' click_on 'Save changes' end expect(page).to have_content 'Application settings saved successfully' - expect(find_field('Allow non-administrators to access to the performance bar')).not_to be_checked + expect(find_field('Allow non-administrators access to the performance bar')).not_to be_checked expect(find_field('Allow access to members of the following group').value).to be_nil end diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index ed8ea84fbf8..6643ebe82e6 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -74,6 +74,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) } it "allows revocation of an active impersonation token" do + stub_feature_flags(bootstrap_confirmation_modals: false) visit admin_user_impersonation_tokens_path(user_id: user.username) accept_confirm { click_on "Revoke" } diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index 0e448446085..c13313609b5 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Admin uses repository checks', :request_store do let(:admin) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) end diff --git a/spec/features/admin/clusters/eks_spec.rb b/spec/features/admin/clusters/eks_spec.rb index a1bac720349..bb2678de2ae 100644 --- a/spec/features/admin/clusters/eks_spec.rb +++ b/spec/features/admin/clusters/eks_spec.rb @@ -14,7 +14,7 @@ RSpec.describe 'Instance-level AWS EKS Cluster', :js do before do visit admin_clusters_path - click_link 'Integrate with a cluster certificate' + click_link 'Connect with a certificate' end context 'when user creates a cluster on AWS EKS' do diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index 624bfde7359..73477fb93dd 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Admin::Users::User' do let_it_be(:current_user) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 119b01ff552..fa943245fcb 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Admin::Users' do let_it_be(:current_user) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end @@ -164,7 +165,7 @@ RSpec.describe 'Admin::Users' do visit admin_users_path - page.within('.filter-two-factor-enabled small') do + page.within('.filter-two-factor-enabled .gl-tab-counter-badge') do expect(page).to have_content('1') end end @@ -181,7 +182,7 @@ RSpec.describe 'Admin::Users' do it 'counts users who have not enabled 2FA' do visit admin_users_path - page.within('.filter-two-factor-disabled small') do + page.within('.filter-two-factor-disabled .gl-tab-counter-badge') do expect(page).to have_content('2') # Including admin end end @@ -200,7 +201,7 @@ RSpec.describe 'Admin::Users' do visit admin_users_path - page.within('.filter-blocked-pending-approval small') do + page.within('.filter-blocked-pending-approval .gl-tab-counter-badge') do expect(page).to have_content('2') end end diff --git a/spec/features/alert_management/alert_management_list_spec.rb b/spec/features/alert_management/alert_management_list_spec.rb index 1e710169c9c..2fbce27033e 100644 --- a/spec/features/alert_management/alert_management_list_spec.rb +++ b/spec/features/alert_management/alert_management_list_spec.rb @@ -55,28 +55,4 @@ RSpec.describe 'Alert Management index', :js do it_behaves_like 'alert page with title, filtered search, and table' end end - - describe 'managed_alerts_deprecation feature flag' do - subject { page } - - before do - stub_feature_flags(managed_alerts_deprecation: feature_flag_value) - sign_in(developer) - - visit project_alert_management_index_path(project) - wait_for_requests - end - - context 'feature flag on' do - let(:feature_flag_value) { true } - - it { is_expected.to have_pushed_frontend_feature_flags(managedAlertsDeprecation: true) } - end - - context 'feature flag off' do - let(:feature_flag_value) { false } - - it { is_expected.to have_pushed_frontend_feature_flags(managedAlertsDeprecation: false) } - end - end end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 9a5b5bbfc34..2f21961d1fc 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -536,6 +536,7 @@ RSpec.describe 'Project issue boards', :js do let_it_be(:user_guest) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_guest(user_guest) sign_in(user_guest) visit project_board_path(project, board) diff --git a/spec/features/clusters/create_agent_spec.rb b/spec/features/clusters/create_agent_spec.rb new file mode 100644 index 00000000000..f40932c4750 --- /dev/null +++ b/spec/features/clusters/create_agent_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Cluster agent registration', :js do + let_it_be(:project) { create(:project, :custom_repo, files: { '.gitlab/agents/example-agent-1/config.yaml' => '' }) } + let_it_be(:current_user) { create(:user, maintainer_projects: [project]) } + + before do + allow(Gitlab::Kas).to receive(:enabled?).and_return(true) + allow(Gitlab::Kas).to receive(:internal_url).and_return('kas.example.internal') + + allow_next_instance_of(Gitlab::Kas::Client) do |client| + allow(client).to receive(:list_agent_config_files).and_return([ + double(agent_name: 'example-agent-1', path: '.gitlab/agents/example-agent-1/config.yaml'), + double(agent_name: 'example-agent-2', path: '.gitlab/agents/example-agent-2/config.yaml') + ]) + end + + allow(Devise).to receive(:friendly_token).and_return('example-agent-token') + + sign_in(current_user) + visit project_clusters_path(project) + end + + it 'allows the user to select an agent to install, and displays the resulting agent token' do + click_button('Actions') + expect(page).to have_content('Install new Agent') + + click_button('Select an Agent') + click_button('example-agent-2') + click_button('Register Agent') + + expect(page).to have_content('The token value will not be shown again after you close this window.') + expect(page).to have_content('example-agent-token') + expect(page).to have_content('docker run --pull=always --rm') + + within find('.modal-footer') do + click_button('Close') + end + + expect(page).to have_link('example-agent-2') + end +end diff --git a/spec/features/contextual_sidebar_spec.rb b/spec/features/contextual_sidebar_spec.rb index 39881a28b11..29c7e0ddd21 100644 --- a/spec/features/contextual_sidebar_spec.rb +++ b/spec/features/contextual_sidebar_spec.rb @@ -3,35 +3,110 @@ require 'spec_helper' RSpec.describe 'Contextual sidebar', :js do - let_it_be(:project) { create(:project) } + context 'when context is a project' do + let_it_be(:project) { create(:project) } - let(:user) { project.owner } + let(:user) { project.owner } - before do - sign_in(user) + before do + sign_in(user) + end - visit project_path(project) - end + context 'when analyzing the menu' do + before do + visit project_path(project) + end + + it 'shows flyout navs when collapsed or expanded apart from on the active item when expanded', :aggregate_failures do + expect(page).not_to have_selector('.js-sidebar-collapsed') + + find('.rspec-link-pipelines').hover + + expect(page).to have_selector('.is-showing-fly-out') + + find('.rspec-project-link').hover + + expect(page).not_to have_selector('.is-showing-fly-out') + + find('.rspec-toggle-sidebar').click + + find('.rspec-link-pipelines').hover + + expect(page).to have_selector('.is-showing-fly-out') - it 'shows flyout navs when collapsed or expanded apart from on the active item when expanded', :aggregate_failures do - expect(page).not_to have_selector('.js-sidebar-collapsed') + find('.rspec-project-link').hover + + expect(page).to have_selector('.is-showing-fly-out') + end + end + + context 'with invite_members_in_side_nav experiment', :experiment do + it 'allows opening of modal for the candidate experience' do + stub_experiments(invite_members_in_side_nav: :candidate) + expect(experiment(:invite_members_in_side_nav)).to track(:assignment) + .with_context(group: project.group) + .on_next_instance + + visit project_path(project) + + page.within '[data-test-id="side-nav-invite-members"' do + find('[data-test-id="invite-members-button"').click + end + + expect(page).to have_content("You're inviting members to the") + end + + it 'does not have invite members link in side nav for the control experience' do + stub_experiments(invite_members_in_side_nav: :control) + expect(experiment(:invite_members_in_side_nav)).to track(:assignment) + .with_context(group: project.group) + .on_next_instance + + visit project_path(project) + + expect(page).not_to have_css('[data-test-id="side-nav-invite-members"') + end + end + end - find('.rspec-link-pipelines').hover + context 'when context is a group' do + let_it_be(:user) { create(:user) } + let_it_be(:group) do + create(:group).tap do |g| + g.add_owner(user) + end + end - expect(page).to have_selector('.is-showing-fly-out') + before do + sign_in(user) + end - find('.rspec-project-link').hover + context 'with invite_members_in_side_nav experiment', :experiment do + it 'allows opening of modal for the candidate experience' do + stub_experiments(invite_members_in_side_nav: :candidate) + expect(experiment(:invite_members_in_side_nav)).to track(:assignment) + .with_context(group: group) + .on_next_instance - expect(page).not_to have_selector('.is-showing-fly-out') + visit group_path(group) - find('.rspec-toggle-sidebar').click + page.within '[data-test-id="side-nav-invite-members"' do + find('[data-test-id="invite-members-button"').click + end - find('.rspec-link-pipelines').hover + expect(page).to have_content("You're inviting members to the") + end - expect(page).to have_selector('.is-showing-fly-out') + it 'does not have invite members link in side nav for the control experience' do + stub_experiments(invite_members_in_side_nav: :control) + expect(experiment(:invite_members_in_side_nav)).to track(:assignment) + .with_context(group: group) + .on_next_instance - find('.rspec-project-link').hover + visit group_path(group) - expect(page).to have_selector('.is-showing-fly-out') + expect(page).not_to have_css('[data-test-id="side-nav-invite-members"') + end + end end end diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 34a55118cb3..69361f66a71 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'Value Stream Analytics', :js do let_it_be(:user) { create(:user) } let_it_be(:guest) { create(:user) } let_it_be(:stage_table_selector) { '[data-testid="vsa-stage-table"]' } + let_it_be(:stage_filter_bar) { '[data-testid="vsa-filter-bar"]' } let_it_be(:stage_table_event_selector) { '[data-testid="vsa-stage-event"]' } let_it_be(:stage_table_event_title_selector) { '[data-testid="vsa-stage-event-title"]' } let_it_be(:stage_table_pagination_selector) { '[data-testid="vsa-stage-pagination"]' } @@ -27,9 +28,16 @@ RSpec.describe 'Value Stream Analytics', :js do def set_daterange(from_date, to_date) page.find(".js-daterange-picker-from input").set(from_date) page.find(".js-daterange-picker-to input").set(to_date) + + # simulate a blur event + page.find(".js-daterange-picker-to input").send_keys(:tab) wait_for_all_requests end + before do + stub_feature_flags(use_vsa_aggregated_tables: false) + end + context 'as an allowed user' do context 'when project is new' do before do @@ -97,7 +105,7 @@ RSpec.describe 'Value Stream Analytics', :js do end end - it 'shows data on each stage', :sidekiq_might_not_need_inline do + it 'shows data on each stage', :sidekiq_might_not_need_inline, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338332' do expect_issue_to_be_present click_stage('Plan') @@ -133,7 +141,7 @@ RSpec.describe 'Value Stream Analytics', :js do expect(metrics_values).to eq(['-'] * 4) end - it 'can sort records' do + it 'can sort records', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338332' do # NOTE: checking that the string changes should suffice # depending on the order the tests are run we might run into problems with hard coded strings original_first_title = first_stage_title @@ -158,6 +166,18 @@ RSpec.describe 'Value Stream Analytics', :js do expect(page).not_to have_text(original_first_title, exact: true) end + it 'can navigate directly to a value stream stream stage with filters applied' do + visit project_cycle_analytics_path(project, created_before: '2019-12-31', created_after: '2019-11-01', stage_id: 'code', milestone_title: milestone.title) + wait_for_requests + + expect(page).to have_selector('.gl-path-active-item-indigo', text: 'Code') + expect(page.find(".js-daterange-picker-from input").value).to eq("2019-11-01") + expect(page.find(".js-daterange-picker-to input").value).to eq("2019-12-31") + + filter_bar = page.find(stage_filter_bar) + expect(filter_bar.find(".gl-filtered-search-token-data-content").text).to eq("%#{milestone.title}") + end + def stage_time_column stage_table.find(stage_table_duration_column_header_selector).ancestor("th") end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 27419479479..82288a6c1a6 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -80,7 +80,7 @@ RSpec.describe 'Dashboard Projects' do visit dashboard_projects_path expect(page).to have_content(project.name) - expect(find('.nav-links li:nth-child(1) .badge-pill')).to have_content(1) + expect(find('.gl-tabs-nav li:nth-child(1) .badge-pill')).to have_content(1) end it 'shows personal projects on personal projects tab', :js do @@ -128,8 +128,8 @@ RSpec.describe 'Dashboard Projects' do expect(page).not_to have_content(project.name) expect(page).to have_content(project2.name) - expect(find('.nav-links li:nth-child(1) .badge-pill')).to have_content(1) - expect(find('.nav-links li:nth-child(2) .badge-pill')).to have_content(1) + expect(find('.gl-tabs-nav li:nth-child(1) .badge-pill')).to have_content(1) + expect(find('.gl-tabs-nav li:nth-child(2) .badge-pill')).to have_content(1) end it 'does not show tabs to filter by all projects or personal' do @@ -204,7 +204,7 @@ RSpec.describe 'Dashboard Projects' do visit dashboard_projects_path expect(page).to have_selector('[data-testid="project_topic_list"]') - expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1')) + expect(page).to have_link('topic1', href: topic_explore_projects_path(topic_name: 'topic1')) end end diff --git a/spec/features/explore/topics_spec.rb b/spec/features/explore/topics_spec.rb new file mode 100644 index 00000000000..9d2e76bc3a1 --- /dev/null +++ b/spec/features/explore/topics_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Explore Topics' do + context 'when no topics exist' do + it 'renders empty message', :aggregate_failures do + visit topics_explore_projects_path + + expect(current_path).to eq topics_explore_projects_path + expect(page).to have_content('There are no topics to show.') + end + end + + context 'when topics exist' do + let!(:topic) { create(:topic, name: 'topic1') } + + it 'renders topic list' do + visit topics_explore_projects_path + + expect(current_path).to eq topics_explore_projects_path + expect(page).to have_content('topic1') + end + end +end diff --git a/spec/features/graphql_known_operations_spec.rb b/spec/features/graphql_known_operations_spec.rb new file mode 100644 index 00000000000..ef406f12902 --- /dev/null +++ b/spec/features/graphql_known_operations_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# We need to distinguish between known and unknown GraphQL operations. This spec +# tests that we set up Gitlab::Graphql::KnownOperations.default which requires +# integration of FE queries, webpack plugin, and BE. +RSpec.describe 'Graphql known operations', :js do + around do |example| + # Let's make sure we aren't receiving or leaving behind any side-effects + # https://gitlab.com/gitlab-org/gitlab/-/jobs/1743294100 + ::Gitlab::Graphql::KnownOperations.instance_variable_set(:@default, nil) + ::Gitlab::Webpack::GraphqlKnownOperations.clear_memoization! + + example.run + + ::Gitlab::Graphql::KnownOperations.instance_variable_set(:@default, nil) + ::Gitlab::Webpack::GraphqlKnownOperations.clear_memoization! + end + + it 'collects known Graphql operations from the code', :aggregate_failures do + # Check that we include some arbitrary operation name we expect + known_operations = Gitlab::Graphql::KnownOperations.default.operations.map(&:name) + + expect(known_operations).to include("searchProjects") + expect(known_operations.length).to be > 20 + expect(known_operations).to all( match(%r{^[a-z]+}i) ) + end +end diff --git a/spec/features/groups/clusters/eks_spec.rb b/spec/features/groups/clusters/eks_spec.rb index c361c502cbb..fe62efbd3bf 100644 --- a/spec/features/groups/clusters/eks_spec.rb +++ b/spec/features/groups/clusters/eks_spec.rb @@ -19,7 +19,7 @@ RSpec.describe 'Group AWS EKS Cluster', :js do before do visit group_clusters_path(group) - click_link 'Integrate with a cluster certificate' + click_link 'Connect with a certificate' end context 'when user creates a cluster on AWS EKS' do diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb index 2a7ededa39b..1788167c94c 100644 --- a/spec/features/groups/clusters/user_spec.rb +++ b/spec/features/groups/clusters/user_spec.rb @@ -25,7 +25,7 @@ RSpec.describe 'User Cluster', :js do before do visit group_clusters_path(group) - click_link 'Integrate with a cluster certificate' + click_link 'Connect with a certificate' click_link 'Connect existing cluster' end @@ -129,7 +129,7 @@ RSpec.describe 'User Cluster', :js do it 'user sees creation form with the successful message' do expect(page).to have_content('Kubernetes cluster integration was successfully removed.') - expect(page).to have_link('Integrate with a cluster certificate') + expect(page).to have_link('Connect with a certificate') end end end diff --git a/spec/features/groups/dependency_proxy_spec.rb b/spec/features/groups/dependency_proxy_spec.rb index d6b0bdc8ea4..623fb065bfc 100644 --- a/spec/features/groups/dependency_proxy_spec.rb +++ b/spec/features/groups/dependency_proxy_spec.rb @@ -56,9 +56,14 @@ RSpec.describe 'Group Dependency Proxy' do visit settings_path wait_for_requests - click_button 'Enable Proxy' + proxy_toggle = find('[data-testid="dependency-proxy-setting-toggle"]') + proxy_toggle_button = proxy_toggle.find('button') - expect(page).to have_button 'Enable Proxy', class: '!is-checked' + expect(proxy_toggle).to have_css("button.is-checked") + + proxy_toggle_button.click + + expect(proxy_toggle).not_to have_css("button.is-checked") visit path diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 489beb70ab3..4e59ab40d04 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -83,6 +83,18 @@ RSpec.describe 'Group issues page' do end end + it 'truncates issue counts if over the threshold', :clean_gitlab_redis_cache do + allow(Rails.cache).to receive(:read).and_call_original + allow(Rails.cache).to receive(:read).with( + ['group', group.id, 'issues'], + { expires_in: Gitlab::IssuablesCountForState::CACHE_EXPIRES_IN } + ).and_return({ opened: 1050, closed: 500, all: 1550 }) + + visit issues_group_path(group) + + expect(page).to have_text('Open 1.1k Closed 500 All 1.6k') + end + context 'when project is archived' do before do ::Projects::UpdateService.new(project, user_in_group, archived: true).execute @@ -94,41 +106,6 @@ RSpec.describe 'Group issues page' do expect(page).not_to have_content issue.title[0..80] end end - - context 'when cached issues state count is enabled', :clean_gitlab_redis_cache do - before do - stub_feature_flags(cached_issues_state_count: true) - end - - it 'truncates issue counts if over the threshold' do - allow(Rails.cache).to receive(:read).and_call_original - allow(Rails.cache).to receive(:read).with( - ['group', group.id, 'issues'], - { expires_in: Gitlab::IssuablesCountForState::CACHE_EXPIRES_IN } - ).and_return({ opened: 1050, closed: 500, all: 1550 }) - - visit issues_group_path(group) - - expect(page).to have_text('Open 1.1k Closed 500 All 1.6k') - end - end - - context 'when cached issues state count is disabled', :clean_gitlab_redis_cache do - before do - stub_feature_flags(cached_issues_state_count: false) - end - - it 'does not truncate counts if they are over the threshold' do - allow_next_instance_of(IssuesFinder) do |finder| - allow(finder).to receive(:count_by_state).and_return(true) - .and_return({ opened: 1050, closed: 500, all: 1550 }) - end - - visit issues_group_path(group) - - expect(page).to have_text('Open 1,050 Closed 500 All 1,550') - end - end end context 'projects with issues disabled' do diff --git a/spec/features/groups/labels/subscription_spec.rb b/spec/features/groups/labels/subscription_spec.rb index dedded777ac..231c4b33bee 100644 --- a/spec/features/groups/labels/subscription_spec.rb +++ b/spec/features/groups/labels/subscription_spec.rb @@ -71,7 +71,7 @@ RSpec.describe 'Labels subscription' do end it 'does not show subscribed tab' do - page.within('.nav-tabs') do + page.within('.gl-tabs-nav') do expect(page).not_to have_link 'Subscribed' end end @@ -86,7 +86,7 @@ RSpec.describe 'Labels subscription' do end def click_subscribed_tab - page.within('.nav-tabs') do + page.within('.gl-tabs-nav') do click_link 'Subscribed' end end diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb index b73313745e9..e6bf1ffc2f7 100644 --- a/spec/features/groups/members/leave_group_spec.rb +++ b/spec/features/groups/members/leave_group_spec.rb @@ -10,6 +10,7 @@ RSpec.describe 'Groups > Members > Leave group' do let(:group) { create(:group) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb index 0a159056569..22409e9e7f6 100644 --- a/spec/features/groups/navbar_spec.rb +++ b/spec/features/groups/navbar_spec.rb @@ -15,6 +15,7 @@ RSpec.describe 'Group navbar' do insert_package_nav(_('Kubernetes')) stub_feature_flags(group_iterations: false) + stub_feature_flags(customer_relations: false) stub_config(dependency_proxy: { enabled: false }) stub_config(registry: { enabled: false }) stub_group_wikis(false) @@ -40,6 +41,22 @@ RSpec.describe 'Group navbar' do it_behaves_like 'verified navigation bar' end + context 'when customer_relations feature flag is enabled' do + before do + stub_feature_flags(customer_relations: true) + + if Gitlab.ee? + insert_customer_relations_nav(_('Analytics')) + else + insert_customer_relations_nav(_('Packages & Registries')) + end + + visit group_path(group) + end + + it_behaves_like 'verified navigation bar' + end + context 'when dependency proxy is available' do before do stub_config(dependency_proxy: { enabled: true }) diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb index 0dfc7180187..3c2ade6b274 100644 --- a/spec/features/groups/packages_spec.rb +++ b/spec/features/groups/packages_spec.rb @@ -28,10 +28,6 @@ RSpec.describe 'Group Packages' do context 'when feature is available', :js do before do - # we are simply setting the featrure flag to false because the new UI has nothing to test yet - # when the refactor is complete or almost complete we will turn on the feature tests - # see https://gitlab.com/gitlab-org/gitlab/-/issues/330846 for status of this work - stub_feature_flags(package_list_apollo: false) visit_group_packages end diff --git a/spec/features/groups/settings/manage_applications_spec.rb b/spec/features/groups/settings/manage_applications_spec.rb index 5f84f61678d..277471cb304 100644 --- a/spec/features/groups/settings/manage_applications_spec.rb +++ b/spec/features/groups/settings/manage_applications_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'User manages applications' do let_it_be(:group) { create(:group) } let_it_be(:user) { create(:user) } let_it_be(:new_application_path) { group_settings_applications_path(group) } + let_it_be(:index_path) { group_settings_applications_path(group) } before do group.add_owner(user) diff --git a/spec/features/incidents/user_creates_new_incident_spec.rb b/spec/features/incidents/user_creates_new_incident_spec.rb index 99a137b5852..685f6ab791a 100644 --- a/spec/features/incidents/user_creates_new_incident_spec.rb +++ b/spec/features/incidents/user_creates_new_incident_spec.rb @@ -4,52 +4,49 @@ require 'spec_helper' RSpec.describe 'Incident Management index', :js do let_it_be(:project) { create(:project) } - let_it_be(:developer) { create(:user) } + let_it_be(:reporter) { create(:user) } let_it_be(:guest) { create(:user) } let_it_be(:incident) { create(:incident, project: project) } before_all do - project.add_developer(developer) + project.add_reporter(reporter) project.add_guest(guest) end - shared_examples 'create incident form' do - it 'shows the create new issue button' do - expect(page).to have_selector('.create-incident-button') - end + before do + sign_in(user) - it 'when clicked shows the create issue page with the Incident type pre-selected' do - find('.create-incident-button').click - wait_for_all_requests + visit project_incidents_path(project) + wait_for_all_requests + end - expect(page).to have_selector('.dropdown-menu-toggle') - expect(page).to have_selector('.js-issuable-type-filter-dropdown-wrap') + describe 'incident list is visited' do + context 'by reporter' do + let(:user) { reporter } - page.within('.js-issuable-type-filter-dropdown-wrap') do - expect(page).to have_content('Incident') + it 'shows the create new incident button' do + expect(page).to have_selector('.create-incident-button') end - end - end - context 'when a developer displays the incident list' do - before do - sign_in(developer) + it 'when clicked shows the create issue page with the Incident type pre-selected' do + find('.create-incident-button').click + wait_for_all_requests - visit project_incidents_path(project) - wait_for_all_requests - end + expect(page).to have_selector('.dropdown-menu-toggle') + expect(page).to have_selector('.js-issuable-type-filter-dropdown-wrap') - it_behaves_like 'create incident form' + page.within('.js-issuable-type-filter-dropdown-wrap') do + expect(page).to have_content('Incident') + end + end + end end - context 'when a guest displays the incident list' do - before do - sign_in(guest) + context 'by guest' do + let(:user) { guest } - visit project_incidents_path(project) - wait_for_all_requests + it 'does not show new incident button' do + expect(page).not_to have_selector('.create-incident-button') end - - it_behaves_like 'create incident form' end end diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb index 244b66f7a9a..fe54f7708c9 100644 --- a/spec/features/incidents/user_views_incident_spec.rb +++ b/spec/features/incidents/user_views_incident_spec.rb @@ -22,12 +22,30 @@ RSpec.describe "User views incident" do it_behaves_like 'page meta description', ' Description header Lorem ipsum dolor sit amet' - it 'shows the merge request and incident actions', :js, :aggregate_failures do - click_button 'Incident actions' + describe 'user actions' do + it 'shows the merge request and incident actions', :js, :aggregate_failures do + click_button 'Incident actions' - expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident', description: "Related to \##{incident.iid}.\n\n" } })) - expect(page).to have_button('Create merge request') - expect(page).to have_button('Close incident') + expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident', description: "Related to \##{incident.iid}.\n\n" } })) + expect(page).to have_button('Create merge request') + expect(page).to have_button('Close incident') + end + + context 'when user is a guest' do + before do + project.add_guest(user) + + login_as(user) + + visit(project_issues_incident_path(project, incident)) + end + + it 'does not show the incident action', :js, :aggregate_failures do + click_button 'Incident actions' + + expect(page).not_to have_link('New incident') + end + end end context 'when the project is archived' do diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb index 87fb8955dcc..f9ab780d2d6 100644 --- a/spec/features/invites_spec.rb +++ b/spec/features/invites_spec.rb @@ -103,6 +103,20 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do expect(page).to have_content('You are already a member of this group.') end end + + context 'when email case doesnt match', :js do + let(:invite_email) { 'User@example.com' } + let(:user) { create(:user, email: 'user@example.com') } + + before do + sign_in(user) + visit invite_path(group_invite.raw_invite_token) + end + + it 'accepts invite' do + expect(page).to have_content('You have been granted Developer access to group Owned.') + end + end end context 'when declining the invitation from invitation reminder email' do diff --git a/spec/features/issuables/markdown_references/internal_references_spec.rb b/spec/features/issuables/markdown_references/internal_references_spec.rb index 07d4271eed7..2dcabb38b8f 100644 --- a/spec/features/issuables/markdown_references/internal_references_spec.rb +++ b/spec/features/issuables/markdown_references/internal_references_spec.rb @@ -53,9 +53,7 @@ RSpec.describe "Internal references", :js do end it "doesn't show any references", quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/257832' do - page.within(".issue-details") do - expect(page).not_to have_content("#merge-requests .merge-requests-title") - end + expect(page).not_to have_text 'Related merge requests' end end @@ -65,12 +63,9 @@ RSpec.describe "Internal references", :js do end it "shows references", :sidekiq_might_not_need_inline do - page.within("#merge-requests .merge-requests-title") do - expect(page).to have_content("Related merge requests") - expect(page).to have_css(".mr-count-badge") - end + expect(page).to have_text 'Related merge requests 1' - page.within("#merge-requests ul") do + page.within('.related-items-list') do expect(page).to have_content(private_project_merge_request.title) expect(page).to have_css(".ic-issue-open-m") end @@ -122,9 +117,7 @@ RSpec.describe "Internal references", :js do end it "doesn't show any references", quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/257832' do - page.within(".merge-request-details") do - expect(page).not_to have_content("#merge-requests .merge-requests-title") - end + expect(page).not_to have_text 'Related merge requests' end end diff --git a/spec/features/issue_rebalancing_spec.rb b/spec/features/issue_rebalancing_spec.rb new file mode 100644 index 00000000000..978768270ec --- /dev/null +++ b/spec/features/issue_rebalancing_spec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Issue rebalancing' do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:user) { create(:user) } + + let(:alert_message_regex) { /Issues are being rebalanced at the moment/ } + + before_all do + create(:issue, project: project) + + group.add_developer(user) + end + + context 'when issue rebalancing is in progress' do + before do + sign_in(user) + + stub_feature_flags(block_issue_repositioning: true) + end + + it 'shows an alert in project boards' do + board = create(:board, project: project) + + visit project_board_path(project, board) + + expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) + end + + it 'shows an alert in group boards' do + board = create(:board, group: group) + + visit group_board_path(group, board) + + expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) + end + + it 'shows an alert in project issues list with manual sort' do + visit project_issues_path(project, sort: 'relative_position') + + expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) + end + + it 'shows an alert in group issues list with manual sort' do + visit issues_group_path(group, sort: 'relative_position') + + expect(page).to have_selector('.gl-alert-info', text: alert_message_regex, count: 1) + end + + it 'does not show an alert in project issues list with other sorts' do + visit project_issues_path(project, sort: 'created_date') + + expect(page).not_to have_selector('.gl-alert-info', text: alert_message_regex) + end + + it 'does not show an alert in group issues list with other sorts' do + visit issues_group_path(group, sort: 'created_date') + + expect(page).not_to have_selector('.gl-alert-info', text: alert_message_regex) + end + end +end diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 4bad67acc87..b26f65316c5 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -4,25 +4,29 @@ require 'spec_helper' RSpec.describe 'New/edit issue', :js do include ActionView::Helpers::JavaScriptHelper - include FormHelper let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user)} - let_it_be(:user2) { create(:user)} + let_it_be(:user) { create(:user) } + let_it_be(:user2) { create(:user) } let_it_be(:milestone) { create(:milestone, project: project) } let_it_be(:label) { create(:label, project: project) } let_it_be(:label2) { create(:label, project: project) } let_it_be(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) } - before do - stub_licensed_features(multiple_issue_assignees: false, issue_weights: false) + let(:current_user) { user } + before_all do project.add_maintainer(user) project.add_maintainer(user2) - sign_in(user) end - context 'new issue' do + before do + stub_licensed_features(multiple_issue_assignees: false, issue_weights: false) + + sign_in(current_user) + end + + describe 'new issue' do before do visit new_project_issue_path(project) end @@ -235,29 +239,61 @@ RSpec.describe 'New/edit issue', :js do end describe 'displays issue type options in the dropdown' do + shared_examples 'type option is visible' do |label:, identifier:| + it "shows #{identifier} option", :aggregate_failures do + page.within('[data-testid="issue-type-select-dropdown"]') do + expect(page).to have_selector(%([data-testid="issue-type-#{identifier}-icon"])) + expect(page).to have_content(label) + end + end + end + + shared_examples 'type option is missing' do |label:, identifier:| + it "does not show #{identifier} option", :aggregate_failures do + page.within('[data-testid="issue-type-select-dropdown"]') do + expect(page).not_to have_selector(%([data-testid="issue-type-#{identifier}-icon"])) + expect(page).not_to have_content(label) + end + end + end + before do page.within('.issue-form') do click_button 'Issue' end end - it 'correctly displays the Issue type option with an icon', :aggregate_failures do - page.within('[data-testid="issue-type-select-dropdown"]') do - expect(page).to have_selector('[data-testid="issue-type-issue-icon"]') - expect(page).to have_content('Issue') + context 'when user is guest' do + let_it_be(:guest) { create(:user) } + + let(:current_user) { guest } + + before_all do + project.add_guest(guest) end + + it_behaves_like 'type option is visible', label: 'Issue', identifier: :issue + it_behaves_like 'type option is missing', label: 'Incident', identifier: :incident end - it 'correctly displays the Incident type option with an icon', :aggregate_failures do - page.within('[data-testid="issue-type-select-dropdown"]') do - expect(page).to have_selector('[data-testid="issue-type-incident-icon"]') - expect(page).to have_content('Incident') + context 'when user is reporter' do + let_it_be(:reporter) { create(:user) } + + let(:current_user) { reporter } + + before_all do + project.add_reporter(reporter) end + + it_behaves_like 'type option is visible', label: 'Issue', identifier: :issue + it_behaves_like 'type option is visible', label: 'Incident', identifier: :incident end end describe 'milestone' do - let!(:milestone) { create(:milestone, title: '"><img src=x onerror=alert(document.domain)>', project: project) } + let!(:milestone) do + create(:milestone, title: '"><img src=x onerror=alert(document.domain)>', project: project) + end it 'escapes milestone' do click_button 'Milestone' @@ -274,7 +310,7 @@ RSpec.describe 'New/edit issue', :js do end end - context 'edit issue' do + describe 'edit issue' do before do visit edit_project_issue_path(project, issue) end @@ -329,7 +365,7 @@ RSpec.describe 'New/edit issue', :js do end end - context 'inline edit' do + describe 'inline edit' do before do visit project_issue_path(project, issue) end diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb index 531c3634b5e..b37c8e9d1cf 100644 --- a/spec/features/issues/issue_detail_spec.rb +++ b/spec/features/issues/issue_detail_spec.rb @@ -3,8 +3,9 @@ require 'spec_helper' RSpec.describe 'Issue Detail', :js do + let_it_be_with_refind(:project) { create(:project, :public) } + let(:user) { create(:user) } - let(:project) { create(:project, :public) } let(:issue) { create(:issue, project: project, author: user) } let(:incident) { create(:incident, project: project, author: user) } @@ -90,7 +91,13 @@ RSpec.describe 'Issue Detail', :js do end describe 'user updates `issue_type` via the issue type dropdown' do - context 'when an issue `issue_type` is edited by a signed in user' do + let_it_be(:reporter) { create(:user) } + + before_all do + project.add_reporter(reporter) + end + + describe 'when an issue `issue_type` is edited' do before do sign_in(user) @@ -98,18 +105,33 @@ RSpec.describe 'Issue Detail', :js do wait_for_requests end - it 'routes the user to the incident details page when the `issue_type` is set to incident' do - open_issue_edit_form + context 'by non-member author' do + it 'cannot see Incident option' do + open_issue_edit_form + + page.within('[data-testid="issuable-form"]') do + expect(page).to have_content('Issue') + expect(page).not_to have_content('Incident') + end + end + end + + context 'by reporter' do + let(:user) { reporter } - page.within('[data-testid="issuable-form"]') do - update_type_select('Issue', 'Incident') + it 'routes the user to the incident details page when the `issue_type` is set to incident' do + open_issue_edit_form - expect(page).to have_current_path(project_issues_incident_path(project, issue)) + page.within('[data-testid="issuable-form"]') do + update_type_select('Issue', 'Incident') + + expect(page).to have_current_path(project_issues_incident_path(project, issue)) + end end end end - context 'when an incident `issue_type` is edited by a signed in user' do + describe 'when an incident `issue_type` is edited' do before do sign_in(user) @@ -117,13 +139,29 @@ RSpec.describe 'Issue Detail', :js do wait_for_requests end - it 'routes the user to the issue details page when the `issue_type` is set to issue' do - open_issue_edit_form + context 'by non-member author' do + it 'routes the user to the issue details page when the `issue_type` is set to issue' do + open_issue_edit_form + + page.within('[data-testid="issuable-form"]') do + update_type_select('Incident', 'Issue') + + expect(page).to have_current_path(project_issue_path(project, incident)) + end + end + end + + context 'by reporter' do + let(:user) { reporter } + + it 'routes the user to the issue details page when the `issue_type` is set to issue' do + open_issue_edit_form - page.within('[data-testid="issuable-form"]') do - update_type_select('Incident', 'Issue') + page.within('[data-testid="issuable-form"]') do + update_type_select('Incident', 'Issue') - expect(page).to have_current_path(project_issue_path(project, incident)) + expect(page).to have_current_path(project_issue_path(project, incident)) + end end end end diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index f46aa5c21b6..37e324e6ded 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -171,7 +171,7 @@ RSpec.describe "User creates issue" do end context 'form create handles issue creation by default' do - let(:project) { create(:project) } + let_it_be(:project) { create(:project) } before do visit new_project_issue_path(project) @@ -187,30 +187,22 @@ RSpec.describe "User creates issue" do end context 'form create handles incident creation' do - let(:project) { create(:project) } + let_it_be(:project) { create(:project) } before do visit new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }) end - it 'pre-fills the issue type dropdown with incident type' do - expect(find('.js-issuable-type-filter-dropdown-wrap .dropdown-toggle-text')).to have_content('Incident') - end - - it 'hides the epic select' do - expect(page).not_to have_selector('.epic-dropdown-container') + it 'does not pre-fill the issue type dropdown with incident type' do + expect(find('.js-issuable-type-filter-dropdown-wrap .dropdown-toggle-text')).not_to have_content('Incident') end it 'shows the milestone select' do expect(page).to have_selector('.qa-issuable-milestone-dropdown') # rubocop:disable QA/SelectorUsage end - it 'hides the weight input' do - expect(page).not_to have_selector('.qa-issuable-weight-input') # rubocop:disable QA/SelectorUsage - end - - it 'shows the incident help text' do - expect(page).to have_text('A modified issue to guide the resolution of incidents.') + it 'hides the incident help text' do + expect(page).not_to have_text('A modified issue to guide the resolution of incidents.') end end @@ -242,6 +234,44 @@ RSpec.describe "User creates issue" do end end + context 'when signed in as reporter', :js do + let_it_be(:project) { create(:project) } + + before_all do + project.add_reporter(user) + end + + before do + sign_in(user) + end + + context 'form create handles incident creation' do + before do + visit new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' } }) + end + + it 'pre-fills the issue type dropdown with incident type' do + expect(find('.js-issuable-type-filter-dropdown-wrap .dropdown-toggle-text')).to have_content('Incident') + end + + it 'hides the epic select' do + expect(page).not_to have_selector('.epic-dropdown-container') + end + + it 'shows the milestone select' do + expect(page).to have_selector('.qa-issuable-milestone-dropdown') # rubocop:disable QA/SelectorUsage + end + + it 'hides the weight input' do + expect(page).not_to have_selector('.qa-issuable-weight-input') # rubocop:disable QA/SelectorUsage + end + + it 'shows the incident help text' do + expect(page).to have_text('A modified issue to guide the resolution of incidents.') + end + end + end + context "when signed in as user with special characters in their name" do let(:user_special) { create(:user, name: "Jon O'Shea") } diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb index 63c36a20adc..76cec2502e3 100644 --- a/spec/features/issues/user_edits_issue_spec.rb +++ b/spec/features/issues/user_edits_issue_spec.rb @@ -146,8 +146,7 @@ RSpec.describe "Issues > User edits issue", :js do fill_in 'Comment', with: '/label ~syzygy' click_button 'Comment' - - wait_for_requests + expect(page).to have_text('added syzygy label just now') page.within '.block.labels' do # Remove `verisimilitude` label @@ -155,8 +154,6 @@ RSpec.describe "Issues > User edits issue", :js do click_button end - wait_for_requests - expect(page).to have_text('syzygy') expect(page).not_to have_text('verisimilitude') end diff --git a/spec/features/issues/user_toggles_subscription_spec.rb b/spec/features/issues/user_toggles_subscription_spec.rb index 9809bb34d26..541bbc8a8e7 100644 --- a/spec/features/issues/user_toggles_subscription_spec.rb +++ b/spec/features/issues/user_toggles_subscription_spec.rb @@ -45,7 +45,7 @@ RSpec.describe "User toggles subscription", :js do it 'is disabled' do expect(page).to have_content('Disabled by project owner') - expect(page).to have_button('Notifications', class: 'is-disabled') + expect(page).to have_selector('[data-testid="subscription-toggle"]', class: 'is-disabled') end end end diff --git a/spec/features/issues/user_uses_quick_actions_spec.rb b/spec/features/issues/user_uses_quick_actions_spec.rb index d88b816b186..c6d743ed38f 100644 --- a/spec/features/issues/user_uses_quick_actions_spec.rb +++ b/spec/features/issues/user_uses_quick_actions_spec.rb @@ -44,5 +44,6 @@ RSpec.describe 'Issues > User uses quick actions', :js do it_behaves_like 'move quick action' it_behaves_like 'zoom quick actions' it_behaves_like 'clone quick action' + it_behaves_like 'promote_to_incident quick action' end end diff --git a/spec/features/jira_connect/subscriptions_spec.rb b/spec/features/jira_connect/subscriptions_spec.rb index 9be6b7c67ee..e1589ba997e 100644 --- a/spec/features/jira_connect/subscriptions_spec.rb +++ b/spec/features/jira_connect/subscriptions_spec.rb @@ -40,8 +40,8 @@ RSpec.describe 'Subscriptions Content Security Policy' do visit jira_connect_subscriptions_path(jwt: jwt) is_expected.to include("frame-ancestors 'self' https://*.atlassian.net") - is_expected.to include("script-src 'self' https://some-cdn.test https://connect-cdn.atl-paas.net https://unpkg.com/jquery@3.3.1/") - is_expected.to include("style-src 'self' https://some-cdn.test 'unsafe-inline' https://unpkg.com/@atlaskit/") + is_expected.to include("script-src 'self' https://some-cdn.test https://connect-cdn.atl-paas.net") + is_expected.to include("style-src 'self' https://some-cdn.test 'unsafe-inline'") end end end diff --git a/spec/features/merge_request/user_approves_spec.rb b/spec/features/merge_request/user_approves_spec.rb index f401dd598f3..4f7bcb58551 100644 --- a/spec/features/merge_request/user_approves_spec.rb +++ b/spec/features/merge_request/user_approves_spec.rb @@ -17,7 +17,7 @@ RSpec.describe 'Merge request > User approves', :js do it 'approves merge request' do click_approval_button('Approve') - expect(page).to have_content('Merge request approved') + expect(page).to have_content('Approved by you') verify_approvals_count_on_index! diff --git a/spec/features/merge_request/user_assigns_themselves_spec.rb b/spec/features/merge_request/user_assigns_themselves_spec.rb index 04d401683bf..fc925781a3b 100644 --- a/spec/features/merge_request/user_assigns_themselves_spec.rb +++ b/spec/features/merge_request/user_assigns_themselves_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'Merge request > User assigns themselves' do visit project_merge_request_path(project, merge_request) end - it 'updates related issues', :js do + it 'updates related issues', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/343006' do click_link 'Assign yourself to these issues' expect(page).to have_content '2 issues have been assigned to you' diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb index 54c3fe738d2..f9b554c5ed2 100644 --- a/spec/features/merge_request/user_comments_on_diff_spec.rb +++ b/spec/features/merge_request/user_comments_on_diff_spec.rb @@ -14,6 +14,7 @@ RSpec.describe 'User comments on a diff', :js do let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb b/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb index 1d3d76d3486..06795344c5c 100644 --- a/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb +++ b/spec/features/merge_request/user_customizes_merge_commit_message_spec.rb @@ -26,33 +26,27 @@ RSpec.describe 'Merge request < User customizes merge commit message', :js do ].join("\n\n") end - let(:message_with_description) do - [ - "Merge branch 'feature' into 'master'", - merge_request.title, - merge_request.description, - "See merge request #{merge_request.to_reference(full: true)}" - ].join("\n\n") - end - before do project.add_maintainer(user) sign_in(user) visit project_merge_request_path(project, merge_request) end - it 'toggles commit message between message with description and without description' do + it 'has commit message without description' do expect(page).not_to have_selector('#merge-message-edit') first('.js-mr-widget-commits-count').click expect(textbox).to be_visible expect(textbox.value).to eq(default_message) + end - check('Include merge request description') - - expect(textbox.value).to eq(message_with_description) - - uncheck('Include merge request description') + context 'when target project has merge commit template set' do + let(:project) { create(:project, :public, :repository, merge_commit_template: '%{title}') } - expect(textbox.value).to eq(default_message) + it 'uses merge commit template' do + expect(page).not_to have_selector('#merge-message-edit') + first('.js-mr-widget-commits-count').click + expect(textbox).to be_visible + expect(textbox.value).to eq(merge_request.title) + end end end diff --git a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb index af5ba14e310..9057b96bff0 100644 --- a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb @@ -36,7 +36,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do click_button "Merge when pipeline succeeds" expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds" - expect(page).to have_content "The source branch will not be deleted" + expect(page).to have_content "Does not delete the source branch" expect(page).to have_selector ".js-cancel-auto-merge" visit project_merge_request_path(project, merge_request) # Needed to refresh the page expect(page).to have_content /enabled an automatic merge when the pipeline for \h{8} succeeds/i @@ -126,7 +126,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do it 'allows to delete source branch' do click_button "Delete source branch" - expect(page).to have_content "The source branch will be deleted" + expect(page).to have_content "Deletes the source branch" end context 'when pipeline succeeds' do diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb index c339a7d9976..79e46e69157 100644 --- a/spec/features/merge_request/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb @@ -18,6 +18,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do project.add_developer(user) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when hovering over a parallel view diff file' do @@ -237,8 +238,10 @@ RSpec.describe 'Merge request > User posts diff notes', :js do def should_allow_dismissing_a_comment(line_holder, diff_side = nil) write_comment_on_line(line_holder, diff_side) - accept_confirm do - find('.js-close-discussion-note-form').click + find('.js-close-discussion-note-form').click + + page.within('.modal') do + click_button 'OK' end assert_comment_dismissal(line_holder) diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb index 83d9388914b..0416474218f 100644 --- a/spec/features/merge_request/user_posts_notes_spec.rb +++ b/spec/features/merge_request/user_posts_notes_spec.rb @@ -18,8 +18,10 @@ RSpec.describe 'Merge request > User posts notes', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) + visit project_merge_request_path(project, merge_request) end diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb index 90cdc28d1bd..64cd5aa2bb1 100644 --- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb +++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb @@ -79,6 +79,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do %w(parallel).each do |view| context "#{view} view" do before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit diffs_project_merge_request_path(project, merge_request, view: view) wait_for_requests diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb index 873cc0a89c6..345404cc28f 100644 --- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb +++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb @@ -110,6 +110,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } before do + stub_feature_flags(bootstrap_confirmation_modals: false) build.success! deployment.update!(on_stop: manual.name) visit project_merge_request_path(project, merge_request) 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 f74b097ab3e..0117cf01e53 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -426,7 +426,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do it 'user cannot remove source branch', :sidekiq_might_not_need_inline do expect(page).not_to have_field('remove-source-branch-input') - expect(page).to have_content('The source branch will be deleted') + expect(page).to have_content('Deletes the source branch') end end diff --git a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb index 3893a9cdf28..2191849edd9 100644 --- a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb +++ b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb @@ -16,7 +16,8 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do end it 'shows the suggest pipeline widget and then allows dismissal correctly' do - expect(page).to have_content('Are you adding technical debt or code vulnerabilities?') + content = 'GitLab CI/CD can automatically build, test, and deploy your application' + expect(page).to have_content(content) page.within '.mr-pipeline-suggest' do find('[data-testid="close"]').click @@ -24,17 +25,16 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do wait_for_requests - expect(page).not_to have_content('Are you adding technical debt or code vulnerabilities?') + expect(page).not_to have_content(content) # Reload so we know the user callout was registered visit page.current_url - expect(page).not_to have_content('Are you adding technical debt or code vulnerabilities?') + expect(page).not_to have_content(content) end - it 'runs tour from start to finish ensuring all nudges are executed' do - # nudge 1 - expect(page).to have_content('Are you adding technical debt or code vulnerabilities?') + it 'takes the user to the pipeline editor with a pre-filled CI config file form' do + expect(page).to have_content('GitLab CI/CD can automatically build, test, and deploy your application') page.within '.mr-pipeline-suggest' do find('[data-testid="ok"]').click @@ -42,30 +42,14 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do wait_for_requests - # nudge 2 - expect(page).to have_content('Choose Code Quality to add a pipeline that tests the quality of your code.') + # Drawer is open + expect(page).to have_content('This template creates a simple test pipeline. To use it:') - find('.js-gitlab-ci-yml-selector').click + # Editor shows template + expect(page).to have_content('This file is a template, and might need editing before it works on your project.') - wait_for_requests - - within '.gitlab-ci-yml-selector' do - find('.dropdown-input-field').set('Jekyll') - find('.dropdown-content li', text: 'Jekyll').click - end - - wait_for_requests - - expect(page).not_to have_content('Choose Code Quality to add a pipeline that tests the quality of your code.') - # nudge 3 - expect(page).to have_content('The template is ready!') - - find('#commit-changes').click - - wait_for_requests - - # nudge 4 - expect(page).to have_content("That's it, well done!") + # Commit form is shown + expect(page).to have_button('Commit changes') end context 'when feature setting is disabled' do diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb index 3402bda5a41..0ea14bc00a5 100644 --- a/spec/features/oauth_login_spec.rb +++ b/spec/features/oauth_login_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do end providers = [:github, :twitter, :bitbucket, :gitlab, :google_oauth2, - :facebook, :cas3, :auth0, :authentiq, :salesforce] + :facebook, :cas3, :auth0, :authentiq, :salesforce, :dingtalk] around do |example| with_omniauth_full_host { example.run } diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 9a261c6d9c8..7d935298f38 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'Profile account page', :js do let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end @@ -80,6 +81,7 @@ RSpec.describe 'Profile account page', :js do 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) visit profile_personal_access_tokens_path end diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb index fd64704b7c8..a515c7b1c1f 100644 --- a/spec/features/profiles/active_sessions_spec.rb +++ b/spec/features/profiles/active_sessions_spec.rb @@ -11,6 +11,10 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do let(:admin) { create(:admin) } + before do + stub_feature_flags(bootstrap_confirmation_modals: false) + end + it 'user sees their active sessions' do travel_to(Time.zone.parse('2018-03-12 09:06')) do Capybara::Session.new(:session1) diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb index 6b6f628e2d5..8f05de60be9 100644 --- a/spec/features/profiles/emails_spec.rb +++ b/spec/features/profiles/emails_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Profile > Emails' do let(:user) { create(:user) } + let(:other_user) { create(:user) } before do sign_in(user) @@ -23,15 +24,25 @@ RSpec.describe 'Profile > Emails' do expect(page).to have_content('Resend confirmation email') end - it 'does not add a duplicate email' do - fill_in('Email', with: user.email) + it 'does not add an email that is the primary email of another user' do + fill_in('Email', with: other_user.email) click_button('Add email address') - email = user.emails.find_by(email: user.email) + email = user.emails.find_by(email: other_user.email) expect(email).to be_nil expect(page).to have_content('Email has already been taken') end + it 'adds an email that is the primary email of the same user' do + fill_in('Email', with: user.email) + click_button('Add email address') + + email = user.emails.find_by(email: user.email) + expect(email).to be_present + expect(page).to have_content("#{user.email} Verified") + expect(page).not_to have_content("#{user.email} Unverified") + end + it 'does not add an invalid email' do fill_in('Email', with: 'test.@example.com') click_button('Add email address') diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb index 2735f601307..6827dff5434 100644 --- a/spec/features/profiles/oauth_applications_spec.rb +++ b/spec/features/profiles/oauth_applications_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'Profile > Applications' do let(:application) { create(:oauth_application, owner: user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 8f44299b18f..74505633cae 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -34,6 +34,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/profiles/two_factor_auths_spec.rb b/spec/features/profiles/two_factor_auths_spec.rb index 3f5789e119a..a9256a73d7b 100644 --- a/spec/features/profiles/two_factor_auths_spec.rb +++ b/spec/features/profiles/two_factor_auths_spec.rb @@ -45,6 +45,19 @@ RSpec.describe 'Two factor auths' do expect(page).to have_content('Status: Enabled') end end + + context 'when invalid pin is provided' do + let_it_be(:user) { create(:omniauth_user) } + + it 'renders a error alert with a link to the troubleshooting section' do + visit profile_two_factor_auth_path + + fill_in 'pin_code', with: '123' + click_button 'Register with two-factor app' + + expect(page).to have_link('Try the troubleshooting steps here.', href: help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'troubleshooting')) + end + end end context 'when user has two-factor authentication enabled' do @@ -57,7 +70,9 @@ RSpec.describe 'Two factor auths' do click_button 'Disable two-factor authentication' - page.accept_alert + page.within('[role="dialog"]') do + click_button 'Disable' + end expect(page).to have_content('You must provide a valid current password') @@ -65,7 +80,9 @@ RSpec.describe 'Two factor auths' do click_button 'Disable two-factor authentication' - page.accept_alert + page.within('[role="dialog"]') do + click_button 'Disable' + end expect(page).to have_content('Two-factor authentication has been disabled successfully!') expect(page).to have_content('Enable two-factor authentication') @@ -95,7 +112,9 @@ RSpec.describe 'Two factor auths' do click_button 'Disable two-factor authentication' - page.accept_alert + page.within('[role="dialog"]') do + click_button 'Disable' + end expect(page).to have_content('Two-factor authentication has been disabled successfully!') expect(page).to have_content('Enable two-factor authentication') diff --git a/spec/features/profiles/user_manages_applications_spec.rb b/spec/features/profiles/user_manages_applications_spec.rb index c76ef2613fd..ea7a6b4b6ba 100644 --- a/spec/features/profiles/user_manages_applications_spec.rb +++ b/spec/features/profiles/user_manages_applications_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'User manages applications' do let_it_be(:user) { create(:user) } let_it_be(:new_application_path) { applications_profile_path } + let_it_be(:index_path) { oauth_applications_path } before do sign_in(user) diff --git a/spec/features/profiles/user_manages_emails_spec.rb b/spec/features/profiles/user_manages_emails_spec.rb index 373c4f565f2..b037d5048aa 100644 --- a/spec/features/profiles/user_manages_emails_spec.rb +++ b/spec/features/profiles/user_manages_emails_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'User manages emails' do let(:user) { create(:user) } + let(:other_user) { create(:user) } before do sign_in(user) @@ -11,7 +12,7 @@ RSpec.describe 'User manages emails' do visit(profile_emails_path) end - it "shows user's emails" do + it "shows user's emails", :aggregate_failures do expect(page).to have_content(user.email) user.emails.each do |email| @@ -19,7 +20,7 @@ RSpec.describe 'User manages emails' do end end - it 'adds an email' do + it 'adds an email', :aggregate_failures do fill_in('email_email', with: 'my@email.com') click_button('Add') @@ -34,21 +35,21 @@ RSpec.describe 'User manages emails' do end end - it 'does not add a duplicate email' do - fill_in('email_email', with: user.email) + it 'does not add an email that is the primary email of another user', :aggregate_failures do + fill_in('email_email', with: other_user.email) click_button('Add') - email = user.emails.find_by(email: user.email) + email = user.emails.find_by(email: other_user.email) expect(email).to be_nil - expect(page).to have_content(user.email) + expect(page).to have_content('Email has already been taken') user.emails.each do |email| expect(page).to have_content(email.email) end end - it 'removes an email' do + it 'removes an email', :aggregate_failures do fill_in('email_email', with: 'my@email.com') click_button('Add') diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb index 475fda5e7a1..273d52996d3 100644 --- a/spec/features/profiles/user_visits_profile_spec.rb +++ b/spec/features/profiles/user_visits_profile_spec.rb @@ -21,6 +21,14 @@ RSpec.describe 'User visits their profile' do expect(page).to have_content "This information will appear on your profile" end + it 'shows user readme' do + create(:project, :repository, :public, path: user.username, namespace: user.namespace) + + visit(user_path(user)) + + expect(find('.file-content')).to have_content('testme') + end + context 'when user has groups' do let(:group) do create :group do |group| diff --git a/spec/features/project_variables_spec.rb b/spec/features/project_variables_spec.rb index 5139c724d82..cc59fea173b 100644 --- a/spec/features/project_variables_spec.rb +++ b/spec/features/project_variables_spec.rb @@ -21,7 +21,7 @@ RSpec.describe 'Project variables', :js do click_button('Add variable') page.within('#add-ci-variable') do - find('[data-qa-selector="ci_variable_key_field"] input').set('akey') # rubocop:disable QA/SelectorUsage + fill_in 'Key', with: 'akey' find('#ci-variable-value').set('akey_value') find('[data-testid="environment-scope"]').click find('[data-testid="ci-environment-search"]').set('review/*') diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb index 3b8f49accc5..8fc5c3d2e1b 100644 --- a/spec/features/projects/branches/user_deletes_branch_spec.rb +++ b/spec/features/projects/branches/user_deletes_branch_spec.rb @@ -35,6 +35,7 @@ RSpec.describe "User deletes branch", :js do 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 diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 0a79719f14a..2725c6a91be 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -179,6 +179,7 @@ RSpec.describe 'Branches' do 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') diff --git a/spec/features/projects/cluster_agents_spec.rb b/spec/features/projects/cluster_agents_spec.rb new file mode 100644 index 00000000000..3ef710169f0 --- /dev/null +++ b/spec/features/projects/cluster_agents_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'ClusterAgents', :js do + let_it_be(:token) { create(:cluster_agent_token, description: 'feature test token')} + + let(:agent) { token.agent } + let(:project) { agent.project } + let(:user) { project.creator } + + before do + gitlab_sign_in(user) + end + + context 'when user does not have any agents and visits the index page' do + let(:empty_project) { create(:project) } + + before do + empty_project.add_maintainer(user) + visit project_clusters_path(empty_project) + end + + it 'displays empty state', :aggregate_failures do + expect(page).to have_content('Install new Agent') + expect(page).to have_selector('.empty-state') + end + end + + context 'when user has an agent' do + context 'when visiting the index page' do + before do + visit project_clusters_path(project) + end + + it 'displays a table with agent', :aggregate_failures do + expect(page).to have_content(agent.name) + expect(page).to have_selector('[data-testid="cluster-agent-list-table"] tbody tr', count: 1) + end + end + + context 'when visiting the show page' do + before do + visit project_cluster_agent_path(project, agent.name) + end + + it 'displays agent and token information', :aggregate_failures do + expect(page).to have_content(agent.name) + expect(page).to have_content(token.description) + end + end + end +end diff --git a/spec/features/projects/clusters/eks_spec.rb b/spec/features/projects/clusters/eks_spec.rb index 9f3f331cfab..09c10c0b3a9 100644 --- a/spec/features/projects/clusters/eks_spec.rb +++ b/spec/features/projects/clusters/eks_spec.rb @@ -19,7 +19,8 @@ RSpec.describe 'AWS EKS Cluster', :js do before do visit project_clusters_path(project) - click_link 'Integrate with a cluster certificate' + click_link 'Certificate based' + click_link 'Connect with a certificate' end context 'when user creates a cluster on AWS EKS' do diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index 21e587288f5..e1659cd2fbf 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -33,7 +33,8 @@ RSpec.describe 'Gcp Cluster', :js do before do visit project_clusters_path(project) - click_link 'Integrate with a cluster certificate' + click_link 'Certificate based' + click_link 'Connect with a certificate' click_link 'Create new cluster' click_link 'Google GKE' end @@ -143,8 +144,9 @@ RSpec.describe 'Gcp Cluster', :js do before do visit project_clusters_path(project) - click_link 'Connect cluster with certificate' - click_link 'Connect existing cluster' + click_link 'Certificate based' + click_button(class: 'dropdown-toggle-split') + click_link 'Connect with certificate' end it 'user sees the "Environment scope" field' do @@ -158,11 +160,12 @@ RSpec.describe 'Gcp Cluster', :js do click_button 'Remove integration and resources' fill_in 'confirm_cluster_name_input', with: cluster.name click_button 'Remove integration' + click_link 'Certificate based' end it 'user sees creation form with the successful message' do expect(page).to have_content('Kubernetes cluster integration was successfully removed.') - expect(page).to have_link('Integrate with a cluster certificate') + expect(page).to have_link('Connect with a certificate') end end end @@ -171,6 +174,7 @@ RSpec.describe 'Gcp Cluster', :js do context 'when user has not dismissed GCP signup offer' do before do visit project_clusters_path(project) + click_link 'Certificate based' end it 'user sees offer on cluster index page' do @@ -178,7 +182,7 @@ RSpec.describe 'Gcp Cluster', :js do end it 'user sees offer on cluster create page' do - click_link 'Integrate with a cluster certificate' + click_link 'Connect with a certificate' expect(page).to have_css('.gcp-signup-offer') end @@ -187,6 +191,7 @@ RSpec.describe 'Gcp Cluster', :js do context 'when user has dismissed GCP signup offer' do before do visit project_clusters_path(project) + click_link 'Certificate based' end it 'user does not see offer after dismissing' do @@ -195,19 +200,18 @@ RSpec.describe 'Gcp Cluster', :js do find('.gcp-signup-offer .js-close').click wait_for_requests - click_link 'Integrate with a cluster certificate' + click_link 'Connect with a certificate' expect(page).not_to have_css('.gcp-signup-offer') end end context 'when third party offers are disabled', :clean_gitlab_redis_shared_state do - let(:admin) { create(:admin) } + let(:user) { create(:admin) } before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') - sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + gitlab_enable_admin_mode_sign_in(user) visit general_admin_application_settings_path end diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index 5b60edbcf87..d3f709bfb53 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -25,7 +25,8 @@ RSpec.describe 'User Cluster', :js do before do visit project_clusters_path(project) - click_link 'Integrate with a cluster certificate' + click_link 'Certificate based' + click_link 'Connect with a certificate' click_link 'Connect existing cluster' end @@ -112,11 +113,12 @@ RSpec.describe 'User Cluster', :js do click_button 'Remove integration and resources' fill_in 'confirm_cluster_name_input', with: cluster.name click_button 'Remove integration' + click_link 'Certificate based' end it 'user sees creation form with the successful message' do expect(page).to have_content('Kubernetes cluster integration was successfully removed.') - expect(page).to have_link('Integrate with a cluster certificate') + expect(page).to have_link('Connect with a certificate') end end end diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb index 6b03301aa74..a49fa4c9e31 100644 --- a/spec/features/projects/clusters_spec.rb +++ b/spec/features/projects/clusters_spec.rb @@ -16,10 +16,11 @@ RSpec.describe 'Clusters', :js do context 'when user does not have a cluster and visits cluster index page' do before do visit project_clusters_path(project) + click_link 'Certificate based' end it 'sees empty state' do - expect(page).to have_link('Integrate with a cluster certificate') + expect(page).to have_link('Connect with a certificate') expect(page).to have_selector('.empty-state') end end @@ -33,16 +34,17 @@ RSpec.describe 'Clusters', :js do before do create(:cluster, :provided_by_user, name: 'default-cluster', environment_scope: '*', projects: [project]) visit project_clusters_path(project) + click_link 'Certificate based' + click_button(class: 'dropdown-toggle-split') end it 'user sees an add cluster button' do - expect(page).to have_selector('.js-add-cluster:not(.readonly)') + expect(page).to have_content('Connect with certificate') end context 'when user filled form with environment scope' do before do - click_link 'Connect cluster with certificate' - click_link 'Connect existing cluster' + click_link 'Connect with certificate' fill_in 'cluster_name', with: 'staging-cluster' fill_in 'cluster_environment_scope', with: 'staging/*' click_button 'Add Kubernetes cluster' @@ -70,8 +72,7 @@ RSpec.describe 'Clusters', :js do context 'when user updates duplicated environment scope' do before do - click_link 'Connect cluster with certificate' - click_link 'Connect existing cluster' + click_link 'Connect with certificate' fill_in 'cluster_name', with: 'staging-cluster' fill_in 'cluster_environment_scope', with: '*' fill_in 'cluster_platform_kubernetes_attributes_api_url', with: 'https://0.0.0.0' @@ -108,15 +109,12 @@ RSpec.describe 'Clusters', :js do create(:cluster, :provided_by_gcp, name: 'default-cluster', environment_scope: '*', projects: [project]) visit project_clusters_path(project) - end - - it 'user sees a add cluster button' do - expect(page).to have_selector('.js-add-cluster:not(.readonly)') + click_link 'Certificate based' end context 'when user filled form with environment scope' do before do - click_link 'Connect cluster with certificate' + click_button(class: 'dropdown-toggle-split') click_link 'Create new cluster' click_link 'Google GKE' @@ -161,7 +159,7 @@ RSpec.describe 'Clusters', :js do context 'when user updates duplicated environment scope' do before do - click_link 'Connect cluster with certificate' + click_button(class: 'dropdown-toggle-split') click_link 'Create new cluster' click_link 'Google GKE' @@ -192,6 +190,7 @@ RSpec.describe 'Clusters', :js do before do visit project_clusters_path(project) + click_link 'Certificate based' end it 'user sees a table with one cluster' do @@ -214,7 +213,8 @@ RSpec.describe 'Clusters', :js do before do visit project_clusters_path(project) - click_link 'Integrate with a cluster certificate' + click_link 'Certificate based' + click_link 'Connect with a certificate' click_link 'Create new cluster' end diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb index 431cbb4ffbb..67d3276fc14 100644 --- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb +++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb @@ -11,6 +11,7 @@ RSpec.describe "User deletes comments on a commit", :js do let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) project.add_developer(user) diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb index 6997c2d8338..b0be6edb245 100644 --- a/spec/features/projects/commit/user_comments_on_commit_spec.rb +++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb @@ -93,6 +93,8 @@ RSpec.describe "User comments on commit", :js do context "when deleting comment" do before do + stub_feature_flags(bootstrap_confirmation_modals: false) + visit(project_commit_path(project, sample_commit.id)) add_note(comment_text) diff --git a/spec/features/projects/confluence/user_views_confluence_page_spec.rb b/spec/features/projects/confluence/user_views_confluence_page_spec.rb index ece2f82f5c6..49e7839f16c 100644 --- a/spec/features/projects/confluence/user_views_confluence_page_spec.rb +++ b/spec/features/projects/confluence/user_views_confluence_page_spec.rb @@ -16,9 +16,12 @@ RSpec.describe 'User views the Confluence page' do visit project_wikis_confluence_path(project) + expect(page).to have_css('.nav-sidebar li.active', text: 'Confluence', match: :first) + element = page.find('.row.empty-state') expect(element).to have_link('Go to Confluence', href: service.confluence_url) + expect(element).to have_link('Confluence epic', href: 'https://gitlab.com/groups/gitlab-org/-/epics/3629') end it 'does not show the page when the Confluence integration disabled' do diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index 5320f68b525..bcbf2f46f79 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -23,10 +23,6 @@ RSpec.describe 'Environment' do let!(:action) { } let!(:cluster) { } - before do - visit_environment(environment) - end - context 'with auto-stop' do let!(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) } @@ -52,12 +48,20 @@ RSpec.describe 'Environment' do end context 'without deployments' do + before do + visit_environment(environment) + end + it 'does not show deployments' do expect(page).to have_content('You don\'t have any deployments right now.') end end context 'with deployments' do + before do + visit_environment(environment) + end + context 'when there is no related deployable' do let(:deployment) do create(:deployment, :success, environment: environment, deployable: nil) @@ -108,6 +112,26 @@ RSpec.describe 'Environment' do end end + context 'with many deployments' do + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, pipeline: pipeline) } + + let!(:second) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: Time.current) } + let!(:first) { create(:deployment, environment: environment, deployable: build, status: :running) } + let!(:last) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: 2.days.ago) } + let!(:third) { create(:deployment, environment: environment, deployable: build, status: :canceled, finished_at: 1.day.ago) } + + before do + visit_environment(environment) + end + + it 'shows all of them in ordered way' do + ids = find_all('[data-testid="deployment-id"]').map { |e| e.text } + expected_ordered_ids = [first, second, third, last].map { |d| "##{d.iid}" } + expect(ids).to eq(expected_ordered_ids) + end + end + context 'with related deployable present' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } @@ -116,6 +140,10 @@ RSpec.describe 'Environment' do create(:deployment, :success, environment: environment, deployable: build) end + before do + visit_environment(environment) + end + it 'does show build name' do expect(page).to have_link("#{build.name} (##{build.id})") end diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 34e2ca7c8a7..3b83c25b629 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Environments page', :js do let(:role) { :developer } before do + stub_feature_flags(new_environments_table: false) project.add_role(user, role) sign_in(user) end @@ -142,6 +143,8 @@ RSpec.describe 'Environments page', :js do create(:environment, project: project, state: :available) end + stub_feature_flags(bootstrap_confirmation_modals: false) + context 'when there are no deployments' do before do visit_environments(project) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 00e85a215b8..3afd1937652 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -31,7 +31,7 @@ RSpec.describe 'Import/Export - project import integration test', :js do it 'user imports an exported project successfully', :sidekiq_might_not_need_inline do visit new_project_path - click_import_project + click_link 'Import project' click_link 'GitLab export' fill_in :name, with: 'Test Project Name', visible: true @@ -50,7 +50,7 @@ RSpec.describe 'Import/Export - project import integration test', :js do visit new_project_path - click_import_project + click_link 'Import project' click_link 'GitLab export' fill_in :name, with: project.name, visible: true attach_file('file', file) @@ -61,8 +61,4 @@ RSpec.describe 'Import/Export - project import integration test', :js do end end end - - def click_import_project - find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage - end end diff --git a/spec/features/projects/infrastructure_registry_spec.rb b/spec/features/projects/infrastructure_registry_spec.rb index ee35e02b5e8..27d0866bc69 100644 --- a/spec/features/projects/infrastructure_registry_spec.rb +++ b/spec/features/projects/infrastructure_registry_spec.rb @@ -43,7 +43,7 @@ RSpec.describe 'Infrastructure Registry' do expect(page).to have_current_path(project_infrastructure_registry_path(terraform_module.project, terraform_module)) - expect(page).to have_css('.packages-app h1[data-testid="title"]', text: terraform_module.name) + expect(page).to have_css('.packages-app h2[data-testid="title"]', text: terraform_module.name) expect(page).to have_content('Provision instructions') expect(page).to have_content('Registry setup') diff --git a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb index f46cade9d5f..d2c4418f0d6 100644 --- a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb +++ b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb @@ -84,7 +84,7 @@ RSpec.describe 'User uses inherited settings', :js do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } let_it_be(:parent_settings) { { url: 'http://group.com', password: 'group' } } - let_it_be(:parent_integration) { create(:jira_integration, group: group, project: nil, **parent_settings) } + let_it_be(:parent_integration) { create(:jira_integration, :group, group: group, **parent_settings) } it_behaves_like 'inherited settings' end diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index 060b7ffbfc9..12e88bbf6a5 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -12,6 +12,7 @@ RSpec.describe 'User browses a job', :js do before do project.add_maintainer(user) project.enable_ci + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) @@ -36,8 +37,18 @@ RSpec.describe 'User browses a job', :js do expect(page).to have_content('Job has been erased') end - context 'with a failed job' do - let!(:build) { create(:ci_build, :failed, :trace_artifact, pipeline: pipeline) } + context 'with unarchived trace artifact' do + let!(:build) { create(:ci_build, :success, :unarchived_trace_artifact, :coverage, pipeline: pipeline) } + + it 'shows no trace message', :js do + wait_for_requests + + expect(page).to have_content('This job does not have a trace.') + end + end + + context 'with a failed job and live trace' do + let!(:build) { create(:ci_build, :failed, :trace_live, pipeline: pipeline) } it 'displays the failure reason' do wait_for_all_requests @@ -46,6 +57,18 @@ RSpec.describe 'User browses a job', :js do ".build-job > a[title='test - failed - (unknown failure)']") end end + + context 'with unarchived trace artifact' do + let!(:artifact) { create(:ci_job_artifact, :unarchived_trace_artifact, job: build) } + + it 'displays the failure reason from the live trace' do + wait_for_all_requests + within('.builds-container') do + expect(page).to have_selector( + ".build-job > a[title='test - failed - (unknown failure)']") + end + end + end end context 'when a failed job has been retried' do diff --git a/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb b/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb new file mode 100644 index 00000000000..e8a14694d88 --- /dev/null +++ b/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User triggers manual job with variables', :js do + let(:user) { create(:user) } + let(:user_access_level) { :developer } + let(:project) { create(:project, :repository, namespace: user.namespace) } + let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') } + let!(:build) { create(:ci_build, :manual, pipeline: pipeline) } + + before do + project.add_maintainer(user) + project.enable_ci + + sign_in(user) + + visit(project_job_path(project, build)) + end + + it 'passes values correctly' do + page.within(find("[data-testid='ci-variable-row']")) do + find("[data-testid='ci-variable-key']").set('key_name') + find("[data-testid='ci-variable-value']").set('key_value') + end + + find("[data-testid='trigger-manual-job-btn']").click + + wait_for_requests + + expect(build.job_variables.as_json).to contain_exactly( + hash_including('key' => 'key_name', 'value' => 'key_value')) + end +end diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index c4bd0b81dc0..4881a7bdf1a 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do before do project.add_developer(user) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end it 'user leaves project' do diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 113ba692497..dcaef5f4ef0 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do before do sign_in(user) visit project_path(project) + stub_feature_flags(bootstrap_confirmation_modals: false) end it 'request access feature is disabled' do diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index dacbaa826a0..4dedd5689de 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -23,7 +23,7 @@ RSpec.describe 'New project', :js do ) visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' expect(page).to have_content 'Other visibility settings have been disabled by the administrator.' end @@ -34,7 +34,7 @@ RSpec.describe 'New project', :js do ) visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' expect(page).to have_content 'Visibility settings have been disabled by the administrator.' end @@ -49,14 +49,14 @@ RSpec.describe 'New project', :js do it 'shows "New project" page', :js do visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' expect(page).to have_content('Project name') expect(page).to have_content('Project URL') expect(page).to have_content('Project slug') click_link('New project') - find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Import project' expect(page).to have_link('GitHub') expect(page).to have_link('Bitbucket') @@ -69,7 +69,7 @@ RSpec.describe 'New project', :js do before do visit new_project_path - find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Import project' end it 'has Manifest file' do @@ -83,7 +83,7 @@ RSpec.describe 'New project', :js do stub_application_setting(default_project_visibility: level) visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' page.within('#blank-project-pane') do expect(find_field("project_visibility_level_#{level}")).to be_checked end @@ -91,7 +91,7 @@ RSpec.describe 'New project', :js do it "saves visibility level #{level} on validation error" do visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' choose(key) click_button('Create project') @@ -111,7 +111,7 @@ RSpec.describe 'New project', :js do context 'when admin mode is enabled', :enable_admin_mode do it 'has private selected' do visit new_project_path(namespace_id: group.id) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' page.within('#blank-project-pane') do expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked @@ -138,7 +138,7 @@ RSpec.describe 'New project', :js do context 'when admin mode is enabled', :enable_admin_mode do it 'has private selected' do visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE }) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' page.within('#blank-project-pane') do expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked @@ -159,7 +159,7 @@ RSpec.describe 'New project', :js do context 'Readme selector' do it 'shows the initialize with Readme checkbox on "Blank project" tab' do visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' expect(page).to have_css('input#project_initialize_with_readme') expect(page).to have_content('Initialize repository with a README') @@ -167,7 +167,7 @@ RSpec.describe 'New project', :js do it 'does not show the initialize with Readme checkbox on "Create from template" tab' do visit new_project_path - find('[data-qa-panel-name="create_from_template"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create from template' first('.choose-template').click page.within '.project-fields-form' do @@ -178,7 +178,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 - find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Import project' first('.js-import-git-toggle-button').click page.within '#import-project-pane' do @@ -192,7 +192,7 @@ RSpec.describe 'New project', :js do context 'with user namespace' do before do visit new_project_path - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' end it 'selects the user namespace' do @@ -208,7 +208,7 @@ RSpec.describe 'New project', :js do before do group.add_owner(user) visit new_project_path(namespace_id: group.id) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' end it 'selects the group namespace' do @@ -225,7 +225,7 @@ RSpec.describe 'New project', :js do before do group.add_maintainer(user) visit new_project_path(namespace_id: subgroup.id) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' end it 'selects the group namespace' do @@ -245,7 +245,7 @@ RSpec.describe 'New project', :js do internal_group.add_owner(user) private_group.add_owner(user) visit new_project_path(namespace_id: public_group.id) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' end it 'enables the correct visibility options' do @@ -275,7 +275,7 @@ RSpec.describe 'New project', :js do context 'Import project options', :js do before do visit new_project_path - find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Import project' end context 'from git repository url, "Repo by URL"' do @@ -351,7 +351,7 @@ RSpec.describe 'New project', :js do before do group.add_developer(user) visit new_project_path(namespace_id: group.id) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' end it 'selects the group namespace' do diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb index 9b1e87192f5..7fcc8200b1c 100644 --- a/spec/features/projects/packages_spec.rb +++ b/spec/features/projects/packages_spec.rb @@ -27,10 +27,6 @@ RSpec.describe 'Packages' do context 'when feature is available', :js do before do - # we are simply setting the featrure flag to false because the new UI has nothing to test yet - # when the refactor is complete or almost complete we will turn on the feature tests - # see https://gitlab.com/gitlab-org/gitlab/-/issues/330846 for status of this work - stub_feature_flags(package_list_apollo: false) visit_project_packages end diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb index de9effe3dc7..06f130ae69c 100644 --- a/spec/features/projects/pages/user_adds_domain_spec.rb +++ b/spec/features/projects/pages/user_adds_domain_spec.rb @@ -14,6 +14,8 @@ RSpec.describe 'User adds pages domain', :js do project.add_maintainer(user) sign_in(user) + + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when pages are exposed on external HTTP address', :http_pages_enabled do diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb index cf8438d5e6f..a3fc5804e13 100644 --- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb @@ -14,6 +14,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do before do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) stub_lets_encrypt_settings + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_role(user, role) sign_in(user) diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb index 71d4cce2784..1226e1dc2ed 100644 --- a/spec/features/projects/pages/user_edits_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_settings_spec.rb @@ -176,6 +176,7 @@ RSpec.describe 'Pages edits pages settings', :js do describe 'Remove page' do context 'when pages are deployed' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.mark_pages_as_deployed end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 94e3331b173..9df430c0f78 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Pipeline Schedules', :js do context 'logged in as maintainer' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) gitlab_sign_in(user) end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index bd22c8632e4..e38c4989f26 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -317,6 +317,7 @@ RSpec.describe 'Pipelines', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit_project_pipelines end @@ -635,7 +636,7 @@ RSpec.describe 'Pipelines', :js do # header expect(page).to have_text("##{pipeline.id}") - expect(page).to have_selector(%Q(img[alt$="#{pipeline.user.name}'s avatar"])) + expect(page).to have_selector(%Q(img[src="#{pipeline.user.avatar_url}"])) expect(page).to have_link(pipeline.user.name, href: user_path(pipeline.user)) # stages diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb index 6bc4c66b8ca..98935fdf872 100644 --- a/spec/features/projects/releases/user_views_releases_spec.rb +++ b/spec/features/projects/releases/user_views_releases_spec.rb @@ -123,11 +123,11 @@ RSpec.describe 'User views releases', :js do within('.release-block', match: :first) do expect(page).to have_content(release_v3.description) + expect(page).to have_content(release_v3.tag) + expect(page).to have_content(release_v3.name) # The following properties (sometimes) include Git info, # so they are not rendered for Guest users - expect(page).not_to have_content(release_v3.name) - expect(page).not_to have_content(release_v3.tag) expect(page).not_to have_content(release_v3.commit.short_id) end end diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb index 4941b936c0c..d8de9e0449e 100644 --- a/spec/features/projects/settings/access_tokens_spec.rb +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -13,6 +13,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/projects/settings/packages_settings_spec.rb b/spec/features/projects/settings/packages_settings_spec.rb index 62f31fd027b..e70839e9720 100644 --- a/spec/features/projects/settings/packages_settings_spec.rb +++ b/spec/features/projects/settings/packages_settings_spec.rb @@ -19,7 +19,7 @@ RSpec.describe 'Projects > Settings > Packages', :js do let(:packages_enabled) { true } it 'displays the packages toggle button' do - expect(page).to have_button('Packages', class: 'gl-toggle') + expect(page).to have_selector('[data-testid="toggle-label"]', text: 'Packages') expect(page).to have_selector('input[name="project[packages_enabled]"] + button', visible: true) end end @@ -28,7 +28,7 @@ RSpec.describe 'Projects > Settings > Packages', :js do let(:packages_enabled) { false } it 'does not show up in UI' do - expect(page).not_to have_button('Packages', class: 'gl-toggle') + expect(page).not_to have_selector('[data-testid="toggle-label"]', text: 'Packages') end end end diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb index 0924f8320e1..0df4bd3f0d9 100644 --- a/spec/features/projects/settings/service_desk_setting_spec.rb +++ b/spec/features/projects/settings/service_desk_setting_spec.rb @@ -54,7 +54,7 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache do wait_for_requests project.reload - expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address) + expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_custom_address) page.within '#js-service-desk' do fill_in('service-desk-project-suffix', with: 'foo') diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb index 7ed96d01189..44b5464a1b0 100644 --- a/spec/features/projects/settings/user_searches_in_settings_spec.rb +++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'User searches project settings', :js do let_it_be(:project) { create(:project, :repository, namespace: user.namespace, pages_https_only: false) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/projects/settings/user_tags_project_spec.rb b/spec/features/projects/settings/user_tags_project_spec.rb index ff19ed22744..e9a2aa29352 100644 --- a/spec/features/projects/settings/user_tags_project_spec.rb +++ b/spec/features/projects/settings/user_tags_project_spec.rb @@ -2,22 +2,40 @@ require 'spec_helper' -RSpec.describe 'Projects > Settings > User tags a project' do +RSpec.describe 'Projects > Settings > User tags a project', :js do let(:user) { create(:user) } let(:project) { create(:project, namespace: user.namespace) } + let!(:topic) { create(:topic, name: 'topic1') } before do sign_in(user) visit edit_project_path(project) + wait_for_all_requests end - it 'sets project topics' do - fill_in 'Topics', with: 'topic1, topic2' + it 'select existing topic' do + fill_in class: 'gl-token-selector-input', with: 'topic1' + wait_for_all_requests + + find('.gl-avatar-labeled[entity-name="topic1"]').click + + page.within '.general-settings' do + click_button 'Save changes' + end + + expect(find('#project_topic_list_field', visible: :hidden).value).to eq 'topic1' + end + + it 'select new topic' do + fill_in class: 'gl-token-selector-input', with: 'topic2' + wait_for_all_requests + + click_button 'Add "topic2"' page.within '.general-settings' do click_button 'Save changes' end - expect(find_field('Topics').value).to eq 'topic1, topic2' + expect(find('#project_topic_list_field', visible: :hidden).value).to eq 'topic2' end end diff --git a/spec/features/projects/show/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb index d18ff75b324..ed06f4e14d3 100644 --- a/spec/features/projects/show/no_password_spec.rb +++ b/spec/features/projects/show/no_password_spec.rb @@ -3,6 +3,9 @@ require 'spec_helper' RSpec.describe 'No Password Alert' do + let_it_be(:message_password_auth_enabled) { 'Your account is authenticated with SSO or SAML. To push and pull over HTTP with Git using this account, you must set a password or set up a Personal Access Token to use instead of a password. For more information, see Clone with HTTPS.' } + let_it_be(:message_password_auth_disabled) { 'Your account is authenticated with SSO or SAML. To push and pull over HTTP with Git using this account, you must set up a Personal Access Token to use instead of a password. For more information, see Clone with HTTPS.' } + let(:project) { create(:project, :repository, namespace: user.namespace) } context 'with internal auth enabled' do @@ -15,7 +18,7 @@ RSpec.describe 'No Password Alert' do let(:user) { create(:user) } it 'shows no alert' do - expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you set a password on your account" + expect(page).not_to have_content message_password_auth_enabled end end @@ -23,7 +26,7 @@ RSpec.describe 'No Password Alert' do let(:user) { create(:user, password_automatically_set: true) } it 'shows a password alert' do - expect(page).to have_content "You won't be able to pull or push repositories via HTTP until you set a password on your account" + expect(page).to have_content message_password_auth_enabled end end end @@ -41,7 +44,7 @@ RSpec.describe 'No Password Alert' do gitlab_sign_in_via('saml', user, 'my-uid') visit project_path(project) - expect(page).to have_content "You won't be able to pull or push repositories via HTTP until you create a personal access token on your account" + expect(page).to have_content message_password_auth_disabled end end @@ -51,7 +54,7 @@ RSpec.describe 'No Password Alert' do gitlab_sign_in_via('saml', user, 'my-uid') visit project_path(project) - expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you create a personal access token on your account" + expect(page).not_to have_content message_password_auth_disabled end end end diff --git a/spec/features/projects/show/user_uploads_files_spec.rb b/spec/features/projects/show/user_uploads_files_spec.rb index 51e41397439..92b54d83ef3 100644 --- a/spec/features/projects/show/user_uploads_files_spec.rb +++ b/spec/features/projects/show/user_uploads_files_spec.rb @@ -44,27 +44,27 @@ RSpec.describe 'Projects > Show > User uploads files' do end end - context 'when in the empty_repo_upload experiment' do - before do - stub_experiments(empty_repo_upload: :candidate) + context 'with an empty repo' do + let(:project) { create(:project, :empty_repo, creator: user) } + before do visit(project_path(project)) end - context 'with an empty repo' do - let(:project) { create(:project, :empty_repo, creator: user) } - - [true, false].each do |value| - include_examples 'uploads and commits a new text file via "upload file" button', drop: value - end + [true, false].each do |value| + include_examples 'uploads and commits a new text file via "upload file" button', drop: value end + end - context 'with a nonempty repo' do - let(:project) { create(:project, :repository, creator: user) } + context 'with a nonempty repo' do + let(:project) { create(:project, :repository, creator: user) } - [true, false].each do |value| - include_examples 'uploads and commits a new text file via "upload file" button', drop: value - end + before do + visit(project_path(project)) + end + + [true, false].each do |value| + include_examples 'uploads and commits a new text file via "upload file" button', drop: value end 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 39b8cddd005..345d16982fd 100644 --- a/spec/features/projects/user_changes_project_visibility_spec.rb +++ b/spec/features/projects/user_changes_project_visibility_spec.rb @@ -22,7 +22,7 @@ RSpec.describe 'User changes public project visibility', :js do click_button 'Save changes' end - find('.js-confirm-danger-input').send_keys(project.path_with_namespace) + find('.js-legacy-confirm-danger-input').send_keys(project.path_with_namespace) page.within '.modal' do click_button 'Reduce project visibility' diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb index 5d482f9fbd0..f5e8a5e8fc1 100644 --- a/spec/features/projects/user_creates_project_spec.rb +++ b/spec/features/projects/user_creates_project_spec.rb @@ -14,7 +14,7 @@ RSpec.describe 'User creates a project', :js do it 'creates a new project' do visit(new_project_path) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' fill_in(:project_name, with: 'Empty') expect(page).to have_checked_field 'Initialize repository with a README' @@ -38,7 +38,7 @@ RSpec.describe 'User creates a project', :js do visit(new_project_path) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' fill_in(:project_name, with: 'With initial commits') expect(page).to have_checked_field 'Initialize repository with a README' @@ -67,7 +67,7 @@ RSpec.describe 'User creates a project', :js do it 'creates a new project' do visit(new_project_path) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' fill_in :project_name, with: 'A Subgroup Project' fill_in :project_path, with: 'a-subgroup-project' @@ -96,7 +96,7 @@ RSpec.describe 'User creates a project', :js do it 'creates a new project' do visit(new_project_path) - find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create blank project' fill_in :project_name, with: 'a-new-project' fill_in :project_path, with: 'a-new-project' diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 59ad7d31ea7..c4619b5498e 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'Project' do shared_examples 'creates from template' do |template, sub_template_tab = nil| it "is created from template", :js do - find('[data-qa-panel-name="create_from_template"]').click # rubocop:disable QA/SelectorUsage + click_link 'Create from template' find(".project-template #{sub_template_tab}").click if sub_template_tab find("label[for=#{template.name}]").click fill_in("project_name", with: template.name) @@ -133,7 +133,7 @@ RSpec.describe 'Project' do visit path expect(page).to have_selector('[data-testid="project_topic_list"]') - expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1')) + expect(page).to have_link('topic1', href: topic_explore_projects_path(topic_name: 'topic1')) end it 'shows up to 3 project topics' do @@ -142,9 +142,9 @@ RSpec.describe 'Project' do visit path expect(page).to have_selector('[data-testid="project_topic_list"]') - expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1')) - expect(page).to have_link('topic2', href: explore_projects_path(topic: 'topic2')) - expect(page).to have_link('topic3', href: explore_projects_path(topic: 'topic3')) + expect(page).to have_link('topic1', href: topic_explore_projects_path(topic_name: 'topic1')) + expect(page).to have_link('topic2', href: topic_explore_projects_path(topic_name: 'topic2')) + expect(page).to have_link('topic3', href: topic_explore_projects_path(topic_name: 'topic3')) expect(page).to have_content('+ 1 more') end end @@ -257,7 +257,7 @@ RSpec.describe 'Project' do end it 'deletes a project', :sidekiq_inline do - expect { remove_with_confirm('Delete project', project.path, 'Yes, delete project') }.to change { Project.count }.by(-1) + expect { remove_with_confirm('Delete project', project.path_with_namespace, 'Yes, delete project') }.to change { Project.count }.by(-1) expect(page).to have_content "Project '#{project.full_name}' is in the process of being deleted." expect(Project.all.count).to be_zero expect(project.issues).to be_empty diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb index d679e4dbb99..610a80eb12c 100644 --- a/spec/features/signed_commits_spec.rb +++ b/spec/features/signed_commits_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'GPG signed commits' do perform_enqueued_jobs do create :gpg_key, key: GpgHelpers::User1.public_key, user: user + user.reload # necessary to reload the association with gpg_keys end visit project_commit_path(project, ref) @@ -114,6 +115,19 @@ RSpec.describe 'GPG signed commits' do end end + it 'unverified signature: commit contains multiple GPG signatures' do + user_1_key + + visit project_commit_path(project, GpgHelpers::MULTIPLE_SIGNATURES_SHA) + wait_for_all_requests + + page.find('.gpg-status-box', text: 'Unverified').click + + within '.popover' do + expect(page).to have_content "This commit was signed with multiple signatures." + end + end + it 'verified and the gpg user has a gitlab profile' do user_1_key @@ -168,7 +182,7 @@ RSpec.describe 'GPG signed commits' do page.find('.gpg-status-box', text: 'Unverified').click within '.popover' do - expect(page).to have_content 'This commit was signed with an unverified signature' + expect(page).to have_content 'This commit was signed with multiple signatures.' end end end diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index fc88cd9205c..6bd31d7314c 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -18,6 +18,7 @@ RSpec.describe 'Comments on personal snippets', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in user visit snippet_path(snippet) diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index ca050daa62a..82fe895d397 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -16,6 +16,7 @@ RSpec.describe 'User creates snippet', :js do let(:snippet_title_field) { 'snippet-title' } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) visit new_snippet_path diff --git a/spec/features/topic_show_spec.rb b/spec/features/topic_show_spec.rb new file mode 100644 index 00000000000..3a9865a6503 --- /dev/null +++ b/spec/features/topic_show_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Topic show page' do + let_it_be(:topic) { create(:topic, name: 'my-topic', description: 'This is **my** topic https://google.com/ :poop: ```\ncode\n```', avatar: fixture_file_upload("spec/fixtures/dk.png", "image/png")) } + + context 'when topic does not exist' do + let(:path) { topic_explore_projects_path(topic_name: 'non-existing') } + + it 'renders 404' do + visit path + + expect(status_code).to eq(404) + end + end + + context 'when topic exists' do + before do + visit topic_explore_projects_path(topic_name: topic.name) + end + + it 'shows name, avatar and description as markdown' do + expect(page).to have_content(topic.name) + expect(page).to have_selector('.avatar-container > img.topic-avatar') + expect(find('.topic-description')).to have_selector('p > strong') + expect(find('.topic-description')).to have_selector('p > a[rel]') + expect(find('.topic-description')).to have_selector('p > gl-emoji') + expect(find('.topic-description')).to have_selector('p > code') + end + + context 'with associated projects' do + let!(:project) { create(:project, :public, topic_list: topic.name) } + + it 'shows project list' do + visit topic_explore_projects_path(topic_name: topic.name) + + expect(find('.projects-list .project-name')).to have_content(project.name) + end + end + + context 'without associated projects' do + it 'shows correct empty state message' do + expect(page).to have_content('Explore public groups to find projects to contribute to.') + end + end + end +end diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 6fa805d8c74..2ddd86dd807 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -72,6 +72,7 @@ RSpec.describe 'Triggers', :js do describe 'trigger "Revoke" workflow' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) create(:ci_trigger, owner: user2, project: @project, description: trigger_title) visit project_settings_ci_cd_path(@project) end diff --git a/spec/features/users/confirmation_spec.rb b/spec/features/users/confirmation_spec.rb new file mode 100644 index 00000000000..aaa49c75223 --- /dev/null +++ b/spec/features/users/confirmation_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User confirmation' do + describe 'resend confirmation instructions' do + context 'when recaptcha is enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + allow(Gitlab::Recaptcha).to receive(:load_configurations!) + visit new_user_confirmation_path + end + + it 'renders recaptcha' do + expect(page).to have_css('.g-recaptcha') + end + end + + context 'when recaptcha is not enabled' do + before do + stub_application_setting(recaptcha_enabled: false) + visit new_user_confirmation_path + end + + it 'does not render recaptcha' do + expect(page).not_to have_css('.g-recaptcha') + end + end + end +end diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 10c1c2cb26e..66ebd00d368 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -753,7 +753,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do end end - context 'when terms are enforced' do + context 'when terms are enforced', :js do let(:user) { create(:user) } before do @@ -802,7 +802,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do end context 'when the user did not enable 2FA' do - it 'asks to set 2FA before asking to accept the terms', :js do + it 'asks to set 2FA before asking to accept the terms' do expect(authentication_metrics) .to increment(:user_authenticated_counter) @@ -887,7 +887,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do end end - context 'when the user does not have an email configured', :js do + context 'when the user does not have an email configured' do let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml', email: 'temp-email-for-oauth-user@gitlab.localhost') } before do diff --git a/spec/features/users/password_spec.rb b/spec/features/users/password_spec.rb new file mode 100644 index 00000000000..793a11c616e --- /dev/null +++ b/spec/features/users/password_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'User password' do + describe 'send password reset' do + context 'when recaptcha is enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + allow(Gitlab::Recaptcha).to receive(:load_configurations!) + visit new_user_password_path + end + + it 'renders recaptcha' do + expect(page).to have_css('.g-recaptcha') + end + end + + context 'when recaptcha is not enabled' do + before do + stub_application_setting(recaptcha_enabled: false) + visit new_user_password_path + end + + it 'does not render recaptcha' do + expect(page).not_to have_css('.g-recaptcha') + end + end + end +end diff --git a/spec/features/users/terms_spec.rb b/spec/features/users/terms_spec.rb index 8ba79d77c22..7cfe74f8aa9 100644 --- a/spec/features/users/terms_spec.rb +++ b/spec/features/users/terms_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Users > Terms' do +RSpec.describe 'Users > Terms', :js do include TermsHelper let!(:term) { create(:term, terms: 'By accepting, you promise to be nice!') } |