diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-20 16:49:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-20 16:49:51 +0300 |
commit | 71786ddc8e28fbd3cb3fcc4b3ff15e5962a1c82e (patch) | |
tree | 6a2d93ef3fb2d353bb7739e4b57e6541f51cdd71 /spec/features | |
parent | a7253423e3403b8c08f8a161e5937e1488f5f407 (diff) |
Add latest changes from gitlab-org/gitlab@15-9-stable-eev15.9.0-rc42
Diffstat (limited to 'spec/features')
166 files changed, 1996 insertions, 1406 deletions
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb index e0a61656a88..1267025a7bf 100644 --- a/spec/features/abuse_report_spec.rb +++ b/spec/features/abuse_report_spec.rb @@ -56,7 +56,7 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do let_it_be(:incident) { create(:incident, project: project, author: abusive_user) } before do - visit project_issues_incident_path(project, incident) + visit incident_project_issues_path(project, incident) click_button 'Incident actions' end @@ -82,7 +82,7 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do visit user_path(abusive_user) - fill_and_submit_abuse_category_form("They're being offsensive or abusive.") + fill_and_submit_abuse_category_form("They're being offensive or abusive.") fill_and_submit_report_abuse_form expect(page).to have_content 'Thank you for your report' @@ -136,7 +136,7 @@ RSpec.describe 'Abuse reports', :js, feature_category: :insider_threat do click_button 'More actions' end - it_behaves_like 'reports the user without an abuse category' + it_behaves_like 'reports the user with an abuse category' end end diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb index 5fbe7039c1d..252d9ac5bac 100644 --- a/spec/features/admin/admin_appearance_spec.rb +++ b/spec/features/admin/admin_appearance_spec.rb @@ -19,6 +19,9 @@ RSpec.describe 'Admin Appearance', feature_category: :not_owned do fill_in 'appearance_title', with: 'MyCompany' fill_in 'appearance_description', with: 'dev server' + fill_in 'appearance_pwa_name', with: 'GitLab PWA' + fill_in 'appearance_pwa_short_name', with: 'GitLab' + fill_in 'appearance_pwa_description', with: 'GitLab as PWA' fill_in 'appearance_new_project_guidelines', with: 'Custom project guidelines' fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines' click_button 'Update appearance settings' @@ -28,6 +31,9 @@ RSpec.describe 'Admin Appearance', feature_category: :not_owned do expect(page).to have_field('appearance_title', with: 'MyCompany') expect(page).to have_field('appearance_description', with: 'dev server') + expect(page).to have_field('appearance_pwa_name', with: 'GitLab PWA') + expect(page).to have_field('appearance_pwa_short_name', with: 'GitLab') + expect(page).to have_field('appearance_pwa_description', with: 'GitLab as PWA') expect(page).to have_field('appearance_new_project_guidelines', with: 'Custom project guidelines') expect(page).to have_field('appearance_profile_image_guidelines', with: 'Custom profile image guidelines') expect(page).to have_content 'Last edit' @@ -135,6 +141,19 @@ RSpec.describe 'Admin Appearance', feature_category: :not_owned do expect(page).not_to have_css(logo_selector) end + it 'appearance pwa icon' do + sign_in(admin) + gitlab_enable_admin_mode_sign_in(admin) + visit admin_application_settings_appearances_path + + attach_file(:appearance_pwa_icon, logo_fixture) + click_button 'Update appearance settings' + expect(page).to have_css(pwa_icon_selector) + + click_link 'Remove icon' + expect(page).not_to have_css(pwa_icon_selector) + end + it 'header logos' do sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) @@ -183,6 +202,10 @@ RSpec.describe 'Admin Appearance', feature_category: :not_owned do '//img[data-src^="/uploads/-/system/appearance/logo"]' end + def pwa_icon_selector + '//img[data-src^="/uploads/-/system/appearance/pwa_icon"]' + end + def header_logo_selector '//img[data-src^="/uploads/-/system/appearance/header_logo"]' end diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 119e09f9b09..a07a5c48713 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' RSpec.describe 'Admin Groups', feature_category: :subgroups do - include Select2Helper include Spec::Support::Helpers::Features::MembersHelpers include Spec::Support::Helpers::Features::InviteMembersModalHelper include Spec::Support::Helpers::ModalHelpers diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index e6630e40147..363c152371e 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -105,8 +105,8 @@ RSpec.describe 'Admin::Hooks', feature_category: :integrations do WebMock.stub_request(:post, system_hook.url) visit admin_hooks_path - find('.hook-test-button.dropdown').click - click_link 'Push events' + click_button 'Test' + click_button 'Push events' end it { expect(page).to have_current_path(admin_hooks_path, ignore_query: true) } @@ -141,8 +141,8 @@ RSpec.describe 'Admin::Hooks', feature_category: :integrations do create(:merge_request, source_project: project) visit admin_hooks_path - find('.hook-test-button.dropdown').click - click_link 'Merge request events' + click_button 'Test' + click_button 'Merge request events' expect(page).to have_content 'Hook executed successfully' end diff --git a/spec/features/admin/admin_jobs_spec.rb b/spec/features/admin/admin_jobs_spec.rb index f0eaa83f05e..d46b314c144 100644 --- a/spec/features/admin/admin_jobs_spec.rb +++ b/spec/features/admin/admin_jobs_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do before do + stub_feature_flags(admin_jobs_vue: false) admin = create(:admin) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) @@ -28,8 +29,8 @@ RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do expect(page).to have_button 'Stop all jobs' click_button 'Stop all jobs' - expect(page).to have_button 'Stop jobs' - expect(page).to have_content 'Stop all jobs?' + expect(page).to have_button 'Yes, proceed' + expect(page).to have_content 'Are you sure?' end end diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index 3c7eba2cc97..f08e6521184 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -6,6 +6,7 @@ RSpec.describe "Admin::Projects", feature_category: :projects do include Spec::Support::Helpers::Features::MembersHelpers include Spec::Support::Helpers::Features::InviteMembersModalHelper include Spec::Support::Helpers::ModalHelpers + include ListboxHelpers let_it_be_with_reload(:user) { create :user } let_it_be_with_reload(:project) { create(:project, :with_namespace_settings) } @@ -117,8 +118,7 @@ RSpec.describe "Admin::Projects", feature_category: :projects do it 'transfers project to group web', :js do visit admin_project_path(project) - click_button 'Search for Namespace' - click_button 'group: web' + select_from_listbox 'group: web', from: 'Search for Namespace' click_button 'Transfer' expect(page).to have_content("Web / #{project.name}") diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 30fd04b1c3e..04dc206f052 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -21,13 +21,27 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do let_it_be(:namespace) { create(:namespace) } let_it_be(:project) { create(:project, namespace: namespace, creator: user) } + describe "runners creation" do + before do + stub_feature_flags(create_runner_workflow: true) + + visit admin_runners_path + end + + it 'shows a create button' do + expect(page).to have_link s_('Runner|New instance runner'), href: new_admin_runner_path + end + end + describe "runners registration" do before do + stub_feature_flags(create_runner_workflow: false) + visit admin_runners_path end it_behaves_like "shows and resets runner registration token" do - let(:dropdown_text) { 'Register an instance runner' } + let(:dropdown_text) { s_('Runners|Register an instance runner') } let(:registration_token) { Gitlab::CurrentSettings.runners_registration_token } end end @@ -65,7 +79,6 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do end it 'has all necessary texts' do - expect(page).to have_text "Register an instance runner" expect(page).to have_text "#{s_('Runners|All')} 3" expect(page).to have_text "#{s_('Runners|Online')} 1" expect(page).to have_text "#{s_('Runners|Offline')} 2" @@ -491,6 +504,8 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do ) end + let_it_be(:runner_job) { create(:ci_build, runner: runner) } + before do visit admin_runner_path(runner) end @@ -517,6 +532,11 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do end end + it_behaves_like 'shows runner jobs tab' do + let(:job_count) { '1' } + let(:job) { runner_job } + end + describe 'when a runner is deleted' do before do click_on 'Delete runner' @@ -644,7 +664,7 @@ RSpec.describe "Admin Runners", feature_category: :runner_fleet do visit edit_admin_runner_path(runner) end - it 'removed specific runner from project' do + it 'removed project runner from project' do within '[data-testid="assigned-projects"]' do click_on 'Disable' end diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb index 4b8636da6b4..cad1bf74d2e 100644 --- a/spec/features/admin/admin_sees_background_migrations_spec.rb +++ b/spec/features/admin/admin_sees_background_migrations_spec.rb @@ -92,11 +92,11 @@ RSpec.describe "Admin > Admin sees background migrations", feature_category: :da expect(page).not_to have_content('Paused') expect(page).to have_content('Active') - click_button('Pause') + click_on('Pause') expect(page).not_to have_content('Active') expect(page).to have_content('Paused') - click_button('Resume') + click_on('Resume') expect(page).not_to have_content('Paused') expect(page).to have_content('Active') end @@ -123,7 +123,7 @@ RSpec.describe "Admin > Admin sees background migrations", feature_category: :da tab = find_link 'Failed' tab.click - expect(page).to have_selector("[method='post'][action='/admin/background_migrations/#{failed_migration.id}/retry?database=main']") + expect(page).to have_selector("[data-method='post'][href='/admin/background_migrations/#{failed_migration.id}/retry?database=main']") end end @@ -144,7 +144,7 @@ RSpec.describe "Admin > Admin sees background migrations", feature_category: :da expect(page).to have_content('0.00%') expect(page).to have_content(failed_migration.status_name.to_s) - click_button('Retry') + click_on('Retry') expect(page).not_to have_content(failed_migration.job_class_name) expect(page).not_to have_content(failed_migration.table_name) expect(page).not_to have_content('0.00%') @@ -172,7 +172,7 @@ RSpec.describe "Admin > Admin sees background migrations", feature_category: :da end it 'can change tabs and retain database param' do - skip_if_multiple_databases_not_setup + skip_if_multiple_databases_not_setup(:ci) visit admin_background_migrations_path(database: 'ci') @@ -212,7 +212,7 @@ RSpec.describe "Admin > Admin sees background migrations", feature_category: :da context 'when multi database is enabled' do before do - skip_if_multiple_databases_not_setup + skip_if_multiple_databases_not_setup(:ci) allow(Gitlab::Database).to receive(:db_config_names).and_return(%w[main ci]) end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 2ac86ab9f49..26efed85513 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do end it 'change visibility settings' do - page.within('.as-visibility-access') do + page.within('[data-testid="admin-visibility-access-settings"]') do choose "application_setting_default_project_visibility_20" click_button 'Save changes' end @@ -33,23 +33,29 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do end it 'uncheck all restricted visibility levels' do - page.within('.as-visibility-access') do - find('#application_setting_restricted_visibility_levels_0').set(false) - find('#application_setting_restricted_visibility_levels_10').set(false) - find('#application_setting_restricted_visibility_levels_20').set(false) + page.within('[data-testid="restricted-visibility-levels"]') do + uncheck s_('VisibilityLevel|Public') + uncheck s_('VisibilityLevel|Internal') + uncheck s_('VisibilityLevel|Private') + end + + page.within('[data-testid="admin-visibility-access-settings"]') do click_button 'Save changes' end expect(page).to have_content "Application settings saved successfully" - expect(find('#application_setting_restricted_visibility_levels_0')).not_to be_checked - expect(find('#application_setting_restricted_visibility_levels_10')).not_to be_checked - expect(find('#application_setting_restricted_visibility_levels_20')).not_to be_checked + + page.within('[data-testid="restricted-visibility-levels"]') do + expect(find_field(s_('VisibilityLevel|Public'))).not_to be_checked + expect(find_field(s_('VisibilityLevel|Internal'))).not_to be_checked + expect(find_field(s_('VisibilityLevel|Private'))).not_to be_checked + end end it 'modify import sources' do expect(current_settings.import_sources).not_to be_empty - page.within('.as-visibility-access') do + page.within('[data-testid="admin-visibility-access-settings"]') do Gitlab::ImportSources.options.map do |name, _| uncheck name end @@ -60,7 +66,7 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do expect(page).to have_content "Application settings saved successfully" expect(current_settings.import_sources).to be_empty - page.within('.as-visibility-access') do + page.within('[data-testid="admin-visibility-access-settings"]') do check "Repository by URL" click_button 'Save changes' end @@ -70,7 +76,7 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do end it 'change Visibility and Access Controls' do - page.within('.as-visibility-access') do + page.within('[data-testid="admin-visibility-access-settings"]') do page.within('[data-testid="project-export"]') do uncheck 'Enabled' end @@ -88,7 +94,7 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do end it 'change Keys settings' do - page.within('.as-visibility-access') do + page.within('[data-testid="admin-visibility-access-settings"]') do select 'Are forbidden', from: 'RSA SSH keys' select 'Are allowed', from: 'DSA SSH keys' select 'Must be at least 384 bits', from: 'ECDSA SSH keys' @@ -155,19 +161,28 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do context 'when Gitlab.com' do let(:dot_com?) { true } - it 'does not expose the setting' do - expect(page).to have_no_selector('#application_setting_deactivate_dormant_users') - end - - it 'does not expose the setting' do - expect(page).to have_no_selector('#application_setting_deactivate_dormant_users_period') + it 'does not expose the setting section' do + # NOTE: not_to have_content may have false positives for content + # that might not load instantly, so before checking that + # `Dormant users` subsection has _not_ loaded, we check that the + # `Account and limit` section _was_ loaded + expect(page).to have_content('Account and limit') + expect(page).not_to have_content('Dormant users') + expect(page).not_to have_field('Deactivate dormant users after a period of inactivity') + expect(page).not_to have_field('Days of inactivity before deactivation') end end context 'when not Gitlab.com' do let(:dot_com?) { false } - it 'changes Dormant users' do + it 'exposes the setting section' do + expect(page).to have_content('Dormant users') + expect(page).to have_field('Deactivate dormant users after a period of inactivity') + expect(page).to have_field('Days of inactivity before deactivation') + end + + it 'changes dormant users' do expect(page).to have_unchecked_field('Deactivate dormant users after a period of inactivity') expect(current_settings.deactivate_dormant_users).to be_falsey @@ -184,7 +199,7 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do expect(page).to have_checked_field('Deactivate dormant users after a period of inactivity') end - it 'change Dormant users period' do + it 'change dormant users period' do expect(page).to have_field _('Days of inactivity before deactivation') page.within(find('[data-testid="account-limit"]')) do @@ -198,6 +213,27 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do expect(page).to have_field _('Days of inactivity before deactivation'), with: '90' end + + it 'displays dormant users period field validation error', :js do + selector = '#application_setting_deactivate_dormant_users_period_error' + expect(page).not_to have_selector(selector, visible: :visible) + + page.within(find('[data-testid="account-limit"]')) do + check 'application_setting_deactivate_dormant_users' + fill_in _('application_setting_deactivate_dormant_users_period'), with: '30' + click_button 'Save changes' + end + + expect(page).to have_selector(selector, visible: :visible) + end + + it 'auto disables dormant users period field depending on parent checkbox', :js do + uncheck 'application_setting_deactivate_dormant_users' + expect(page).to have_field('application_setting_deactivate_dormant_users_period', disabled: true) + + check 'application_setting_deactivate_dormant_users' + expect(page).to have_field('application_setting_deactivate_dormant_users_period', disabled: false) + end end end @@ -329,11 +365,13 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do page.within('#js-jira_connect-settings') do fill_in 'Jira Connect Application ID', with: '1234' fill_in 'Jira Connect Proxy URL', with: 'https://example.com' + check 'Enable public key storage' click_button 'Save changes' end expect(current_settings.jira_connect_application_key).to eq('1234') expect(current_settings.jira_connect_proxy_url).to eq('https://example.com') + expect(current_settings.jira_connect_public_key_storage_enabled).to eq(true) expect(page).to have_content "Application settings saved successfully" end end @@ -791,9 +829,36 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do context 'Preferences page' do before do + stub_feature_flags(deactivation_email_additional_text: deactivation_email_additional_text_feature_flag) visit preferences_admin_application_settings_path end + let(:deactivation_email_additional_text_feature_flag) { true } + + describe 'Email page' do + context 'when deactivation email additional text feature flag is enabled' do + it 'shows deactivation email additional text field' do + expect(page).to have_field 'Additional text for deactivation email' + + page.within('.as-email') do + fill_in 'Additional text for deactivation email', with: 'So long and thanks for all the fish!' + click_button 'Save changes' + end + + expect(page).to have_content 'Application settings saved successfully' + expect(current_settings.deactivation_email_additional_text).to eq('So long and thanks for all the fish!') + end + end + + context 'when deactivation email additional text feature flag is disabled' do + let(:deactivation_email_additional_text_feature_flag) { false } + + it 'does not show deactivation email additional text field' do + expect(page).not_to have_field 'Additional text for deactivation email' + end + end + end + it 'change Help page' do new_support_url = 'http://example.com/help' new_documentation_url = 'https://docs.gitlab.com' @@ -861,7 +926,7 @@ RSpec.describe 'Admin updates settings', feature_category: :not_owned do context 'Nav bar' do it 'shows default help links in nav' do - default_support_url = "https://#{ApplicationHelper.promo_host}/getting-help/" + default_support_url = "https://#{ApplicationHelper.promo_host}/get-help/" visit root_dashboard_path diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 975af84969d..07db0750074 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Admin::Users', feature_category: :user_management do include Spec::Support::Helpers::Features::AdminUsersHelpers include Spec::Support::Helpers::ModalHelpers + include ListboxHelpers let_it_be(:user, reload: true) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } let_it_be(:current_user) { create(:admin) } @@ -608,8 +609,8 @@ RSpec.describe 'Admin::Users', feature_category: :user_management do def sort_by(option) page.within('.filtered-search-block') do - find('.gl-dropdown').click - find('.gl-dropdown-item', text: option).click + find('.gl-new-dropdown').click + select_listbox_item(option) end end end diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb index f1ee7a8fde7..8aecaab42c2 100644 --- a/spec/features/boards/issue_ordering_spec.rb +++ b/spec/features/boards/issue_ordering_spec.rb @@ -130,6 +130,41 @@ RSpec.describe 'Issue Boards', :js, feature_category: :team_planning do end end + context 'ordering in list using move to position' do + let(:move_to_position) { find('[data-testid="board-move-to-position"]') } + + before do + visit project_board_path(project, board) + wait_for_requests + end + + it 'moves to end of list' do + expect(all('.board-card').first).to have_content(issue3.title) + + page.within(find('.board:nth-child(2)')) do + first('.board-card').hover + move_to_position.click + + click_button 'Move to end of list' + end + + expect(all('.board-card').last).to have_content(issue3.title) + end + + it 'moves to start of list' do + expect(all('.board-card').last).to have_content(issue1.title) + + page.within(find('.board:nth-child(2)')) do + all('.board-card').last.hover + move_to_position.click + + click_button 'Move to start of list' + end + + expect(all('.board-card').first).to have_content(issue1.title) + end + end + context 'ordering when changing list' do let(:label2) { create(:label, project: project) } let!(:list2) { create(:list, board: board, label: label2, position: 1) } diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index 1b0695e4e60..d597c57ac1c 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -14,6 +14,10 @@ RSpec.describe 'Issue Boards new issue', :js, feature_category: :team_planning d let(:board_list_header) { first('[data-testid="board-list-header"]') } let(:project_select_dropdown) { find('[data-testid="project-select-dropdown"]') } + before do + stub_feature_flags(apollo_boards: false) + end + context 'authorized user' do before do project.add_maintainer(user) diff --git a/spec/features/boards/reload_boards_on_browser_back_spec.rb b/spec/features/boards/reload_boards_on_browser_back_spec.rb index 0ca680c5ed5..036daee7655 100644 --- a/spec/features/boards/reload_boards_on_browser_back_spec.rb +++ b/spec/features/boards/reload_boards_on_browser_back_spec.rb @@ -9,6 +9,8 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js, feat context 'authorized user' do before do + stub_feature_flags(apollo_boards: false) + project.add_maintainer(user) sign_in(user) diff --git a/spec/features/boards/sidebar_labels_in_namespaces_spec.rb b/spec/features/boards/sidebar_labels_in_namespaces_spec.rb index c3bb58df797..39485fe21a9 100644 --- a/spec/features/boards/sidebar_labels_in_namespaces_spec.rb +++ b/spec/features/boards/sidebar_labels_in_namespaces_spec.rb @@ -15,6 +15,8 @@ RSpec.describe 'Issue boards sidebar labels select', :js, feature_category: :tea let_it_be(:board_list) { create(:backlog_list, board: group_board) } before do + stub_feature_flags(apollo_boards: false) + load_board group_board_path(group, group_board) end diff --git a/spec/features/broadcast_messages_spec.rb b/spec/features/broadcast_messages_spec.rb index 8300cfce539..3e4289347e3 100644 --- a/spec/features/broadcast_messages_spec.rb +++ b/spec/features/broadcast_messages_spec.rb @@ -23,7 +23,8 @@ RSpec.describe 'Broadcast Messages', feature_category: :onboarding do end shared_examples 'a dismissable Broadcast Messages' do - it 'hides broadcast message after dismiss', :js do + it 'hides broadcast message after dismiss', :js, + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/390900' do visit root_path find('.js-dismiss-current-broadcast-notification').click @@ -31,7 +32,8 @@ RSpec.describe 'Broadcast Messages', feature_category: :onboarding do expect(page).not_to have_content 'SampleMessage' end - it 'broadcast message is still hidden after refresh', :js do + it 'broadcast message is still hidden after refresh', :js, + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391406' do visit root_path find('.js-dismiss-current-broadcast-notification').click diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 2c5b7d66e2f..b2a29c88b68 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Contributions Calendar', :js, feature_category: :users do +RSpec.describe 'Contributions Calendar', :js, feature_category: :user_profile do include MobileHelpers let(:user) { create(:user) } @@ -71,6 +71,7 @@ RSpec.describe 'Contributions Calendar', :js, feature_category: :users do end before do + stub_feature_flags(profile_tabs_vue: false) sign_in user end @@ -145,9 +146,9 @@ RSpec.describe 'Contributions Calendar', :js, feature_category: :users do describe '1 issue and 1 work item creation calendar activity' do before do - Issues::CreateService.new(project: contributed_project, current_user: user, params: issue_params, spam_params: nil).execute + Issues::CreateService.new(container: contributed_project, current_user: user, params: issue_params, spam_params: nil).execute WorkItems::CreateService.new( - project: contributed_project, + container: contributed_project, current_user: user, params: { title: 'new task' }, spam_params: nil @@ -189,7 +190,7 @@ RSpec.describe 'Contributions Calendar', :js, feature_category: :users do push_code_contribution travel_to(Date.yesterday) do - Issues::CreateService.new(project: contributed_project, current_user: user, params: issue_params, spam_params: nil).execute + Issues::CreateService.new(container: contributed_project, current_user: user, params: issue_params, spam_params: nil).execute end end include_context 'visit user page' diff --git a/spec/features/callouts/registration_enabled_spec.rb b/spec/features/callouts/registration_enabled_spec.rb index ac7b68876da..15c900592a1 100644 --- a/spec/features/callouts/registration_enabled_spec.rb +++ b/spec/features/callouts/registration_enabled_spec.rb @@ -50,7 +50,7 @@ RSpec.describe 'Registration enabled callout', feature_category: :authentication visit root_dashboard_path end - it 'does not display callout' do + it 'does not display callout', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391192' do expect(page).not_to have_content callout_title end end diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index e4d4375a138..eafe74f4b0b 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -24,7 +24,8 @@ RSpec.describe 'Commits', feature_category: :source_code_management do end context 'commit status is Generic Commit Status' do - let!(:status) { create(:generic_commit_status, pipeline: pipeline, ref: pipeline.ref) } + let(:stage) { create(:ci_stage, pipeline: pipeline, name: 'external') } + let!(:status) { create(:generic_commit_status, pipeline: pipeline, ref: pipeline.ref, ci_stage: stage) } before do project.add_reporter(user) diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index edb3dacc2cc..2f9b7bb7e0f 100644 --- a/spec/features/dashboard/activity_spec.rb +++ b/spec/features/dashboard/activity_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Dashboard > Activity', feature_category: :users do +RSpec.describe 'Dashboard > Activity', feature_category: :user_profile do let(:user) { create(:user) } before do @@ -12,9 +12,15 @@ RSpec.describe 'Dashboard > Activity', feature_category: :users do it_behaves_like 'a dashboard page with sidebar', :activity_dashboard_path, :activity context 'tabs' do - it 'shows Your Projects' do + it 'shows Your Activity' do visit activity_dashboard_path + expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Your activity') + end + + it 'shows Your Projects' do + visit activity_dashboard_path(filter: 'projects') + expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Your projects') end @@ -24,7 +30,7 @@ RSpec.describe 'Dashboard > Activity', feature_category: :users do expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Starred projects') end - it 'shows Followed Projects' do + it 'shows Followed Users' do visit activity_dashboard_path(filter: 'followed') expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Followed users') diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index 34f99765c29..c6e78c8b57c 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Tooltips on .timeago dates', :js, feature_category: :users do +RSpec.describe 'Tooltips on .timeago dates', :js, feature_category: :user_profile do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, name: 'test', namespace: user.namespace) } @@ -12,6 +12,10 @@ RSpec.describe 'Tooltips on .timeago dates', :js, feature_category: :users do project.add_maintainer(user) end + before do + stub_feature_flags(profile_tabs_vue: false) + end + context 'on the activity tab' do before do Event.create!(project: project, author_id: user.id, action: :joined, @@ -40,7 +44,7 @@ RSpec.describe 'Tooltips on .timeago dates', :js, feature_category: :users do wait_for_requests end - it 'has the datetime formated correctly' do + it 'has the datetime formated correctly', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/334481' do expect(page).to have_selector('[data-testid=snippet-created-at] .js-timeago', text: '1 day ago') page.find('[data-testid=snippet-created-at] .js-timeago').hover diff --git a/spec/features/dashboard/issues_filter_spec.rb b/spec/features/dashboard/issues_filter_spec.rb index d5f362d8449..a7734ed50c2 100644 --- a/spec/features/dashboard/issues_filter_spec.rb +++ b/spec/features/dashboard/issues_filter_spec.rb @@ -92,7 +92,7 @@ RSpec.describe 'Dashboard Issues filtering', :js, feature_category: :team_planni end end - def visit_issues(*args) - visit issues_dashboard_path(*args) + def visit_issues(...) + visit issues_dashboard_path(...) end end diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index ae375bd3e13..654cc9978a7 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -51,29 +51,26 @@ RSpec.describe 'Dashboard Issues', feature_category: :team_planning do describe 'new issue dropdown' do it 'shows projects only with issues feature enabled', :js do - click_button 'Toggle project select' + click_button _('Select project to create issue') - page.within('.select2-results') do + page.within('[data-testid="new-resource-dropdown"] [role="menu"]') do expect(page).to have_content(project.full_name) expect(page).not_to have_content(project_with_issues_disabled.full_name) end end it 'shows the new issue page', :js do - click_button 'Toggle project select' + click_button _('Select project to create issue') wait_for_requests project_path = "/#{project.full_path}" - project_json = { name: project.full_name, url: project_path }.to_json - # simulate selection, and prevent overlap by dropdown menu - first('.project-item-select', visible: false) - execute_script("$('.project-item-select').val('#{project_json}').trigger('change');") - find('#select2-drop-mask', visible: false) - execute_script("$('#select2-drop-mask').remove();") + page.within('[data-testid="new-resource-dropdown"]') do + find_button(project.full_name).click + end - find('.js-new-project-item-link').click + click_link format(_('New issue in %{project}'), project: project.name) expect(page).to have_current_path("#{project_path}/-/issues/new") diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb index a146a6987bc..34bab9dffd0 100644 --- a/spec/features/dashboard/merge_requests_spec.rb +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -36,11 +36,16 @@ RSpec.describe 'Dashboard Merge Requests', feature_category: :code_review_workfl end it 'shows projects only with merge requests feature enabled', :js do - click_button 'Toggle project select' + click_button 'Select project to create merge request' + wait_for_requests - page.within('.select2-results') do + page.within('[data-testid="new-resource-dropdown"]') do expect(page).to have_content(project.full_name) expect(page).not_to have_content(project_with_disabled_merge_requests.full_name) + + find_button(project.full_name).click + + expect(page).to have_link("New merge request in #{project.name}") end end end diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb index a9f23f90bb1..3b197bbf009 100644 --- a/spec/features/dashboard/milestones_spec.rb +++ b/spec/features/dashboard/milestones_spec.rb @@ -37,19 +37,13 @@ RSpec.describe 'Dashboard > Milestones', feature_category: :team_planning do describe 'new milestones dropdown', :js do it 'takes user to a new milestone page', :js do - click_button 'Toggle project select' + click_button 'Select project to create milestone' - page.within('.select2-results') do - first('.select2-result-label').click + page.within('[data-testid="new-resource-dropdown"]') do + click_button group.name + click_link "New milestone in #{group.name}" end - a_el = find('.js-new-project-item-link') - - expect(a_el).to have_content('New Milestone in ') - expect(a_el).to have_no_content('New New Milestone in ') - - a_el.click - expect(page).to have_current_path(new_group_milestone_path(group), ignore_query: true) end end diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb index 5bf1566fa31..c4dc78bf45b 100644 --- a/spec/features/dashboard/project_member_activity_index_spec.rb +++ b/spec/features/dashboard/project_member_activity_index_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Project member activity', :js, feature_category: :users do +RSpec.describe 'Project member activity', :js, feature_category: :user_profile do let(:user) { create(:user) } let(:project) { create(:project, :public, name: 'x', namespace: user.namespace) } diff --git a/spec/features/dashboard/root_explore_spec.rb b/spec/features/dashboard/root_explore_spec.rb index c0d1f0de1f5..a232ebec68e 100644 --- a/spec/features/dashboard/root_explore_spec.rb +++ b/spec/features/dashboard/root_explore_spec.rb @@ -39,17 +39,5 @@ RSpec.describe 'Root explore', feature_category: :not_owned do expect(has_language_dropdown?).to eq(true) end - - context 'with project_language_search ff disabled' do - before do - stub_feature_flags(project_language_search: false) - end - - it 'is conditionally rendered' do - visit explore_projects_path - - expect(has_language_dropdown?).to eq(false) - end - end end end diff --git a/spec/features/explore/topics_spec.rb b/spec/features/explore/topics_spec.rb index b5787a2dba8..dcccaea8c80 100644 --- a/spec/features/explore/topics_spec.rb +++ b/spec/features/explore/topics_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Explore Topics', feature_category: :users do +RSpec.describe 'Explore Topics', feature_category: :user_profile do context 'when no topics exist' do it 'renders empty message', :aggregate_failures do visit topics_explore_projects_path diff --git a/spec/features/explore/user_explores_projects_spec.rb b/spec/features/explore/user_explores_projects_spec.rb index f54a51c9ac9..14fddf5d84c 100644 --- a/spec/features/explore/user_explores_projects_spec.rb +++ b/spec/features/explore/user_explores_projects_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User explores projects', feature_category: :users do +RSpec.describe 'User explores projects', feature_category: :user_profile do context 'when some projects exist' do let_it_be(:archived_project) { create(:project, :archived) } let_it_be(:internal_project) { create(:project, :internal) } diff --git a/spec/features/file_uploads/user_avatar_spec.rb b/spec/features/file_uploads/user_avatar_spec.rb index 06501e09866..062c47d5310 100644 --- a/spec/features/file_uploads/user_avatar_spec.rb +++ b/spec/features/file_uploads/user_avatar_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Upload a user avatar', :js, feature_category: :users do +RSpec.describe 'Upload a user avatar', :js, feature_category: :user_profile do let_it_be(:user, reload: true) { create(:user) } let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') } diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb index 11ec38f637b..c451a97bed5 100644 --- a/spec/features/groups/board_spec.rb +++ b/spec/features/groups/board_spec.rb @@ -14,6 +14,8 @@ RSpec.describe 'Group Boards', feature_category: :team_planning do let_it_be(:project) { create(:project_empty_repo, group: group) } before do + stub_feature_flags(apollo_boards: false) + group.add_maintainer(user) sign_in(user) @@ -60,6 +62,8 @@ RSpec.describe 'Group Boards', feature_category: :team_planning do let_it_be(:issue2) { create(:issue, title: 'issue2', project: project2) } before do + stub_feature_flags(apollo_boards: false) + project1.add_guest(user) project2.add_reporter(user) diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb index 3e565dd8eab..d876a5804bd 100644 --- a/spec/features/groups/clusters/user_spec.rb +++ b/spec/features/groups/clusters/user_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User Cluster', :js, feature_category: :users do +RSpec.describe 'User Cluster', :js, feature_category: :user_profile do include GoogleApi::CloudPlatformHelpers let(:group) { create(:group) } diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb index a37c40f50e0..e123e223ae5 100644 --- a/spec/features/groups/empty_states_spec.rb +++ b/spec/features/groups/empty_states_spec.rb @@ -98,13 +98,9 @@ RSpec.describe 'Group empty states', feature_category: :subgroups do end it "the new #{issuable_name} button opens a project dropdown" do - click_button 'Toggle project select' + click_button "Select project to create #{issuable_name}" - if issuable == :issue - expect(page).to have_button project.name - else - expect(page).to have_selector('.ajax-project-dropdown') - end + expect(page).to have_button project.name end end end diff --git a/spec/features/groups/group_runners_spec.rb b/spec/features/groups/group_runners_spec.rb index ab53ef7c470..ae757e04716 100644 --- a/spec/features/groups/group_runners_spec.rb +++ b/spec/features/groups/group_runners_spec.rb @@ -203,15 +203,24 @@ RSpec.describe "Group Runners", feature_category: :runner_fleet do end describe "Group runner show page", :js do - let!(:group_runner) do + let_it_be(:group_runner) do create(:ci_runner, :group, groups: [group], description: 'runner-foo') end - it 'user views runner details' do + let_it_be(:group_runner_job) { create(:ci_build, runner: group_runner) } + + before do visit group_runner_path(group, group_runner) + end + it 'user views runner details' do expect(page).to have_content "#{s_('Runners|Description')} runner-foo" end + + it_behaves_like 'shows runner jobs tab' do + let(:job_count) { '1' } + let(:job) { group_runner_job } + end end describe "Group runner edit page", :js do diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb index fe1b0909c06..5510e73ef0f 100644 --- a/spec/features/groups/group_settings_spec.rb +++ b/spec/features/groups/group_settings_spec.rb @@ -162,7 +162,7 @@ RSpec.describe 'Edit group settings', feature_category: :subgroups do page.within(confirm_modal) do expect(page).to have_text "You are going to transfer #{selected_group.name} to another namespace. Are you ABSOLUTELY sure?" - fill_in 'confirm_name_input', with: selected_group.name + fill_in 'confirm_name_input', with: selected_group.full_path click_button 'Confirm' end diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb index 8a3401d0572..bbb7d322b9a 100644 --- a/spec/features/groups/merge_requests_spec.rb +++ b/spec/features/groups/merge_requests_spec.rb @@ -77,9 +77,9 @@ RSpec.describe 'Group merge requests page', feature_category: :code_review_workf end it 'shows projects only with merge requests feature enabled', :js do - find('.js-new-project-item-link').click + click_button 'Select project to create merge request' - page.within('.select2-results') do + page.within('[data-testid="new-resource-dropdown"]') do expect(page).to have_content(project.name_with_namespace) expect(page).not_to have_content(project_with_merge_requests_disabled.name_with_namespace) end @@ -95,7 +95,7 @@ RSpec.describe 'Group merge requests page', feature_category: :code_review_workf visit path expect(page).to have_selector('.empty-state') - expect(page).to have_link('Select project to create merge request') + expect(page).to have_button('Select project to create merge request') expect(page).to have_selector('.issues-filters') end @@ -105,7 +105,7 @@ RSpec.describe 'Group merge requests page', feature_category: :code_review_workf visit path expect(page).to have_selector('.empty-state') - expect(page).to have_link('Select project to create merge request') + expect(page).to have_button('Select project to create merge request') expect(page).to have_selector('.issues-filters') end end diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb index 60aad8452ce..80e2dcd5174 100644 --- a/spec/features/groups/settings/packages_and_registries_spec.rb +++ b/spec/features/groups/settings/packages_and_registries_spec.rb @@ -46,7 +46,7 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package it 'has a page title set' do visit_settings_page - expect(page).to have_title _('Package and registry settings') + expect(page).to have_title _('Packages and registries settings') end it 'sidebar menu is open' do diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index c0af6080d0f..5cab79b40cf 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Group show page', feature_category: :subgroups do + include Spec::Support::Helpers::Features::InviteMembersModalHelper + let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } @@ -37,6 +39,16 @@ RSpec.describe 'Group show page', feature_category: :subgroups do expect(page).to have_content('Collaborate with your team') page.within(find('[data-testid="invite-members-banner"]')) do + click_button('Invite your colleagues') + end + + page.within(invite_modal_selector) do + expect(page).to have_content("You're inviting members to the #{group.name} group") + + click_button('Cancel') + end + + page.within(find('[data-testid="invite-members-banner"]')) do find('[data-testid="close-icon"]').click end @@ -73,7 +85,7 @@ RSpec.describe 'Group show page', feature_category: :subgroups do end end - context 'subgroups and projects empty state', :js do + context 'with subgroups and projects empty state', :js do context 'when user has permissions to create new subgroups or projects' do before do group.add_owner(user) @@ -82,22 +94,19 @@ RSpec.describe 'Group show page', feature_category: :subgroups do end it 'shows `Create new subgroup` link' do - expect(page).to have_link( - s_('GroupsEmptyState|Create new subgroup'), - href: new_group_path(parent_id: group.id, anchor: 'create-group-pane') - ) + link = new_group_path(parent_id: group.id, anchor: 'create-group-pane') + + expect(page).to have_link(s_('GroupsEmptyState|Create new subgroup'), href: link) end it 'shows `Create new project` link' do - expect(page).to have_link( - s_('GroupsEmptyState|Create new project'), - href: new_project_path(namespace_id: group.id) - ) + expect(page) + .to have_link(s_('GroupsEmptyState|Create new project'), href: new_project_path(namespace_id: group.id)) end end end - context 'visibility warning popover' do + context 'with visibility warning popover' do let_it_be(:public_project) { create(:project, :public) } shared_examples 'it shows warning popover' do @@ -145,23 +154,22 @@ RSpec.describe 'Group show page', feature_category: :subgroups do end it 'does not show `Create new subgroup` link' do - expect(page).not_to have_link( - s_('GroupsEmptyState|Create new subgroup'), - href: new_group_path(parent_id: group.id) - ) + expect(page) + .not_to have_link(s_('GroupsEmptyState|Create new subgroup'), href: new_group_path(parent_id: group.id)) end it 'does not show `Create new project` link' do - expect(page).not_to have_link( - s_('GroupsEmptyState|Create new project'), - href: new_project_path(namespace_id: group.id) - ) + expect(page) + .not_to have_link(s_('GroupsEmptyState|Create new project'), href: new_project_path(namespace_id: group.id)) end it 'shows empty state' do + content = s_('GroupsEmptyState|You do not have necessary permissions to create a subgroup ' \ + 'or project in this group. Please contact an owner of this group to create a ' \ + 'new subgroup or project.') + expect(page).to have_content(s_('GroupsEmptyState|No subgroups or projects.')) - expect(page).to have_content(s_('GroupsEmptyState|You do not have necessary permissions to create a subgroup' \ - ' or project in this group. Please contact an owner of this group to create a new subgroup or project.')) + expect(page).to have_content(content) end end end @@ -198,7 +206,7 @@ RSpec.describe 'Group show page', feature_category: :subgroups do end end - context 'subgroup support' do + context 'with subgroup support' do let_it_be(:restricted_group) do create(:group, subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS) end @@ -255,7 +263,7 @@ RSpec.describe 'Group show page', feature_category: :subgroups do end end - context 'notification button', :js do + context 'for notification button', :js do before do group.add_maintainer(user) sign_in(user) @@ -276,7 +284,7 @@ RSpec.describe 'Group show page', feature_category: :subgroups do end end - context 'page og:description' do + context 'for page og:description' do before do group.update!(description: '**Lorem** _ipsum_ dolor sit [amet](https://example.com)') group.add_maintainer(user) @@ -287,7 +295,7 @@ RSpec.describe 'Group show page', feature_category: :subgroups do it_behaves_like 'page meta description', 'Lorem ipsum dolor sit amet' end - context 'structured schema markup' do + context 'for structured schema markup' do let_it_be(:group) { create(:group, :public, :with_avatar, description: 'foo') } let_it_be(:subgroup) { create(:group, :public, :with_avatar, parent: group, description: 'bar') } let_it_be_with_reload(:project) { create(:project, :public, :with_avatar, namespace: group, description: 'foo') } diff --git a/spec/features/ide/clientside_preview_csp_spec.rb b/spec/features/ide/clientside_preview_csp_spec.rb deleted file mode 100644 index 04427a5c294..00000000000 --- a/spec/features/ide/clientside_preview_csp_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'IDE Clientside Preview CSP', feature_category: :web_ide do - let_it_be(:user) { create(:user) } - - shared_context 'disable feature' do - before do - stub_application_setting(web_ide_clientside_preview_enabled: false) - end - end - - it_behaves_like 'setting CSP', 'frame-src' do - let(:allowlisted_url) { 'https://sandbox.gitlab-static.test' } - let(:extended_controller_class) { IdeController } - - subject do - visit ide_path - - response_headers['Content-Security-Policy'] - end - - before do - stub_application_setting(web_ide_clientside_preview_enabled: true) - stub_application_setting(web_ide_clientside_preview_bundler_url: allowlisted_url) - - sign_in(user) - end - end -end diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb index e1167285464..709919d0196 100644 --- a/spec/features/incidents/incident_details_spec.rb +++ b/spec/features/incidents/incident_details_spec.rb @@ -3,11 +3,16 @@ require 'spec_helper' RSpec.describe 'Incident details', :js, feature_category: :incident_management do + include MergeRequestDiffHelpers + let_it_be(:project) { create(:project) } let_it_be(:developer) { create(:user) } let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') } let_it_be(:issue) { create(:issue, project: project, author: developer, description: 'Issue description') } let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: incident) } + let_it_be(:confidential_incident) do + create(:incident, confidential: true, project: project, author: developer, description: 'Confidential') + end before_all do project.add_developer(developer) @@ -19,7 +24,7 @@ RSpec.describe 'Incident details', :js, feature_category: :incident_management d context 'when a developer+ displays the incident' do before do - visit project_issues_incident_path(project, incident) + visit incident_project_issues_path(project, incident) wait_for_requests end @@ -98,7 +103,7 @@ RSpec.describe 'Incident details', :js, feature_category: :incident_management d page.within('[data-testid="issuable-form"]') do click_button 'Issue' - click_button 'Incident' + find('[data-testid="issue-type-list-item"]', text: 'Incident').click click_button 'Save changes' wait_for_requests @@ -108,7 +113,7 @@ RSpec.describe 'Incident details', :js, feature_category: :incident_management d end it 'routes the user to the issue details page when the `issue_type` is set to issue' do - visit project_issues_incident_path(project, incident) + visit incident_project_issues_path(project, incident) wait_for_requests project_path = "/#{project.full_path}" @@ -117,7 +122,7 @@ RSpec.describe 'Incident details', :js, feature_category: :incident_management d page.within('[data-testid="issuable-form"]') do click_button 'Incident' - click_button 'Issue' + find('[data-testid="issue-type-list-item"]', text: 'Issue').click click_button 'Save changes' wait_for_requests @@ -125,4 +130,12 @@ RSpec.describe 'Incident details', :js, feature_category: :incident_management d expect(page).to have_current_path("#{project_path}/-/issues/#{incident.iid}") end end + + it 'displays the confidential badge on the sticky header when the incident is confidential' do + visit incident_project_issues_path(project, confidential_incident) + wait_for_requests + + sticky_header = find_by_scrolling('[data-testid=issue-sticky-header]') + expect(sticky_header.find('[data-testid=confidential]')).to be_present + end end diff --git a/spec/features/incidents/incident_timeline_events_spec.rb b/spec/features/incidents/incident_timeline_events_spec.rb index 3a73ea50247..7404ac64cc9 100644 --- a/spec/features/incidents/incident_timeline_events_spec.rb +++ b/spec/features/incidents/incident_timeline_events_spec.rb @@ -3,99 +3,98 @@ require 'spec_helper' RSpec.describe 'Incident timeline events', :js, feature_category: :incident_management do + include ListboxHelpers + let_it_be(:project) { create(:project) } - let_it_be(:developer) { create(:user) } + let_it_be(:user) { create(:user, developer_projects: [project]) } let_it_be(:incident) { create(:incident, project: project) } - before_all do - project.add_developer(developer) - end - - before do - sign_in(developer) - - visit project_issues_incident_path(project, incident) - wait_for_requests - click_link s_('Incident|Timeline') - end - - context 'when add event is clicked' do - it 'submits event data when save is clicked' do - click_button s_('Incident|Add new timeline event') - - expect(page).to have_selector('.common-note-form') - - fill_in _('Description'), with: 'Event note goes here' - fill_in 'timeline-input-hours', with: '07' - fill_in 'timeline-input-minutes', with: '25' - - click_button _('Save') + shared_examples 'add, edit, and delete timeline events' do + it 'submits event data on save' do + # Add event + click_button(s_('Incident|Add new timeline event')) + complete_form('Event note goes here', '07', '25') expect(page).to have_selector('.incident-timeline-events') - page.within '.timeline-event-note' do expect(page).to have_content('Event note goes here') expect(page).to have_content('07:25') end - end - end - context 'when edit is clicked' do - before do - click_button 'Add new timeline event' - fill_in 'Description', with: 'Event note to edit' - click_button _('Save') - end + # Edit event + trigger_dropdown_action(_('Edit')) + complete_form('Edited event note goes here', '08', '30') - it 'shows the confirmation modal and edits the event' do - click_button _('More actions') + page.within '.timeline-event-note' do + expect(page).to have_content('Edited event note goes here') + expect(page).to have_content('08:30') + end - page.within '.gl-dropdown-contents' do - expect(page).to have_content(_('Edit')) - page.find('.gl-dropdown-item-text-primary', text: _('Edit')).click + # Delete event + trigger_dropdown_action(_('Delete')) + + page.within '.modal' do + expect(page).to have_content(s_('Incident|Delete event')) end - expect(page).to have_selector('.common-note-form') + click_button s_('Incident|Delete event') + wait_for_requests + + expect(page).to have_content(s_('Incident|No timeline items have been added yet.')) + end + + it 'submits event data on save with feature flag on' do + stub_feature_flags(incident_event_tags: true) - fill_in _('Description'), with: 'Event note goes here' - fill_in 'timeline-input-hours', with: '07' - fill_in 'timeline-input-minutes', with: '25' + # Add event + click_button(s_('Incident|Add new timeline event')) - click_button _('Save') + select_from_listbox('Start time', from: 'Select tags') - wait_for_requests + complete_form('Event note goes here', '07', '25') + expect(page).to have_selector('.incident-timeline-events') page.within '.timeline-event-note' do expect(page).to have_content('Event note goes here') expect(page).to have_content('07:25') + expect(page).to have_content('Start time') end - end - end - context 'when delete is clicked' do - before do - click_button s_('Incident|Add new timeline event') - fill_in _('Description'), with: 'Event note to delete' - click_button _('Save') - end + # Edit event + trigger_dropdown_action(_('Edit')) - it 'shows the confirmation modal and deletes the event' do - click_button _('More actions') + select_from_listbox('Start time', from: 'Start time') - page.within '.gl-dropdown-contents' do - expect(page).to have_content(_('Delete')) - page.find('.gl-dropdown-item-text-primary', text: 'Delete').click - end + complete_form('Edited event note goes here', '08', '30') - page.within '.modal' do - expect(page).to have_content(s_('Incident|Delete event')) + page.within '.timeline-event-note' do + expect(page).to have_content('Edited event note goes here') + expect(page).to have_content('08:30') + expect(page).not_to have_content('Start time') end + end - click_button s_('Incident|Delete event') + private + def complete_form(title, hours, minutes) + fill_in _('Description'), with: title + fill_in 'timeline-input-hours', with: hours + fill_in 'timeline-input-minutes', with: minutes + + click_button _('Save') wait_for_requests + end - expect(page).to have_content(s_('Incident|No timeline items have been added yet.')) + def trigger_dropdown_action(text) + click_button _('More actions') + + page.within '.gl-dropdown-contents' do + page.find('.gl-dropdown-item', text: text).click + end end end + + it_behaves_like 'for each incident details route', + 'add, edit, and delete timeline events', + tab_text: s_('Incident|Timeline') end diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb index 49041d187dd..0265960fce7 100644 --- a/spec/features/incidents/user_views_incident_spec.rb +++ b/spec/features/incidents/user_views_incident_spec.rb @@ -19,7 +19,7 @@ RSpec.describe "User views incident", feature_category: :incident_management do before do sign_in(user) - visit(project_issues_incident_path(project, incident)) + visit(incident_project_issues_path(project, incident)) end specify do @@ -75,7 +75,7 @@ RSpec.describe "User views incident", feature_category: :incident_management do describe 'user status' do context 'when showing status of the author of the incident' do - subject { visit(project_issues_incident_path(project, incident)) } + subject { visit(incident_project_issues_path(project, incident)) } it_behaves_like 'showing user status' do let(:user_with_status) { user } diff --git a/spec/features/issuables/shortcuts_issuable_spec.rb b/spec/features/issuables/shortcuts_issuable_spec.rb index 0190111b2f0..06387c14ee2 100644 --- a/spec/features/issuables/shortcuts_issuable_spec.rb +++ b/spec/features/issuables/shortcuts_issuable_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Blob shortcuts', :js, feature_category: :team_planning do before do project.add_developer(user) + sign_in(user) end diff --git a/spec/features/issuables/sorting_list_spec.rb b/spec/features/issuables/sorting_list_spec.rb index b5362267309..9045124cc8c 100644 --- a/spec/features/issuables/sorting_list_spec.rb +++ b/spec/features/issuables/sorting_list_spec.rb @@ -2,6 +2,8 @@ require 'spec_helper' RSpec.describe 'Sort Issuable List', feature_category: :team_planning do + include ListboxHelpers + let(:project) { create(:project, :public) } let(:first_created_issuable) { issuables.order_created_asc.first } @@ -94,8 +96,7 @@ RSpec.describe 'Sort Issuable List', feature_category: :team_planning do it 'supports sorting in asc and desc order' do visit_merge_requests_with_state(project, 'open') - click_button('Created date') - find('.dropdown-item', text: 'Updated date').click + select_from_listbox('Updated date', from: 'Created date') expect(first_merge_request).to include(last_updated_issuable.title) expect(last_merge_request).to include(first_updated_issuable.title) @@ -209,7 +210,7 @@ RSpec.describe 'Sort Issuable List', feature_category: :team_planning do end def selected_sort_order - find('.filter-dropdown-container .dropdown button').text.downcase + find('.filter-dropdown-container .gl-new-dropdown button').text.downcase end def visit_merge_requests_with_state(project, state) diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 2898c97c2e9..585740f7782 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -353,14 +353,14 @@ RSpec.describe 'New/edit issue', :js, feature_category: :team_planning do expect(find('#issue_description').value).to match('description from query parameter') end - it 'fills the description from the issuable_template query parameter' do + it 'fills the description from the issuable_template query parameter', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/388728' do visit new_project_issue_path(project, issuable_template: 'test_template') wait_for_requests expect(find('#issue_description').value).to match('description from template') end - it 'fills the description from the issuable_template and issue[description] query parameters' do + it 'fills the description from the issuable_template and issue[description] query parameters', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/388728' do visit new_project_issue_path(project, issuable_template: 'test_template', issue: { description: 'description from query parameter' }) wait_for_requests diff --git a/spec/features/issues/incident_issue_spec.rb b/spec/features/issues/incident_issue_spec.rb index 2fba1ca9141..41bbd79202f 100644 --- a/spec/features/issues/incident_issue_spec.rb +++ b/spec/features/issues/incident_issue_spec.rb @@ -29,7 +29,7 @@ RSpec.describe 'Incident Detail', :js, feature_category: :team_planning do project.add_developer(user) sign_in(user) - visit project_issues_incident_path(project, incident) + visit incident_project_issues_path(project, incident) wait_for_requests end diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb index 44e9bbad1ba..20a69c61871 100644 --- a/spec/features/issues/issue_detail_spec.rb +++ b/spec/features/issues/issue_detail_spec.rb @@ -130,7 +130,7 @@ RSpec.describe 'Issue Detail', :js, feature_category: :team_planning do page.within('[data-testid="issuable-form"]') do update_type_select('Issue', 'Incident') - expect(page).to have_current_path(project_issues_incident_path(project, issue)) + expect(page).to have_current_path(incident_project_issues_path(project, issue)) end end end @@ -170,7 +170,7 @@ RSpec.describe 'Issue Detail', :js, feature_category: :team_planning do def update_type_select(from, to) click_button from - click_button to + find('[data-testid="issue-type-list-item"]', text: to).click click_button 'Save changes' wait_for_requests diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index fa72acad8c6..686074f7412 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Issue Sidebar', feature_category: :team_planning do include MobileHelpers + include Spec::Support::Helpers::Features::InviteMembersModalHelper let_it_be(:group) { create(:group, :nested) } let_it_be(:project) { create(:project, :public, namespace: group) } @@ -120,11 +121,13 @@ RSpec.describe 'Issue Sidebar', feature_category: :team_planning do expect(page).to have_link('Invite members') expect(page).to have_selector('[data-track-action="click_invite_members"]') expect(page).to have_selector('[data-track-label="edit_assignee"]') - end - click_link 'Invite members' + click_link 'Invite members' + end - expect(page).to have_content("You're inviting members to the") + page.within invite_modal_selector do + expect(page).to have_content("You're inviting members to the #{project.name} project") + end end end @@ -208,7 +211,7 @@ RSpec.describe 'Issue Sidebar', feature_category: :team_planning do visit_issue(project, issue) end - context 'sidebar', :js do + context 'for sidebar', :js do it 'changes size when the screen size is smaller' do sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' # Resize the window @@ -227,25 +230,25 @@ RSpec.describe 'Issue Sidebar', feature_category: :team_planning do end end - context 'editing issue milestone', :js do + context 'for editing issue milestone', :js do it_behaves_like 'milestone sidebar widget' end - context 'editing issue due date', :js do + context 'for editing issue due date', :js do it_behaves_like 'date sidebar widget' end - context 'editing issue labels', :js do + context 'for editing issue labels', :js do it_behaves_like 'labels sidebar widget' end - context 'escalation status', :js do + context 'for escalation status', :js do it 'is not available for default issue type' do expect(page).not_to have_selector('.block.escalation-status') end end - context 'interacting with collapsed sidebar', :js do + context 'when interacting with collapsed sidebar', :js do collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded' confidentiality_sidebar_block = '.block.confidentiality' @@ -300,7 +303,7 @@ RSpec.describe 'Issue Sidebar', feature_category: :team_planning do expect(page).not_to have_selector('.block.labels .js-sidebar-dropdown-toggle') end - context 'sidebar', :js do + context 'for sidebar', :js do it 'finds issue copy forwarding email' do expect( find('[data-testid="copy-forward-email"]').text @@ -308,7 +311,7 @@ RSpec.describe 'Issue Sidebar', feature_category: :team_planning do end end - context 'interacting with collapsed sidebar', :js do + context 'when interacting with collapsed sidebar', :js do collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded' lock_sidebar_block = '.block.lock' @@ -334,7 +337,7 @@ RSpec.describe 'Issue Sidebar', feature_category: :team_planning do end context 'when not signed in' do - context 'sidebar', :js do + context 'for sidebar', :js do before do visit_issue(project, issue) end diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index 72c6e288168..ea68f2266b3 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -23,7 +23,7 @@ RSpec.describe 'issue move to another project', feature_category: :team_planning end it 'moving issue to another project not allowed' do - expect(page).to have_no_selector('.js-sidebar-move-issue-block') + expect(page).to have_no_selector('.js-issuable-move-block') end end @@ -42,10 +42,10 @@ RSpec.describe 'issue move to another project', feature_category: :team_planning end it 'moving issue to another project', :js do - find('.js-move-issue').click + click_button _('Move issue') wait_for_requests - all('.js-move-issue-dropdown-item')[0].click - find('.js-move-issue-confirmation-button').click + all('.gl-dropdown-item')[0].click + click_button _('Move') expect(page).to have_content("Text with #{cross_reference}#{mr.to_reference}") expect(page).to have_content("moved from #{cross_reference}#{issue.to_reference}") @@ -56,11 +56,11 @@ RSpec.describe 'issue move to another project', feature_category: :team_planning it 'searching project dropdown', :js do new_project_search.add_reporter(user) - find('.js-move-issue').click + click_button _('Move issue') wait_for_requests - page.within '.js-sidebar-move-issue-block' do - fill_in('sidebar-move-issue-dropdown-search', with: new_project_search.name) + page.within '.js-issuable-move-block' do + fill_in(_('Search project'), with: new_project_search.name) expect(page).to have_content(new_project_search.name) expect(page).not_to have_content(new_project.name) @@ -76,10 +76,10 @@ RSpec.describe 'issue move to another project', feature_category: :team_planning end it 'browsing projects in projects select' do - find('.js-move-issue').click + click_button _('Move issue') wait_for_requests - page.within '.js-sidebar-move-issue-block' do + page.within '.js-issuable-move-block' do expect(page).to have_content new_project.full_name end end @@ -115,10 +115,10 @@ RSpec.describe 'issue move to another project', feature_category: :team_planning visit issue_path(service_desk_issue) - find('.js-move-issue').click + click_button _('Move issue') wait_for_requests - find('.js-move-issue-dropdown-item', text: project_title).click - find('.js-move-issue-confirmation-button').click + find('.gl-dropdown-item', text: project_title).click + click_button _('Move') end it 'shows an alert after being moved' do diff --git a/spec/features/issues/spam_akismet_issue_creation_spec.rb b/spec/features/issues/spam_akismet_issue_creation_spec.rb index 7c62f141105..176c26c6d8a 100644 --- a/spec/features/issues/spam_akismet_issue_creation_spec.rb +++ b/spec/features/issues/spam_akismet_issue_creation_spec.rb @@ -108,20 +108,20 @@ RSpec.describe 'Spam detection on issue creation', :js, feature_category: :team_ end end - shared_context 'when allow_possible_spam feature flag is true' do + shared_context 'when allow_possible_spam application setting is true' do before do - stub_feature_flags(allow_possible_spam: true) + stub_application_setting(allow_possible_spam: true) end end - shared_context 'when allow_possible_spam feature flag is false' do + shared_context 'when allow_possible_spam application setting is false' do before do - stub_feature_flags(allow_possible_spam: false) + stub_application_setting(allow_possible_spam: false) end end describe 'spam handling' do - # verdict, spam_flagged, captcha_enabled, allow_possible_spam_flag, creates_spam_log + # verdict, spam_flagged, captcha_enabled, allow_possible_spam, creates_spam_log # TODO: Add example for BLOCK_USER verdict when we add support for testing SpamCheck - see https://gitlab.com/groups/gitlab-org/-/epics/5527#lacking-coverage-for-spamcheck-vs-akismet # DISALLOW, true, false, false, true # CONDITIONAL_ALLOW, true, true, false, true @@ -133,7 +133,7 @@ RSpec.describe 'Spam detection on issue creation', :js, feature_category: :team_ context 'DISALLOW: spam_flagged=true, captcha_enabled=true, allow_possible_spam=true' do include_context 'when spammable is identified as possible spam' include_context 'when CAPTCHA is enabled' - include_context 'when allow_possible_spam feature flag is true' + include_context 'when allow_possible_spam application setting is true' it_behaves_like 'allows issue creation without CAPTCHA' it_behaves_like 'creates a spam_log record' @@ -142,7 +142,7 @@ RSpec.describe 'Spam detection on issue creation', :js, feature_category: :team_ context 'CONDITIONAL_ALLOW: spam_flagged=true, captcha_enabled=true, allow_possible_spam=false' do include_context 'when spammable is identified as possible spam' include_context 'when CAPTCHA is enabled' - include_context 'when allow_possible_spam feature flag is false' + include_context 'when allow_possible_spam application setting is false' it_behaves_like 'allows issue creation with CAPTCHA' it_behaves_like 'creates a spam_log record' @@ -151,7 +151,7 @@ RSpec.describe 'Spam detection on issue creation', :js, feature_category: :team_ context 'OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM: spam_flagged=true, captcha_enabled=true, allow_possible_spam=true' do include_context 'when spammable is identified as possible spam' include_context 'when CAPTCHA is enabled' - include_context 'when allow_possible_spam feature flag is true' + include_context 'when allow_possible_spam application setting is true' it_behaves_like 'allows issue creation without CAPTCHA' it_behaves_like 'creates a spam_log record' @@ -160,7 +160,7 @@ RSpec.describe 'Spam detection on issue creation', :js, feature_category: :team_ context 'OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM: spam_flagged=true, captcha_enabled=false, allow_possible_spam=true' do include_context 'when spammable is identified as possible spam' include_context 'when CAPTCHA is not enabled' - include_context 'when allow_possible_spam feature flag is true' + include_context 'when allow_possible_spam application setting is true' it_behaves_like 'allows issue creation without CAPTCHA' it_behaves_like 'creates a spam_log record' @@ -169,7 +169,7 @@ RSpec.describe 'Spam detection on issue creation', :js, feature_category: :team_ context 'ALLOW: spam_flagged=false, captcha_enabled=true, allow_possible_spam=false' do include_context 'when spammable is not identified as possible spam' include_context 'when CAPTCHA is not enabled' - include_context 'when allow_possible_spam feature flag is false' + include_context 'when allow_possible_spam application setting is false' it_behaves_like 'allows issue creation without CAPTCHA' it_behaves_like 'does not create a spam_log record' diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb index fc48bc4baf9..5696bde4069 100644 --- a/spec/features/issues/user_bulk_edits_issues_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_spec.rb @@ -46,7 +46,7 @@ RSpec.describe 'Multiple issue updating from issues#index', :js, feature_categor click_button 'Edit issues' check 'Select all' click_update_assignee_button - click_link user.username + click_button user.username click_update_issues_button @@ -64,7 +64,7 @@ RSpec.describe 'Multiple issue updating from issues#index', :js, feature_categor click_button 'Edit issues' check 'Select all' click_update_assignee_button - click_link 'Unassigned' + click_button 'Unassigned' click_update_issues_button expect(find('.issue:first-of-type')).not_to have_link "Assigned to #{user.name}" diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb index df039493cec..c5d0791dc57 100644 --- a/spec/features/issues/user_creates_issue_spec.rb +++ b/spec/features/issues/user_creates_issue_spec.rb @@ -157,15 +157,10 @@ RSpec.describe "User creates issue", feature_category: :team_planning do end end - context 'form filled by URL parameters' do + context 'form filled by URL parameters', :use_null_store_as_repository_cache do let(:project) { create(:project, :public, :repository) } before do - # With multistore feature flags enabled (using an actual Redis store instead of NullStore), - # it somehow writes an invalid content to Redis and the specs would fail. - stub_feature_flags(use_primary_and_secondary_stores_for_repository_cache: false) - stub_feature_flags(use_primary_store_as_default_for_repository_cache: false) - project.repository.create_file( user, '.gitlab/issue_templates/bug.md', diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb index 19b2633969d..bf2af918f39 100644 --- a/spec/features/issues/user_edits_issue_spec.rb +++ b/spec/features/issues/user_edits_issue_spec.rb @@ -26,7 +26,7 @@ RSpec.describe "Issues > User edits issue", :js, feature_category: :team_plannin visit edit_project_issue_path(project, issue) end - it "previews content" do + it "previews content", quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391757' do form = first(".gfm-form") page.within(form) do @@ -433,7 +433,7 @@ RSpec.describe "Issues > User edits issue", :js, feature_category: :team_plannin issue.save! end - it 'shows milestone text' do + it 'shows milestone text', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/389287' do sign_out(:user) sign_in(guest) diff --git a/spec/features/jira_connect/branches_spec.rb b/spec/features/jira_connect/branches_spec.rb index 8cf07f2ade2..c90c0d2dda9 100644 --- a/spec/features/jira_connect/branches_spec.rb +++ b/spec/features/jira_connect/branches_spec.rb @@ -20,8 +20,8 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ sign_in(alice) end - def within_dropdown(&block) - within('.dropdown-menu', &block) + def within_project_listbox(&block) + within('#project-select', &block) end it 'select project and branch and submit the form' do @@ -35,16 +35,16 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ click_on 'Select a project' - within_dropdown do - expect(page).to have_text('Alice / foo') - expect(page).to have_text('Alice / bar') - expect(page).not_to have_text('Bob /') + within_project_listbox do + expect_listbox_item('Alice / foo') + expect_listbox_item('Alice / bar') + expect_no_listbox_item('Bob /') fill_in 'Search', with: 'foo' - expect(page).not_to have_text('Alice / bar') + expect_no_listbox_item('Alice / bar') - find('span', text: 'Alice / foo', match: :first).click + select_listbox_item('Alice / foo') end expect(page).to have_field('Branch name', with: 'ACME-123-my-issue-title') @@ -61,9 +61,9 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ find('span', text: 'Alice / foo', match: :first).click - within_dropdown do + within_project_listbox do fill_in 'Search', with: '' - find('span', text: 'Alice / bar', match: :first).click + select_listbox_item('Alice / bar') end click_on 'master' diff --git a/spec/features/markdown/markdown_spec.rb b/spec/features/markdown/markdown_spec.rb index 132a03877f8..6e62aa892bb 100644 --- a/spec/features/markdown/markdown_spec.rb +++ b/spec/features/markdown/markdown_spec.rb @@ -296,6 +296,11 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures, feature_category: :team_p expect(img.attr('width')).to eq('75%') expect(img.attr('height')).to eq('100') + + vid = doc.at_css('video[data-title="Sized Video"]') + + expect(vid.attr('width')).to eq('75%') + expect(vid.attr('height')).to eq('100') end end end diff --git a/spec/features/markdown/math_spec.rb b/spec/features/markdown/math_spec.rb index 0c77bd2a8ff..25459494a0c 100644 --- a/spec/features/markdown/math_spec.rb +++ b/spec/features/markdown/math_spec.rb @@ -64,7 +64,82 @@ RSpec.describe 'Math rendering', :js, feature_category: :team_planning do visit project_issue_path(project, issue) page.within '.description > .md' do - expect(page).to have_selector('.js-lazy-render-math') + expect(page).to have_selector('.js-lazy-render-math-container', text: /math block exceeds 1000 characters/) + end + end + + it 'allows many expansions', :js do + description = <<~MATH + ```math + #{'\\mod e ' * 100} + ``` + MATH + + issue = create(:issue, project: project, description: description) + + visit project_issue_path(project, issue) + + wait_for_requests + + page.within '.description > .md' do + expect(page).not_to have_selector('.katex-error') + end + end + + it 'shows error message when too many expansions', :js do + description = <<~MATH + ```math + #{'\\mod e ' * 150} + ``` + MATH + + issue = create(:issue, project: project, description: description) + + visit project_issue_path(project, issue) + + wait_for_requests + + page.within '.description > .md' do + click_button 'Display anyway' + + expect(page).to have_selector('.katex-error', text: /Too many expansions/) + end + end + + it 'shows error message when other errors are generated', :js do + description = <<~MATH + ```math + \\unknown + ``` + MATH + + issue = create(:issue, project: project, description: description) + + visit project_issue_path(project, issue) + + wait_for_requests + + page.within '.description > .md' do + expect(page).to have_selector('.katex-error', + text: /There was an error rendering this math block. KaTeX parse error/) + end + end + + it 'escapes HTML in error', :js do + description = <<~MATH + ```math + \\unknown <script> + ``` + MATH + + issue = create(:issue, project: project, description: description) + + visit project_issue_path(project, issue) + + wait_for_requests + + page.within '.description > .md' do + expect(page).to have_selector('.katex-error', text: /&lt;script&gt;/) end end diff --git a/spec/features/merge_request/batch_comments_spec.rb b/spec/features/merge_request/batch_comments_spec.rb index 736c986d0fe..ddbcb04fa80 100644 --- a/spec/features/merge_request/batch_comments_spec.rb +++ b/spec/features/merge_request/batch_comments_spec.rb @@ -210,7 +210,8 @@ RSpec.describe 'Merge request > Batch comments', :js, feature_category: :code_re page.find('.js-diff-comment-avatar').click end - it 'publishes comment right away and unresolves the thread' do + it 'publishes comment right away and unresolves the thread', + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/337931' do expect(active_discussion.resolved?).to eq(true) write_reply_to_discussion(button_text: 'Add comment now', unresolve: true) @@ -220,7 +221,8 @@ RSpec.describe 'Merge request > Batch comments', :js, feature_category: :code_re end end - it 'publishes review and unresolves the thread' do + it 'publishes review and unresolves the thread', + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/337931' do expect(active_discussion.resolved?).to eq(true) wait_for_requests @@ -252,10 +254,10 @@ RSpec.describe 'Merge request > Batch comments', :js, feature_category: :code_re wait_for_requests end - def write_diff_comment(**params) + def write_diff_comment(...) click_diff_line(find_by_scrolling("[id='#{sample_compare.changes[0][:line_code]}']")) - write_comment(**params) + write_comment(...) end def write_parallel_comment(line, **params) diff --git a/spec/features/merge_request/user_can_see_draft_toggle_spec.rb b/spec/features/merge_request/user_can_see_draft_toggle_spec.rb new file mode 100644 index 00000000000..ac7b5cdab04 --- /dev/null +++ b/spec/features/merge_request/user_can_see_draft_toggle_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Merge request > User sees draft toggle', feature_category: :code_review_workflow do + let_it_be(:project) { create(:project, :public, :repository) } + let(:user) { project.creator } + + before do + project.add_maintainer(user) + sign_in(user) + end + + context 'with draft commits' do + it 'shows the draft toggle' do + visit project_new_merge_request_path( + project, + merge_request: { + source_project_id: project.id, + target_project_id: project.id, + source_branch: 'wip', + target_branch: 'master' + }) + + expect(page).to have_css('input[type="checkbox"].js-toggle-draft', count: 1) + expect(page).to have_text('Mark as draft') + expect(page).to have_text('Drafts cannot be merged until marked ready.') + end + end + + context 'without draft commits' do + it 'shows the draft toggle' do + visit project_new_merge_request_path( + project, + merge_request: { + source_project_id: project.id, + target_project_id: project.id, + source_branch: 'fix', + target_branch: 'master' + }) + + expect(page).to have_css('input[type="checkbox"].js-toggle-draft', count: 1) + expect(page).to have_text('Mark as draft') + expect(page).to have_text('Drafts cannot be merged until marked ready.') + end + end +end diff --git a/spec/features/merge_request/user_creates_merge_request_spec.rb b/spec/features/merge_request/user_creates_merge_request_spec.rb index 1717069a259..97b423f2cc2 100644 --- a/spec/features/merge_request/user_creates_merge_request_spec.rb +++ b/spec/features/merge_request/user_creates_merge_request_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'User creates a merge request', :js, feature_category: :code_review_workflow do include ProjectForksHelper + include ListboxHelpers shared_examples 'creates a merge request' do specify do @@ -73,19 +74,9 @@ RSpec.describe 'User creates a merge request', :js, feature_category: :code_revi expect(page).to have_content('You must select source and target branch') - first('.js-source-project').click - first('.dropdown-source-project a', text: forked_project.full_path) - - first('.js-target-project').click - first('.dropdown-target-project li', text: project.full_path) - - first('.js-source-branch').click - - wait_for_requests - - source_branch = 'fix' - - first('.js-source-branch-dropdown .dropdown-content a', text: source_branch).click + select_project('.js-source-project', forked_project) + select_project('.js-target-project', project) + select_branch('.js-source-branch', 'fix') click_button('Compare branches and continue') @@ -107,7 +98,7 @@ RSpec.describe 'User creates a merge request', :js, feature_category: :code_revi click_button('Create merge request') - expect(page).to have_content(title).and have_content("requested to merge #{forked_project.full_path}:#{source_branch} into master") + expect(page).to have_content(title).and have_content("requested to merge #{forked_project.full_path}:fix into master") end end end @@ -153,12 +144,27 @@ RSpec.describe 'User creates a merge request', :js, feature_category: :code_revi private def compare_source_and_target(source_branch, target_branch) - find('.js-source-branch').click - click_link(source_branch) - - find('.js-target-branch').click - click_link(target_branch) + select_branch('.js-source-branch', source_branch) + select_branch('.js-target-branch', target_branch) click_button('Compare branches') end + + def select_project(selector, project) + first(selector).click + + wait_for_requests + + find('.gl-listbox-search-input').set(project.full_path) + select_listbox_item(project.full_path) + end + + def select_branch(selector, branch) + first(selector).click + + wait_for_requests + + find('.gl-listbox-search-input').set(branch) + select_listbox_item(branch, exact_text: true) + end end diff --git a/spec/features/merge_request/user_creates_mr_spec.rb b/spec/features/merge_request/user_creates_mr_spec.rb index 523027582b3..6ee20a08a47 100644 --- a/spec/features/merge_request/user_creates_mr_spec.rb +++ b/spec/features/merge_request/user_creates_mr_spec.rb @@ -59,9 +59,9 @@ RSpec.describe 'Merge request > User creates MR', feature_category: :code_review it 'filters source project' do find('.js-source-project').click - find('.dropdown-source-project input').set('source') + find('.gl-listbox-search-input').set('source') - expect(find('.dropdown-source-project .dropdown-content')).not_to have_content(source_project.name) + expect(first('.merge-request-select .gl-new-dropdown-panel')).not_to have_content(source_project.name) end end end diff --git a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb index 60631027d9d..cf5024ad59e 100644 --- a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb +++ b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Merge request > User edits assignees sidebar', :js, feature_category: :code_review_workflow do + include Spec::Support::Helpers::Features::InviteMembersModalHelper + let(:project) { create(:project, :public, :repository) } let(:protected_branch) { create(:protected_branch, :maintainers_can_push, name: 'master', project: project) } let(:merge_request) { create(:merge_request, :simple, source_project: project, target_branch: protected_branch.name) } @@ -15,11 +17,17 @@ RSpec.describe 'Merge request > User edits assignees sidebar', :js, feature_cate # DOM finders to simplify and improve readability let(:sidebar_assignee_block) { page.find('.js-issuable-sidebar .assignee') } - let(:sidebar_assignee_avatar_link) { sidebar_assignee_block.find_all('a').find { |a| a['href'].include? assignee.username } } + let(:sidebar_assignee_avatar_link) do + sidebar_assignee_block.find_all('a').find { |a| a['href'].include? assignee.username } + end + let(:sidebar_assignee_tooltip) { sidebar_assignee_avatar_link['title'] || '' } context 'when GraphQL assignees widget feature flag is disabled' do - let(:sidebar_assignee_dropdown_item) { sidebar_assignee_block.find(".dropdown-menu li[data-user-id=\"#{assignee.id}\"]") } + let(:sidebar_assignee_dropdown_item) do + sidebar_assignee_block.find(".dropdown-menu li[data-user-id=\"#{assignee.id}\"]") + end + let(:sidebar_assignee_dropdown_tooltip) { sidebar_assignee_dropdown_item.find('a')['data-title'] || '' } before do @@ -156,11 +164,13 @@ RSpec.describe 'Merge request > User edits assignees sidebar', :js, feature_cate expect(page).to have_link('Invite members') expect(page).to have_selector('[data-track-action="click_invite_members"]') expect(page).to have_selector('[data-track-label="edit_assignee"]') - end - click_link 'Invite members' + click_link 'Invite members' + end - expect(page).to have_content("You're inviting members to the") + page.within invite_modal_selector do + expect(page).to have_content("You're inviting members to the #{project.name} project") + end end end diff --git a/spec/features/merge_request/user_merges_immediately_spec.rb b/spec/features/merge_request/user_merges_immediately_spec.rb index 79c166434aa..d47968ebc6b 100644 --- a/spec/features/merge_request/user_merges_immediately_spec.rb +++ b/spec/features/merge_request/user_merges_immediately_spec.rb @@ -38,7 +38,7 @@ RSpec.describe 'Merge requests > User merges immediately', :js, feature_category end end - expect(find('.media-body h4')).to have_content('Merging!') + expect(find('[data-testid="merging-state"]')).to have_content('Merging!') wait_for_requests end diff --git a/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb index c73ba1bdbe5..cdc00017ab3 100644 --- a/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb +++ b/spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb @@ -57,7 +57,7 @@ RSpec.describe 'Merge request > User merges only if pipeline succeeds', :js, fea wait_for_requests expect(page).not_to have_button('Merge') - expect(page).to have_content('Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or learn about other solutions.') + expect(page).to have_content('Merge blocked: pipeline must succeed. Push a commit that fixes the failure or learn about other solutions.') end end @@ -70,7 +70,7 @@ RSpec.describe 'Merge request > User merges only if pipeline succeeds', :js, fea wait_for_requests expect(page).not_to have_button 'Merge' - expect(page).to have_content('Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or learn about other solutions.') + expect(page).to have_content('Merge blocked: pipeline must succeed. Push a commit that fixes the failure or learn about other solutions.') end end diff --git a/spec/features/merge_request/user_resolves_wip_mr_spec.rb b/spec/features/merge_request/user_resolves_wip_mr_spec.rb index 8a19a72f6ae..01cc6bd5167 100644 --- a/spec/features/merge_request/user_resolves_wip_mr_spec.rb +++ b/spec/features/merge_request/user_resolves_wip_mr_spec.rb @@ -33,7 +33,7 @@ RSpec.describe 'Merge request > User resolves Draft', :js, feature_category: :co it 'retains merge request data after clicking Resolve WIP status' do expect(page.find('.ci-widget-content')).to have_content("Pipeline ##{pipeline.id}") - expect(page).to have_content "Merge blocked: merge request must be marked as ready. It's still marked as draft." + expect(page).to have_content "Merge blocked: Select Mark as ready to remove it from Draft status." page.within('.mr-state-widget') do click_button('Mark as ready') @@ -45,7 +45,7 @@ RSpec.describe 'Merge request > User resolves Draft', :js, feature_category: :co # merge request widget refreshes, which masks missing elements # that should already be present. expect(page.find('.ci-widget-content', wait: 0)).to have_content("Pipeline ##{pipeline.id}") - expect(page).not_to have_content("Merge blocked: merge request must be marked as ready. It's still marked as draft.") + expect(page).not_to have_content("Merge blocked: Select Mark as ready to remove it from Draft status.") end end end diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb index daeeaa1bd88..12fdcf4859e 100644 --- a/spec/features/merge_request/user_sees_diff_spec.rb +++ b/spec/features/merge_request/user_sees_diff_spec.rb @@ -32,7 +32,7 @@ RSpec.describe 'Merge request > User sees diff', :js, feature_category: :code_re visit "#{diffs_project_merge_request_path(project, merge_request)}#{fragment}" end - it 'shows expanded note' do + it 'shows expanded note', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391239' do expect(page).to have_selector(fragment, visible: true) end end diff --git a/spec/features/merge_request/user_sees_discussions_navigation_spec.rb b/spec/features/merge_request/user_sees_discussions_navigation_spec.rb index 9d3046a9a72..6e6c2cddfbf 100644 --- a/spec/features/merge_request/user_sees_discussions_navigation_spec.rb +++ b/spec/features/merge_request/user_sees_discussions_navigation_spec.rb @@ -58,7 +58,7 @@ RSpec.describe 'Merge request > User sees discussions navigation', :js, feature_ expect(page).to have_selector(second_discussion_selector, obscured: false) end - it 'cycles back to the first thread' do + it 'cycles back to the first thread', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391604' do goto_next_thread goto_next_thread goto_next_thread @@ -92,7 +92,8 @@ RSpec.describe 'Merge request > User sees discussions navigation', :js, feature_ page.execute_script("window.scrollTo(0,0)") end - it 'excludes resolved threads during navigation' do + it 'excludes resolved threads during navigation', + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/383687' do goto_next_thread goto_next_thread goto_next_thread 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 0297bb5b935..acf2893b513 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -18,7 +18,6 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: end before do - stub_feature_flags(refactor_security_extension: false) project.add_maintainer(user) project_only_mwps.add_maintainer(user) sign_in(user) @@ -90,12 +89,12 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_button 'master' end - page.within("#{modal_selector} .dropdown-menu") do - find('[data-testid="dropdown-search-box"]').set('') + page.within("#{modal_selector} [data-testid=\"base-dropdown-menu\"]") do + fill_in 'Search branches', with: '' wait_for_requests - expect(page.all('[data-testid="dropdown-item"]').size).to be > 1 + expect(page).to have_selector('[data-testid="listbox-item-master"]', visible: true) end end end @@ -149,7 +148,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category: click_button 'Merge unverified changes' end - expect(find('.media-body h4')).to have_content('Merging!') + expect(find('[data-testid="merging-state"]')).to have_content('Merging!') end end diff --git a/spec/features/merge_request/user_sees_wip_help_message_spec.rb b/spec/features/merge_request/user_sees_wip_help_message_spec.rb deleted file mode 100644 index fdefe5ffb06..00000000000 --- a/spec/features/merge_request/user_sees_wip_help_message_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Merge request > User sees draft help message', feature_category: :code_review_workflow do - let(:project) { create(:project, :public, :repository) } - let(:user) { project.creator } - - before do - project.add_maintainer(user) - sign_in(user) - end - - context 'with draft commits' do - it 'shows a specific draft hint' do - visit project_new_merge_request_path( - project, - merge_request: { - source_project_id: project.id, - target_project_id: project.id, - source_branch: 'wip', - target_branch: 'master' - }) - - within_wip_explanation do - expect(page).to have_text( - 'It looks like you have some draft commits in this branch' - ) - end - end - end - - context 'without draft commits' do - it 'shows the regular draft message' do - visit project_new_merge_request_path( - project, - merge_request: { - source_project_id: project.id, - target_project_id: project.id, - source_branch: 'fix', - target_branch: 'master' - }) - - within_wip_explanation do - expect(page).not_to have_text( - 'It looks like you have some draft commits in this branch' - ) - expect(page).to have_text( - "Start the title with Draft: to prevent a merge request draft \ -from merging before it's ready." - ) - end - end - end - - def within_wip_explanation(&block) - page.within '.js-no-wip-explanation' do - yield - end - end -end diff --git a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb index b7784de12b9..0de59ea21c5 100644 --- a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb +++ b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb @@ -3,13 +3,15 @@ require 'spec_helper' RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_category: :code_review_workflow do + include ListboxHelpers + let(:project) { create(:project, :public, :repository) } let(:user) { project.creator } def select_source_branch(branch_name) find('.js-source-branch', match: :first).click - find('.js-source-branch-dropdown .dropdown-input-field').native.send_keys branch_name - find('.js-source-branch-dropdown .dropdown-content a', text: branch_name, match: :first).click + find('.gl-listbox-search-input').native.send_keys branch_name + select_listbox_item(branch_name) end before do @@ -27,7 +29,7 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ expect(page).to have_content('Target branch') first('.js-source-branch').click - find('.js-source-branch-dropdown .dropdown-content a', match: :first).click + find('.gl-new-dropdown-item', match: :first).click expect(page).to have_content "b83d6e3" end @@ -43,7 +45,8 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ expect(page).to have_content('Target branch') first('.js-target-branch').click - find('.js-target-branch-dropdown .dropdown-content a', text: 'v1.1.0', match: :first).click + find('.gl-listbox-search-input').native.send_keys 'v1.1.0' + select_listbox_item('v1.1.0') expect(page).to have_content "b83d6e3" end @@ -68,27 +71,6 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ expect(page).to have_content 'git checkout -b \'orphaned-branch\' \'origin/orphaned-branch\'' end - it 'allows filtering multiple dropdowns' do - visit project_new_merge_request_path(project) - - first('.js-source-branch').click - - page.within '.js-source-branch-dropdown' do - input = find('.dropdown-input-field') - input.click - input.send_keys('orphaned-branch') - - expect(page).to have_css('.dropdown-content li', count: 1) - end - - first('.js-target-branch').click - - find('.js-target-branch-dropdown .dropdown-content li', match: :first) - target_items = all('.js-target-branch-dropdown .dropdown-content li') - - expect(target_items.count).to be > 1 - end - context 'when target project cannot be viewed by the current user' do it 'does not leak the private project name & namespace' do private_project = create(:project, :private, :repository) diff --git a/spec/features/merge_requests/user_mass_updates_spec.rb b/spec/features/merge_requests/user_mass_updates_spec.rb index 5a9054ece48..b0be76d386a 100644 --- a/spec/features/merge_requests/user_mass_updates_spec.rb +++ b/spec/features/merge_requests/user_mass_updates_spec.rb @@ -121,7 +121,7 @@ RSpec.describe 'Merge requests > User mass updates', :js, feature_category: :cod within 'aside[aria-label="Bulk update"]' do click_button 'Select assignee' wait_for_requests - click_link text + click_button text end click_update_merge_requests_button end diff --git a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb index cf99f2cb94a..58d796f8288 100644 --- a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb +++ b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb @@ -27,15 +27,15 @@ RSpec.describe 'User sorts merge requests', :js, feature_category: :code_review_ visit(merge_requests_dashboard_path(assignee_username: user.username)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') visit(project_merge_requests_path(project)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') visit(merge_requests_group_path(group)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') end it 'fallbacks to issuable_sort cookie key when remembering the sorting option' do @@ -43,7 +43,7 @@ RSpec.describe 'User sorts merge requests', :js, feature_category: :code_review_ visit(merge_requests_dashboard_path(assignee_username: user.username)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') end it 'separates remember sorting with issues', :js do diff --git a/spec/features/nav/top_nav_responsive_spec.rb b/spec/features/nav/top_nav_responsive_spec.rb index d038c5d9e32..56f9d373f00 100644 --- a/spec/features/nav/top_nav_responsive_spec.rb +++ b/spec/features/nav/top_nav_responsive_spec.rb @@ -9,43 +9,87 @@ RSpec.describe 'top nav responsive', :js, feature_category: :navigation do before do sign_in(user) - visit explore_projects_path resize_screen_xs end - context 'before opened' do - it 'has page content and hides responsive menu', :aggregate_failures do - expect(page).to have_css('.page-title', text: 'Projects') - expect(page).to have_link('Dashboard', id: 'logo') + context 'when outside groups and projects' do + before do + visit explore_projects_path + end - expect(page).to have_no_css('.top-nav-responsive') + context 'when menu is closed' do + it 'has page content and hides responsive menu', :aggregate_failures do + expect(page).to have_css('.page-title', text: 'Projects') + expect(page).to have_link('Dashboard', id: 'logo') + + expect(page).to have_no_css('.top-nav-responsive') + end + end + + context 'when menu is opened' do + before do + click_button('Menu') + end + + it 'hides everything and shows responsive menu', :aggregate_failures do + expect(page).to have_no_css('.page-title', text: 'Projects') + expect(page).to have_no_link('Dashboard', id: 'logo') + + within '.top-nav-responsive' do + expect(page).to have_link(nil, href: search_path) + expect(page).to have_button('Projects') + expect(page).to have_button('Groups') + expect(page).to have_link('Snippets', href: dashboard_snippets_path) + end + end + + it 'has new dropdown', :aggregate_failures do + create_new_button.click + + expect(page).to have_link('New project', href: new_project_path) + expect(page).to have_link('New group', href: new_group_path) + expect(page).to have_link('New snippet', href: new_snippet_path) + end end end - context 'when opened' do + context 'when inside a project' do + let_it_be(:project) { create(:project).tap { |record| record.add_owner(user) } } + before do - click_button('Menu') + visit project_path(project) end - it 'hides everything and shows responsive menu', :aggregate_failures do - expect(page).to have_no_css('.page-title', text: 'Projects') - expect(page).to have_no_link('Dashboard', id: 'logo') + it 'the add menu contains invite members dropdown option and goes to the members page' do + invite_members_from_menu - within '.top-nav-responsive' do - expect(page).to have_link(nil, href: search_path) - expect(page).to have_button('Projects') - expect(page).to have_button('Groups') - expect(page).to have_link('Snippets', href: dashboard_snippets_path) - end + expect(page).to have_current_path(project_project_members_path(project)) + end + end + + context 'when inside a group' do + let_it_be(:group) { create(:group).tap { |record| record.add_owner(user) } } + + before do + visit group_path(group) end - it 'has new dropdown', :aggregate_failures do - click_button('Create new...') + it 'the add menu contains invite members dropdown option and goes to the members page' do + invite_members_from_menu - expect(page).to have_link('New project', href: new_project_path) - expect(page).to have_link('New group', href: new_group_path) - expect(page).to have_link('New snippet', href: new_snippet_path) + expect(page).to have_current_path(group_group_members_path(group)) end end + + def invite_members_from_menu + click_button('Menu') + create_new_button.click + + click_link('Invite members') + end + + def create_new_button + find('[data-testid="plus-icon"]') + end end diff --git a/spec/features/nav/top_nav_spec.rb b/spec/features/nav/top_nav_spec.rb new file mode 100644 index 00000000000..cc20b626e30 --- /dev/null +++ b/spec/features/nav/top_nav_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'top nav responsive', :js, feature_category: :navigation do + let_it_be(:user) { create(:user) } + + before do + sign_in(user) + end + + context 'when inside a project' do + let_it_be(:project) { create(:project).tap { |record| record.add_owner(user) } } + + before do + visit project_path(project) + end + + it 'the add menu contains invite members dropdown option and goes to the members page' do + invite_members_from_menu + + expect(page).to have_current_path(project_project_members_path(project)) + end + end + + context 'when inside a group' do + let_it_be(:group) { create(:group).tap { |record| record.add_owner(user) } } + + before do + visit group_path(group) + end + + it 'the add menu contains invite members dropdown option and goes to the members page' do + invite_members_from_menu + + expect(page).to have_current_path(group_group_members_path(group)) + end + end + + def invite_members_from_menu + find('[data-testid="new-dropdown"]').click + + click_link('Invite members') + end +end diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb index 07d0fca0139..bd96d65f984 100644 --- a/spec/features/oauth_login_spec.rb +++ b/spec/features/oauth_login_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'OAuth Login', :allow_forgery_protection, feature_category: :syst end providers = [:github, :twitter, :bitbucket, :gitlab, :google_oauth2, - :facebook, :cas3, :auth0, :authentiq, :salesforce, :dingtalk, :alicloud] + :facebook, :cas3, :auth0, :salesforce, :dingtalk, :alicloud] around do |example| with_omniauth_full_host { example.run } diff --git a/spec/features/oauth_registration_spec.rb b/spec/features/oauth_registration_spec.rb index 6e1445a9ed6..3c1004e452f 100644 --- a/spec/features/oauth_registration_spec.rb +++ b/spec/features/oauth_registration_spec.rb @@ -23,7 +23,6 @@ RSpec.describe 'OAuth Registration', :js, :allow_forgery_protection, feature_cat :facebook | {} :cas3 | {} :auth0 | {} - :authentiq | {} :salesforce | { extra: { email_verified: true } } :dingtalk | {} :alicloud | {} diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 87a65438768..e190dfda937 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile account page', :js, feature_category: :users do +RSpec.describe 'Profile account page', :js, feature_category: :user_profile do include Spec::Support::Helpers::ModalHelpers let(:user) { create(:user) } diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb index 82c45862e07..7e4308106be 100644 --- a/spec/features/profiles/account_spec.rb +++ b/spec/features/profiles/account_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Account', :js, feature_category: :users do +RSpec.describe 'Profile > Account', :js, feature_category: :user_profile do let(:user) { create(:user, username: 'foo') } before do diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb index 5c20735cf35..0de4ad47f9a 100644 --- a/spec/features/profiles/active_sessions_spec.rb +++ b/spec/features/profiles/active_sessions_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state, feature_category: :users do +RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state, feature_category: :user_profile do include Spec::Support::Helpers::ModalHelpers let(:user) do diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb index 14fdb8ba56f..299ecdb6032 100644 --- a/spec/features/profiles/chat_names_spec.rb +++ b/spec/features/profiles/chat_names_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Chat', feature_category: :users do +RSpec.describe 'Profile > Chat', feature_category: :user_profile do let(:user) { create(:user) } let(:integration) { create(:integration) } diff --git a/spec/features/profiles/emails_spec.rb b/spec/features/profiles/emails_spec.rb index e8ea227c072..d00cef1f6f0 100644 --- a/spec/features/profiles/emails_spec.rb +++ b/spec/features/profiles/emails_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Emails', feature_category: :users do +RSpec.describe 'Profile > Emails', feature_category: :user_profile do let(:user) { create(:user) } let(:other_user) { create(:user) } diff --git a/spec/features/profiles/gpg_keys_spec.rb b/spec/features/profiles/gpg_keys_spec.rb index 1d014f983e7..0fc59f21489 100644 --- a/spec/features/profiles/gpg_keys_spec.rb +++ b/spec/features/profiles/gpg_keys_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > GPG Keys', feature_category: :users do +RSpec.describe 'Profile > GPG Keys', feature_category: :user_profile do let(:user) { create(:user, email: GpgHelpers::User2.emails.first) } before do diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb index 7a2a12d8dca..ae61f1cf492 100644 --- a/spec/features/profiles/keys_spec.rb +++ b/spec/features/profiles/keys_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > SSH Keys', feature_category: :users do +RSpec.describe 'Profile > SSH Keys', feature_category: :user_profile do let(:user) { create(:user) } before do @@ -76,35 +76,76 @@ RSpec.describe 'Profile > SSH Keys', feature_category: :users do expect(page).to have_content(key.title) end + def destroy_key(path, action, confirmation_button) + visit path + + page.click_button(action) + + page.within('.modal') do + page.click_button(confirmation_button) + end + + expect(page).to have_content('Your SSH keys (0)') + end + describe 'User removes a key', :js do - shared_examples 'removes key' do - it 'removes key' do - visit path - find('[data-testid=remove-icon]').click + let!(:key) { create(:key, user: user) } - page.within('.modal') do - page.click_button('Delete') - end + context 'via the key index' do + it 'removes key' do + destroy_key(profile_keys_path, 'Remove', 'Delete') + end + end - expect(page).to have_content('Your SSH keys (0)') + context 'via its details page' do + it 'removes key' do + destroy_key(profile_keys_path(key), 'Remove', 'Delete') end end + end + + describe 'User revokes a key', :js do + context 'when a commit is signed using SSH key' do + let!(:project) { create(:project, :repository) } + let!(:key) { create(:key, user: user) } + let!(:commit) { project.commit('ssh-signed-commit') } + + let!(:signature) do + create(:ssh_signature, + project: project, + key: key, + key_fingerprint_sha256: key.fingerprint_sha256, + commit_sha: commit.sha) + end - context 'via the key index' do before do - create(:key, user: user) + project.add_developer(user) end - let(:path) { profile_keys_path } + it 'revoking the SSH key marks commits as unverified' do + visit project_commit_path(project, commit) + wait_for_all_requests - it_behaves_like 'removes key' - end + find('a.signature-badge', text: 'Verified').click - context 'via its details page' do - let(:key) { create(:key, user: user) } - let(:path) { profile_keys_path(key) } + within('.popover') do + expect(page).to have_content("Verified commit") + expect(page).to have_content("SSH key fingerprint: #{key.fingerprint_sha256}") + end + + destroy_key(profile_keys_path, 'Revoke', 'Revoke') + + visit project_commit_path(project, commit) + wait_for_all_requests - it_behaves_like 'removes key' + find('a.signature-badge', text: 'Unverified').click + + within('.popover') do + expect(page).to have_content("Unverified signature") + expect(page).to have_content('This commit was signed with a key that was revoked.') + expect(page).to have_content("SSH key fingerprint: #{signature.key_fingerprint_sha256}") + end + end end end end diff --git a/spec/features/profiles/list_users_saved_replies_spec.rb b/spec/features/profiles/list_users_saved_replies_spec.rb new file mode 100644 index 00000000000..4f3678f8051 --- /dev/null +++ b/spec/features/profiles/list_users_saved_replies_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Profile > Notifications > List users saved replies', :js, + feature_category: :user_profile do + let_it_be(:user) { create(:user) } + let_it_be(:saved_reply) { create(:saved_reply, user: user) } + + before do + sign_in(user) + end + + it 'shows the user a list of their saved replies' do + visit profile_saved_replies_path + + expect(page).to have_content('My saved replies (1)') + expect(page).to have_content(saved_reply.name) + expect(page).to have_content(saved_reply.content) + end +end diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb index 80d05fd5cc7..d088f73f9df 100644 --- a/spec/features/profiles/oauth_applications_spec.rb +++ b/spec/features/profiles/oauth_applications_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Applications', feature_category: :users do +RSpec.describe 'Profile > Applications', feature_category: :user_profile do include Spec::Support::Helpers::ModalHelpers let(:user) { create(:user) } diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb index b324ee17873..c0c573d2f20 100644 --- a/spec/features/profiles/password_spec.rb +++ b/spec/features/profiles/password_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Password', feature_category: :users do +RSpec.describe 'Profile > Password', feature_category: :user_profile do let(:user) { create(:user) } def fill_passwords(password, confirmation) diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 3087d7ff296..a050e87241b 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Profile > Personal Access Tokens', :js, feature_category: :users do +RSpec.describe 'Profile > Personal Access Tokens', :js, feature_category: :user_profile do include Spec::Support::Helpers::ModalHelpers include Spec::Support::Helpers::AccessTokenHelpers diff --git a/spec/features/profiles/two_factor_auths_spec.rb b/spec/features/profiles/two_factor_auths_spec.rb index 8dddaad11c3..e8ff8416722 100644 --- a/spec/features/profiles/two_factor_auths_spec.rb +++ b/spec/features/profiles/two_factor_auths_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Two factor auths', feature_category: :users do +RSpec.describe 'Two factor auths', feature_category: :user_profile do include Spec::Support::Helpers::ModalHelpers context 'when signed in' do diff --git a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb index 197a33c355d..89887cb4772 100644 --- a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb +++ b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Profile > Notifications > User changes notified_of_own_activity setting', :js, -feature_category: :users do +feature_category: :user_profile do let(:user) { create(:user) } before do diff --git a/spec/features/profiles/user_edit_preferences_spec.rb b/spec/features/profiles/user_edit_preferences_spec.rb index 1a231f1d269..f7a9850355a 100644 --- a/spec/features/profiles/user_edit_preferences_spec.rb +++ b/spec/features/profiles/user_edit_preferences_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User edit preferences profile', :js, feature_category: :users do +RSpec.describe 'User edit preferences profile', :js, feature_category: :user_profile do include StubLanguagesTranslationPercentage # Empty value doesn't change the levels diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb index 67604292090..3819723cc09 100644 --- a/spec/features/profiles/user_edit_profile_spec.rb +++ b/spec/features/profiles/user_edit_profile_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User edit profile', feature_category: :users do +RSpec.describe 'User edit profile', feature_category: :user_profile do include Spec::Support::Helpers::Features::NotesHelpers let_it_be(:user) { create(:user) } diff --git a/spec/features/profiles/user_manages_applications_spec.rb b/spec/features/profiles/user_manages_applications_spec.rb index 179da61b8ed..e3c4a797431 100644 --- a/spec/features/profiles/user_manages_applications_spec.rb +++ b/spec/features/profiles/user_manages_applications_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User manages applications', feature_category: :users do +RSpec.describe 'User manages applications', feature_category: :user_profile do let_it_be(:user) { create(:user) } let_it_be(:new_application_path) { applications_profile_path } let_it_be(:index_path) { oauth_applications_path } diff --git a/spec/features/profiles/user_manages_emails_spec.rb b/spec/features/profiles/user_manages_emails_spec.rb index 16a9fbc2f47..b875dfec217 100644 --- a/spec/features/profiles/user_manages_emails_spec.rb +++ b/spec/features/profiles/user_manages_emails_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User manages emails', feature_category: :users do +RSpec.describe 'User manages emails', feature_category: :user_profile do let(:user) { create(:user) } let(:other_user) { create(:user) } diff --git a/spec/features/profiles/user_search_settings_spec.rb b/spec/features/profiles/user_search_settings_spec.rb index 09ee8ddeaab..932ea11075a 100644 --- a/spec/features/profiles/user_search_settings_spec.rb +++ b/spec/features/profiles/user_search_settings_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User searches their settings', :js, feature_category: :users do +RSpec.describe 'User searches their settings', :js, feature_category: :user_profile do let_it_be(:user) { create(:user) } before do diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb index d212982f4e3..1295a0b6150 100644 --- a/spec/features/profiles/user_visits_notifications_tab_spec.rb +++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User visits the notifications tab', :js, feature_category: :users do +RSpec.describe 'User visits the notifications tab', :js, feature_category: :user_profile do let(:project) { create(:project) } let(:user) { create(:user) } diff --git a/spec/features/profiles/user_visits_profile_account_page_spec.rb b/spec/features/profiles/user_visits_profile_account_page_spec.rb index 1cf34478ecf..8ff9cbc242e 100644 --- a/spec/features/profiles/user_visits_profile_account_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_account_page_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User visits the profile account page', feature_category: :users do +RSpec.describe 'User visits the profile account page', feature_category: :user_profile do let(:user) { create(:user) } before do diff --git a/spec/features/profiles/user_visits_profile_authentication_log_spec.rb b/spec/features/profiles/user_visits_profile_authentication_log_spec.rb index 726cca4a4bd..90f24c5b866 100644 --- a/spec/features/profiles/user_visits_profile_authentication_log_spec.rb +++ b/spec/features/profiles/user_visits_profile_authentication_log_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User visits the authentication log', feature_category: :users do +RSpec.describe 'User visits the authentication log', feature_category: :user_profile do let(:user) { create(:user) } context 'when user signed in' do diff --git a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb index e3940973c46..d690589b893 100644 --- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User visits the profile preferences page', :js, feature_category: :users do +RSpec.describe 'User visits the profile preferences page', :js, feature_category: :user_profile do include ListboxHelpers let(:user) { create(:user) } diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb index 7fca0f24deb..ad265fbae9e 100644 --- a/spec/features/profiles/user_visits_profile_spec.rb +++ b/spec/features/profiles/user_visits_profile_spec.rb @@ -2,10 +2,11 @@ require 'spec_helper' -RSpec.describe 'User visits their profile', feature_category: :users do +RSpec.describe 'User visits their profile', feature_category: :user_profile do let_it_be_with_refind(:user) { create(:user) } before do + stub_feature_flags(profile_tabs_vue: false) sign_in(user) end diff --git a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb index 8467e9abeaf..547e47ead77 100644 --- a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User visits the profile SSH keys page', feature_category: :users do +RSpec.describe 'User visits the profile SSH keys page', feature_category: :user_profile do let(:user) { create(:user) } before do diff --git a/spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb b/spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb new file mode 100644 index 00000000000..f1601348e57 --- /dev/null +++ b/spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe 'User views project artifacts page', :js, feature_category: :build_artifacts do + let_it_be(:project) { create(:project, :public) } + let_it_be(:pipeline) { create(:ci_empty_pipeline, project: project) } + let_it_be(:job_with_artifacts) { create(:ci_build, :artifacts, name: 'test1', pipeline: pipeline) } + let_it_be(:job_with_trace) { create(:ci_build, :trace_artifact, name: 'test3', pipeline: pipeline) } + let_it_be(:job_without_artifacts) { create(:ci_build, name: 'test2', pipeline: pipeline) } + + let(:path) { project_artifacts_path(project) } + + context 'when browsing artifacts page' do + before do + visit(path) + + wait_for_requests + end + + it 'lists the project jobs and their artifacts' do + page.within('main#content-body') do + page.within('table thead') do + expect(page).to have_content('Artifacts') + .and have_content('Job') + .and have_content('Size') + end + + find_all('[data-testid="job-artifacts-count"').each(&:click) + + expect(page).to have_content(job_with_artifacts.name) + expect(page).to have_content(job_with_trace.name) + expect(page).not_to have_content(job_without_artifacts.name) + + expect(page).to have_content('archive').and have_content('metadata') + expect(page).to have_content('trace') + end + end + end +end diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index b7e0e3fd590..7faf0e1a6b1 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -961,8 +961,8 @@ RSpec.describe 'File blob', :js, feature_category: :projects do end it 'renders sandboxed iframe' do - expected = %(<iframe src="/-/sandbox/swagger" sandbox="allow-scripts allow-popups allow-forms" frameborder="0" width="100%" height="1000">) - expect(page.html).to include(expected) + expected = %(iframe[src$="/-/sandbox/swagger"][sandbox="allow-scripts allow-popups allow-forms"][frameborder="0"][width="100%"][height="1000"]) + expect(page).to have_css(expected) end end end @@ -1007,8 +1007,8 @@ RSpec.describe 'File blob', :js, feature_category: :projects do it 'displays a GPG badge' do visit_blob('CONTRIBUTING.md', ref: '33f3729a45c02fc67d00adb1b8bca394b0e761d9') - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end end @@ -1016,8 +1016,8 @@ RSpec.describe 'File blob', :js, feature_category: :projects do it 'displays a GPG badge' do visit_blob('conflicting-file.md', ref: '6101e87e575de14b38b4e1ce180519a813671e10') - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end end diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb index eb370cfc1fc..9afd8b3263a 100644 --- a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb +++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do + include ListboxHelpers + let(:user) { create(:user) } let(:project) { create(:project, :public, :repository) } let(:sha) { project.commit.sha } @@ -18,15 +20,13 @@ RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do it 'finds a tag in a list' do tag_name = 'v1.0.0' - toggle.click - filter_by(tag_name) wait_for_requests expect(items_count(tag_name)).to be(1) - item(tag_name).click + select_listbox_item tag_name expect(toggle).to have_content tag_name end @@ -34,22 +34,18 @@ RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do it 'finds a branch in a list' do branch_name = 'audio' - toggle.click - filter_by(branch_name) wait_for_requests expect(items_count(branch_name)).to be(1) - item(branch_name).click + select_listbox_item branch_name expect(toggle).to have_content branch_name end it 'finds a commit in a list' do - toggle.click - filter_by(sha) wait_for_requests @@ -58,21 +54,19 @@ RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do expect(items_count(sha_short)).to be(1) - item(sha_short).click + select_listbox_item sha_short expect(toggle).to have_content sha_short end it 'shows no results when there is no branch, tag or commit sha found' do non_existing_ref = 'non_existing_branch_name' - - toggle.click - filter_by(non_existing_ref) wait_for_requests - expect(find('.gl-dropdown-contents')).not_to have_content(non_existing_ref) + click_button 'master' + expect(toggle).not_to have_content(non_existing_ref) end def item(ref_name) @@ -84,6 +78,7 @@ RSpec.describe 'New Branch Ref Dropdown', :js, feature_category: :projects do end def filter_by(filter_text) - fill_in _('Search by Git revision'), with: filter_text + click_button 'master' + send_keys filter_text end end diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index dc8b84283a1..93ce851521f 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -77,10 +77,12 @@ RSpec.describe 'Cherry-pick Commits', :js, feature_category: :source_code_manage click_button 'master' end - page.within("#{modal_selector} .dropdown-menu") do - find('[data-testid="dropdown-search-box"]').set('feature') + page.within("#{modal_selector} [data-testid=\"base-dropdown-menu\"]") do + fill_in 'Search branches', with: 'feature' + wait_for_requests - click_button 'feature' + + find('[data-testid="listbox-item-feature"]').click end submit_cherry_pick diff --git a/spec/features/projects/commits/multi_view_diff_spec.rb b/spec/features/projects/commits/multi_view_diff_spec.rb index b178a1c2171..f0a074e9b7f 100644 --- a/spec/features/projects/commits/multi_view_diff_spec.rb +++ b/spec/features/projects/commits/multi_view_diff_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.shared_examples "no multiple viewers", feature_category: :source_code_management do |commit_ref| +RSpec.shared_examples "no multiple viewers" do |commit_ref| let(:ref) { commit_ref } it "does not display multiple diff viewers" do @@ -10,7 +10,7 @@ RSpec.shared_examples "no multiple viewers", feature_category: :source_code_mana end end -RSpec.describe 'Multiple view Diffs', :js do +RSpec.describe 'Multiple view Diffs', :js, feature_category: :source_code_management do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb index 125f7209ab4..8082d1bdf63 100644 --- a/spec/features/projects/files/user_browses_files_spec.rb +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -4,6 +4,7 @@ require "spec_helper" RSpec.describe "User browses files", :js, feature_category: :projects do include RepoHelpers + include ListboxHelpers let(:fork_message) do "You're not allowed to make changes to this project directly. "\ @@ -282,17 +283,13 @@ RSpec.describe "User browses files", :js, feature_category: :projects do expect(page).to have_content(".gitignore").and have_content("LICENSE") end - it "shows files from a repository with apostroph in its name" do - ref_name = 'test' + it "shows files from a repository with apostrophe in its name" do + ref_name = 'fix' find(ref_selector).click wait_for_requests - page.within(ref_selector) do - fill_in 'Search by Git revision', with: ref_name - wait_for_requests - find('li', text: ref_name, match: :prefer_exact).click - end + filter_by(ref_name) expect(find(ref_selector)).to have_text(ref_name) @@ -307,11 +304,7 @@ RSpec.describe "User browses files", :js, feature_category: :projects do find(ref_selector).click wait_for_requests - page.within(ref_selector) do - fill_in 'Search by Git revision', with: ref_name - wait_for_requests - find('li', text: ref_name, match: :prefer_exact).click - end + filter_by(ref_name) visit(project_tree_path(project, "fix/.testdir")) @@ -345,8 +338,8 @@ RSpec.describe "User browses files", :js, feature_category: :projects do .and have_content("Initial commit") .and have_content("Ignore DS files") - previous_commit_anchor = "//a[@title='Ignore DS files']/parent::span/following-sibling::span/a" - find(:xpath, previous_commit_anchor).click + previous_commit_link = find('.tr', text: "Ignore DS files").find("[aria-label='View blame prior to this change']") + previous_commit_link.click expect(page).to have_content("*.rb") .and have_content("Dmitriy Zaporozhets") @@ -394,4 +387,12 @@ RSpec.describe "User browses files", :js, feature_category: :projects do end end end + + def filter_by(filter_text) + send_keys filter_text + + wait_for_requests + + select_listbox_item filter_text + end end diff --git a/spec/features/projects/files/user_find_file_spec.rb b/spec/features/projects/files/user_find_file_spec.rb index 1b53189da83..9cc2ce6a7b4 100644 --- a/spec/features/projects/files/user_find_file_spec.rb +++ b/spec/features/projects/files/user_find_file_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'User find project file', feature_category: :projects do + include ListboxHelpers + let(:user) { create :user } let(:project) { create :project, :repository } @@ -21,6 +23,10 @@ RSpec.describe 'User find project file', feature_category: :projects do fill_in 'file_find', with: text end + def ref_selector_dropdown + find('.gl-button-text') + end + it 'navigates to find file by shortcut', :js do find('body').native.send_key('t') @@ -65,4 +71,39 @@ RSpec.describe 'User find project file', feature_category: :projects do expect(page).not_to have_content('CHANGELOG') expect(page).not_to have_content('VERSION') end + + context 'when refs are switched', :js do + before do + click_link 'Find file' + end + + specify 'the ref switcher lists all the branches and tags' do + ref = 'add-ipython-files' + expect(ref_selector_dropdown).not_to have_text(ref) + + find('.ref-selector').click + wait_for_requests + + page.within('.ref-selector') do + expect(page).to have_selector('li', text: ref) + expect(page).to have_selector('li', text: 'v1.0.0') + end + end + + specify 'the search result changes when refs switched' do + ref = 'add-ipython-files' + expect(ref_selector_dropdown).not_to have_text(ref) + + find('.ref-selector button').click + wait_for_requests + + page.within('.ref-selector') do + fill_in _('Switch branch/tag'), with: ref + wait_for_requests + + select_listbox_item(ref) + end + expect(ref_selector_dropdown).to have_text(ref) + end + end end diff --git a/spec/features/projects/graph_spec.rb b/spec/features/projects/graph_spec.rb index f96356b11c9..a1f047d9b43 100644 --- a/spec/features/projects/graph_spec.rb +++ b/spec/features/projects/graph_spec.rb @@ -59,23 +59,30 @@ RSpec.describe 'Project Graph', :js, feature_category: :projects do it 'HTML escapes branch name' do expect(page.body).to include("Commit statistics for <strong>#{ERB::Util.html_escape(branch_name)}</strong>") - expect(page.find('.dropdown-toggle-text')['innerHTML']).to eq(ERB::Util.html_escape(branch_name)) + expect(page.find('.gl-new-dropdown-button-text')['innerHTML']).to include(ERB::Util.html_escape(branch_name)) end end context 'charts graph ref switcher' do it 'switches ref to branch' do - ref_name = 'feature' + ref_name = 'add-pdf-file' visit charts_project_graph_path(project, 'master') - first('.js-project-refs-dropdown').click - page.within '.project-refs-form' do - click_link ref_name + # Not a huge fan of using a HTML (CSS) selectors here as any change of them will cause a failed test + ref_selector = find('.ref-selector .gl-new-dropdown-toggle') + scroll_to(ref_selector) + ref_selector.click + + page.within '.gl-new-dropdown-contents' do + dropdown_branch_item = find('li', text: 'add-pdf-file') + scroll_to(dropdown_branch_item) + dropdown_branch_item.click end - expect(page).to have_selector '.dropdown-menu-toggle', text: ref_name + scroll_to(find('.tree-ref-header'), align: :center) + expect(page).to have_selector '.gl-new-dropdown-toggle', text: ref_name page.within '.tree-ref-header' do - expect(page).to have_content ref_name + expect(page).to have_selector('h4', text: ref_name) end end end diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 0230c9e835b..6630956f835 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -7,7 +7,6 @@ require 'spec_helper' # we'll have to either include it adding the model that includes it to the +safe_list+ # or make sure the attribute is blacklisted in the +import_export.yml+ configuration RSpec.describe 'Import/Export - project export integration test', :js, feature_category: :importers do - include Select2Helper include ExportFileHelper let(:user) { create(:admin) } diff --git a/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb b/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb index 01c202baf70..ec00dcaf046 100644 --- a/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb +++ b/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'User activates Slack notifications', :js, feature_category: :int context 'when integration is not configured yet' do before do + stub_feature_flags(integration_slack_app_notifications: false) visit_project_integration('Slack notifications') end diff --git a/spec/features/projects/issues/design_management/user_views_design_spec.rb b/spec/features/projects/issues/design_management/user_views_design_spec.rb index 11c8bdda3ac..268c209cba1 100644 --- a/spec/features/projects/issues/design_management/user_views_design_spec.rb +++ b/spec/features/projects/issues/design_management/user_views_design_spec.rb @@ -24,4 +24,26 @@ RSpec.describe 'User views issue designs', :js, feature_category: :design_manage expect(page).to have_selector('.js-design-image') end + + context 'when svg file is loaded in design detail' do + let_it_be(:file) { Rails.root.join('spec/fixtures/svg_without_attr.svg') } + let_it_be(:design) { create(:design, :with_file, filename: 'svg_without_attr.svg', file: file, issue: issue) } + + before do + visit designs_project_issue_path( + project, + issue, + { vueroute: design.filename } + ) + wait_for_requests + end + + it 'check if svg is loading' do + expect(page).to have_selector( + ".js-design-image > img[alt='svg_without_attr.svg']", + count: 1, + visible: :hidden + ) + end + end end diff --git a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb index a45b9b718c3..bbc54382ae6 100644 --- a/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb +++ b/spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb @@ -42,7 +42,7 @@ RSpec.describe 'User views an SVG design that contains XSS', :js, feature_catego } # With the page loaded, there should be no alert modal - expect(run_expectation).to raise_error( + expect { run_expectation.call }.to raise_error( Capybara::ModalNotFound, 'Unable to find modal dialog' ) @@ -51,6 +51,6 @@ RSpec.describe 'User views an SVG design that contains XSS', :js, feature_catego # With an alert modal displaying, the modal should be dismissable. execute_script('alert(true)') - expect(run_expectation).not_to raise_error + expect { run_expectation.call }.not_to raise_error end end diff --git a/spec/features/projects/issues/email_participants_spec.rb b/spec/features/projects/issues/email_participants_spec.rb index 4dedbff608e..a902c8294d7 100644 --- a/spec/features/projects/issues/email_participants_spec.rb +++ b/spec/features/projects/issues/email_participants_spec.rb @@ -2,8 +2,9 @@ require 'spec_helper' -RSpec.describe 'viewing an issue', :js, feature_category: :issue_email_participants do +RSpec.describe 'viewing an issue', :js, feature_category: :service_desk do let_it_be(:user) { create(:user) } + let_it_be(:non_member) { create(:user) } let_it_be(:project) { create(:project, :public) } let_it_be_with_refind(:issue) { create(:issue, project: project) } let_it_be(:note) { create(:note_on_issue, project: project, noteable: issue) } @@ -19,9 +20,17 @@ RSpec.describe 'viewing an issue', :js, feature_category: :issue_email_participa end end - shared_examples 'no email participants warning' do |selector| - it 'does not show email participants warning' do - expect(find(selector)).not_to have_content(", and 1 more will be notified of your comment") + shared_examples 'email participants warning in all editors' do + context 'for a new note' do + it_behaves_like 'email participants warning', '.new-note' + end + + context 'for a reply form' do + before do + find('.js-reply-button').click + end + + it_behaves_like 'email participants warning', '.note-edit-form' end end @@ -32,35 +41,42 @@ RSpec.describe 'viewing an issue', :js, feature_category: :issue_email_participa visit project_issue_path(project, issue) end - context 'for a new note' do - it_behaves_like 'email participants warning', '.new-note' - end + it_behaves_like 'email participants warning in all editors' + end - context 'for a reply form' do - before do - find('.js-reply-button').click + context 'when issue is not confidential' do + context 'with signed in user' do + context 'when user has no role in project' do + before do + sign_in(non_member) + visit project_issue_path(project, issue) + end + + it_behaves_like 'email participants warning in all editors' end - it_behaves_like 'email participants warning', '.note-edit-form' + context 'when user has (at least) reporter role in project' do + before do + sign_in(user) + visit project_issue_path(project, issue) + end + + it_behaves_like 'email participants warning in all editors' + end end end - context 'when issue is not confidential' do + context 'for feature flags' do before do sign_in(user) - visit project_issue_path(project, issue) end - context 'for a new note' do - it_behaves_like 'no email participants warning', '.new-note' - end + it 'pushes service_desk_new_note_email_native_attachments feature flag to frontend' do + stub_feature_flags(service_desk_new_note_email_native_attachments: true) - context 'for a reply form' do - before do - find('.js-reply-button').click - end + visit project_issue_path(project, issue) - it_behaves_like 'no email participants warning', '.note-edit-form' + expect(page).to have_pushed_frontend_feature_flags(serviceDeskNewNoteEmailNativeAttachments: true) end end end diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index 78fb72ad2df..dd57b4117f9 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -34,10 +34,6 @@ RSpec.describe 'User browses a job', :js, feature_category: :projects do wait_for_requests expect(page).to have_no_css('.artifacts') - expect(build).not_to have_trace - expect(build.artifacts_file.present?).to be_falsy - expect(build.artifacts_metadata.present?).to be_falsy - expect(page).to have_content('Job has been erased') end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 4734a607ef1..67389fdda8a 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -302,7 +302,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :proj click_link 'Download' end - artifact_request = requests.find { |req| req.url.match(%r{artifacts/download}) } + artifact_request = requests.find { |req| req.url.include?('artifacts/download') } expect(artifact_request.response_headers['Content-Disposition']).to eq(%Q{attachment; filename="#{job.artifacts_file.filename}"; filename*=UTF-8''#{job.artifacts_file.filename}}) expect(artifact_request.response_headers['Content-Transfer-Encoding']).to eq("binary") @@ -745,11 +745,11 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :proj 'You can add CI/CD variables below for last-minute configuration changes before starting the job.' ) ) - expect(page).to have_button('Trigger this manual action') + expect(page).to have_button('Run job') end it 'plays manual action and shows pending status', :js do - click_button 'Trigger this manual action' + click_button 'Run job' wait_for_requests expect(page).to have_content('This job has not started yet') @@ -783,7 +783,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state, feature_category: :proj 'You can add CI/CD variables below for last-minute configuration changes before starting the job.' ) ) - expect(page).to have_button('Trigger this manual action') + expect(page).to have_button('Run job') end end diff --git a/spec/features/projects/network_graph_spec.rb b/spec/features/projects/network_graph_spec.rb index b36fde8a2bf..a29c9f58195 100644 --- a/spec/features/projects/network_graph_spec.rb +++ b/spec/features/projects/network_graph_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Project Network Graph', :js, feature_category: :projects do let(:user) { create :user } let(:project) { create :project, :repository, namespace: user.namespace } + let(:ref_selector) { '.ref-selector' } before do sign_in(user) @@ -16,10 +17,13 @@ RSpec.describe 'Project Network Graph', :js, feature_category: :projects do shared_examples 'network graph' do context 'when branch is master' do def switch_ref_to(ref_name) - first('.js-project-refs-dropdown').click + first(ref_selector).click + wait_for_requests - page.within '.project-refs-form' do - click_link ref_name + page.within ref_selector do + fill_in 'Search by Git revision', with: ref_name + wait_for_requests + find('li', text: ref_name, match: :prefer_exact).click end end @@ -33,7 +37,7 @@ RSpec.describe 'Project Network Graph', :js, feature_category: :projects do it 'renders project network' do expect(page).to have_selector ".network-graph" - expect(page).to have_selector '.dropdown-menu-toggle', text: "master" + expect(page).to have_selector ref_selector, text: "master" page.within '.network-graph' do expect(page).to have_content 'master' end @@ -42,7 +46,7 @@ RSpec.describe 'Project Network Graph', :js, feature_category: :projects do it 'switches ref to branch' do switch_ref_to('feature') - expect(page).to have_selector '.dropdown-menu-toggle', text: 'feature' + expect(page).to have_selector ref_selector, text: 'feature' page.within '.network-graph' do expect(page).to have_content 'feature' end @@ -51,7 +55,7 @@ RSpec.describe 'Project Network Graph', :js, feature_category: :projects do it 'switches ref to tag' do switch_ref_to('v1.0.0') - expect(page).to have_selector '.dropdown-menu-toggle', text: 'v1.0.0' + expect(page).to have_selector ref_selector, text: 'v1.0.0' page.within '.network-graph' do expect(page).to have_content 'v1.0.0' end @@ -64,7 +68,7 @@ RSpec.describe 'Project Network Graph', :js, feature_category: :projects do end expect(page).to have_selector ".network-graph" - expect(page).to have_selector '.dropdown-menu-toggle', text: "master" + expect(page).to have_selector ref_selector, text: "master" page.within '.network-graph' do expect(page).to have_content 'v1.0.0' end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 8beb8af1a8e..3ede76d3360 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -64,7 +64,7 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :projects do it 'shows the pipeline schedule with default ref' do page.within('[data-testid="schedule-target-ref"]') do - expect(first('.gl-dropdown-button-text').text).to eq('master') + expect(first('.gl-button-text').text).to eq('master') end end end @@ -77,7 +77,7 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :projects do it 'shows the pipeline schedule with default ref' do page.within('[data-testid="schedule-target-ref"]') do - expect(first('.gl-dropdown-button-text').text).to eq('master') + expect(first('.gl-button-text').text).to eq('master') end end end @@ -319,7 +319,6 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :projects do end def select_target_branch - find('[data-testid="schedule-target-ref"] .dropdown-toggle').click click_button 'master' end diff --git a/spec/features/projects/pipelines/legacy_pipelines_spec.rb b/spec/features/projects/pipelines/legacy_pipelines_spec.rb deleted file mode 100644 index e69de29bb2d..00000000000 --- a/spec/features/projects/pipelines/legacy_pipelines_spec.rb +++ /dev/null diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index d5739386a30..343c7f53022 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -1233,12 +1233,27 @@ RSpec.describe 'Pipeline', :js, feature_category: :projects do it 'displays the pipeline graph' do subject - expect(page).to have_current_path(pipeline_path(pipeline), ignore_query: true) + expect(page).to have_current_path(pipeline_path(pipeline)) expect(page).to have_selector('.js-pipeline-graph') end end end + describe 'GET /:project/-/pipelines/latest' do + let_it_be(:project) { create(:project, :repository) } + + let!(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } + + before do + visit latest_project_pipelines_path(project) + end + + it 'displays the pipeline graph with correct URL' do + expect(page).to have_current_path("#{pipeline_path(pipeline)}/") + expect(page).to have_selector('.js-pipeline-graph') + end + end + describe 'GET /:project/-/pipelines/:id/dag' do include_context 'pipeline builds' diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 6a44f421249..b5f640f1cca 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -597,8 +597,8 @@ RSpec.describe 'Pipelines', :js, feature_category: :projects do it 'changes the Pipeline ID column for Pipeline IID' do page.find('[data-testid="pipeline-key-collapsible-box"]').click - within '.gl-dropdown-contents' do - dropdown_options = page.find_all '.gl-dropdown-item' + within '.gl-new-dropdown-contents' do + dropdown_options = page.find_all '.gl-new-dropdown-item' dropdown_options[1].click end @@ -675,7 +675,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :projects do click_button project.default_branch wait_for_requests - find('.gl-dropdown-item', text: 'master').click + find('.gl-new-dropdown-item', text: 'master').click wait_for_requests end diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb index ef3b35837ff..b3f21a2d328 100644 --- a/spec/features/projects/releases/user_views_edit_release_spec.rb +++ b/spec/features/projects/releases/user_views_edit_release_spec.rb @@ -41,7 +41,7 @@ RSpec.describe 'User edits Release', :js, feature_category: :continuous_delivery end it 'renders the edit Release form' do - expect(page).to have_content('Releases are based on Git tags. We recommend tags that use semantic versioning, for example v1.0.0, v2.1.0-pre.') + expect(page).to have_content('Releases are based on Git tags. We recommend tags that use semantic versioning, for example 1.0.0, 2.1.0-pre.') expect(find_field('Tag name', disabled: true).value).to eq(release.tag) expect(find_field('Release title').value).to eq(release.name) diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb index 13dde57d885..0a4075be02f 100644 --- a/spec/features/projects/releases/user_views_releases_spec.rb +++ b/spec/features/projects/releases/user_views_releases_spec.rb @@ -46,10 +46,10 @@ RSpec.describe 'User views releases', :js, feature_category: :continuous_deliver external_link_indicator_selector = '[data-testid="external-link-indicator"]' expect(page).to have_link internal_link.name, href: internal_link.url - expect(find_link(internal_link.name)).not_to have_css(external_link_indicator_selector) + expect(find_link(internal_link.name)).to have_css(external_link_indicator_selector) expect(page).to have_link internal_link_with_redirect.name, href: Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << "/downloads#{internal_link_with_redirect.filepath}" - expect(find_link(internal_link_with_redirect.name)).not_to have_css(external_link_indicator_selector) + expect(find_link(internal_link_with_redirect.name)).to have_css(external_link_indicator_selector) expect(page).to have_link external_link.name, href: external_link.url expect(find_link(external_link.name)).to have_css(external_link_indicator_selector) diff --git a/spec/features/projects/settings/packages_settings_spec.rb b/spec/features/projects/settings/packages_settings_spec.rb index 4ef17830f81..bf5c779b109 100644 --- a/spec/features/projects/settings/packages_settings_spec.rb +++ b/spec/features/projects/settings/packages_settings_spec.rb @@ -11,7 +11,6 @@ RSpec.describe 'Projects > Settings > Packages', :js, feature_category: :project sign_in(user) stub_config(packages: { enabled: packages_enabled }) - stub_feature_flags(package_registry_access_level: package_registry_access_level) visit edit_project_path(project) end @@ -19,35 +18,21 @@ RSpec.describe 'Projects > Settings > Packages', :js, feature_category: :project context 'Packages enabled in config' do let(:packages_enabled) { true } - context 'with feature flag disabled' do - let(:package_registry_access_level) { false } - - it 'displays the packages toggle button' do - 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 - - context 'with feature flag enabled' do - let(:package_registry_access_level) { true } - - it 'displays the packages access level setting' do - expect(page).to have_selector('[data-testid="package-registry-access-level"] > label', text: 'Package registry') - expect(page).to have_selector('input[name="package_registry_enabled"]', visible: false) - expect(page).to have_selector('input[name="package_registry_enabled"] + button', visible: true) - expect(page).to have_selector('input[name="package_registry_api_for_everyone_enabled"]', visible: false) - expect(page).to have_selector('input[name="package_registry_api_for_everyone_enabled"] + button', visible: true) - expect(page).to have_selector( - 'input[name="project[project_feature_attributes][package_registry_access_level]"]', - visible: false - ) - end + it 'displays the packages access level setting' do + expect(page).to have_selector('[data-testid="package-registry-access-level"] > label', text: 'Package registry') + expect(page).to have_selector('input[name="package_registry_enabled"]', visible: false) + expect(page).to have_selector('input[name="package_registry_enabled"] + button', visible: true) + expect(page).to have_selector('input[name="package_registry_api_for_everyone_enabled"]', visible: false) + expect(page).to have_selector('input[name="package_registry_api_for_everyone_enabled"] + button', visible: true) + expect(page).to have_selector( + 'input[name="project[project_feature_attributes][package_registry_access_level]"]', + visible: false + ) end end context 'Packages disabled in config' do let(:packages_enabled) { false } - let(:package_registry_access_level) { false } it 'does not show up in UI' do expect(page).not_to have_selector('[data-testid="toggle-label"]', text: 'Packages') diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 6f0a3094849..a0625c93b1a 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Projects > Settings > Repository settings', feature_category: :p before do stub_feature_flags(branch_rules: false) + stub_feature_flags(mirror_only_branches_match_regex: false) project.add_role(user, role) sign_in(user) end diff --git a/spec/features/projects/settings/user_changes_default_branch_spec.rb b/spec/features/projects/settings/user_changes_default_branch_spec.rb index 39704fdbbb2..67ba16a2716 100644 --- a/spec/features/projects/settings/user_changes_default_branch_spec.rb +++ b/spec/features/projects/settings/user_changes_default_branch_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Projects > Settings > User changes default branch', feature_category: :projects do + include ListboxHelpers + let(:user) { create(:user) } before do @@ -20,10 +22,10 @@ RSpec.describe 'Projects > Settings > User changes default branch', feature_cate wait_for_requests expect(page).to have_selector(dropdown_selector) - find(dropdown_selector).click + click_button 'master' + send_keys 'fix' - fill_in 'Search branch', with: 'fix' - click_button 'fix' + select_listbox_item 'fix' page.within '#branch-defaults-settings' do click_button 'Save changes' diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb index fac4d5a99a5..159a83a261d 100644 --- a/spec/features/projects/settings/user_manages_project_members_spec.rb +++ b/spec/features/projects/settings/user_manages_project_members_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Projects > Settings > User manages project members', feature_category: :projects do include Spec::Support::Helpers::Features::MembersHelpers include Spec::Support::Helpers::ModalHelpers + include ListboxHelpers let(:group) { create(:group, name: 'OpenSource') } let(:project) { create(:project, :with_namespace_settings) } @@ -46,7 +47,7 @@ RSpec.describe 'Projects > Settings > User manages project members', feature_cat click_on 'Select a project' wait_for_requests - click_button project2.name + select_listbox_item(project2.name_with_namespace) click_button 'Import project members' wait_for_requests diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb index 8d22d84b9c9..3b8b982b621 100644 --- a/spec/features/projects/settings/webhooks_settings_spec.rb +++ b/spec/features/projects/settings/webhooks_settings_spec.rb @@ -82,8 +82,8 @@ RSpec.describe 'Projects > Settings > Webhook Settings', feature_category: :proj WebMock.stub_request(:post, hook.url) visit webhooks_path - find('.hook-test-button.dropdown').click - click_link 'Push events' + click_button 'Test' + click_button 'Push events' expect(page).to have_current_path(webhooks_path, ignore_query: true) end diff --git a/spec/features/projects/show/clone_button_spec.rb b/spec/features/projects/show/clone_button_spec.rb new file mode 100644 index 00000000000..48af4bf8277 --- /dev/null +++ b/spec/features/projects/show/clone_button_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Projects > Show > Clone button', feature_category: :projects do + let_it_be(:admin) { create(:admin) } + let_it_be(:guest) { create(:user) } + let_it_be(:project) { create(:project, :private, :in_group, :repository) } + + describe 'when checking project main page user' do + context 'with an admin role' do + before do + project.add_owner(admin) + sign_in(admin) + visit project_path(project) + end + + it 'is able to access project page' do + expect(page).to have_content project.name + end + + it 'sees clone button' do + expect(page).to have_content _('Clone') + end + end + + context 'with a guest role and no download_code access' do + before do + project.add_guest(guest) + sign_in(guest) + visit project_path(project) + end + + it 'is able to access project page' do + expect(page).to have_content project.name + end + + it 'does not see clone button' do + expect(page).not_to have_content _('Clone') + end + end + end +end diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index f2c575231ad..06e48bc82c0 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Snippets > Create Snippet', :js, feature_category: :snippets do +RSpec.describe 'Projects > Snippets > Create Snippet', :js, feature_category: :source_code_management do include DropzoneHelper include Spec::Support::Helpers::Features::SnippetSpecHelpers diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb index 1a480696b4e..12018b4b9d7 100644 --- a/spec/features/projects/snippets/show_spec.rb +++ b/spec/features/projects/snippets/show_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Snippets > Project snippet', :js, feature_category: :snippets do +RSpec.describe 'Projects > Snippets > Project snippet', :js, feature_category: :source_code_management do let_it_be(:user) { create(:user) } let_it_be(:project) do create(:project, creator: user).tap do |p| diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb index 556f549f86c..a153298da8e 100644 --- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb +++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Snippets > User comments on a snippet', :js, feature_category: :snippets do +RSpec.describe 'Projects > Snippets > User comments on a snippet', :js, feature_category: :source_code_management do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } let_it_be(:snippet) { create(:project_snippet, :repository, project: project, author: user) } diff --git a/spec/features/projects/snippets/user_deletes_snippet_spec.rb b/spec/features/projects/snippets/user_deletes_snippet_spec.rb index c9d1afb7a4e..6a825fe18de 100644 --- a/spec/features/projects/snippets/user_deletes_snippet_spec.rb +++ b/spec/features/projects/snippets/user_deletes_snippet_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Snippets > User deletes a snippet', :js, feature_category: :snippets do +RSpec.describe 'Projects > Snippets > User deletes a snippet', :js, feature_category: :source_code_management do let(:project) { create(:project) } let!(:snippet) { create(:project_snippet, :repository, project: project, author: user) } let(:user) { create(:user) } diff --git a/spec/features/projects/snippets/user_updates_snippet_spec.rb b/spec/features/projects/snippets/user_updates_snippet_spec.rb index 205db6c08b1..014bf63c696 100644 --- a/spec/features/projects/snippets/user_updates_snippet_spec.rb +++ b/spec/features/projects/snippets/user_updates_snippet_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Snippets > User updates a snippet', :js, feature_category: :snippets do +RSpec.describe 'Projects > Snippets > User updates a snippet', :js, feature_category: :source_code_management do include Spec::Support::Helpers::Features::SnippetSpecHelpers let_it_be(:user) { create(:user) } diff --git a/spec/features/projects/snippets/user_views_snippets_spec.rb b/spec/features/projects/snippets/user_views_snippets_spec.rb index ece65763ea5..a6d1db2b02f 100644 --- a/spec/features/projects/snippets/user_views_snippets_spec.rb +++ b/spec/features/projects/snippets/user_views_snippets_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Projects > Snippets > User views snippets', feature_category: :snippets do +RSpec.describe 'Projects > Snippets > User views snippets', feature_category: :source_code_management do let_it_be(:project) { create(:project) } let(:user) { create(:user) } diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb index 835a3cda65e..52c6cb2192b 100644 --- a/spec/features/projects/tree/tree_show_spec.rb +++ b/spec/features/projects/tree/tree_show_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Projects tree', :js, feature_category: :web_ide do include WebIdeSpecHelpers include RepoHelpers + include ListboxHelpers let(:user) { create(:user) } let(:project) { create(:project, :repository) } @@ -93,8 +94,8 @@ RSpec.describe 'Projects tree', :js, feature_category: :web_ide do visit project_tree_path(project, '33f3729a45c02fc67d00adb1b8bca394b0e761d9') wait_for_requests - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end context 'on a directory that has not changed recently' do @@ -103,8 +104,8 @@ RSpec.describe 'Projects tree', :js, feature_category: :web_ide do visit project_tree_path(project, tree_path) wait_for_requests - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end end end @@ -151,26 +152,22 @@ RSpec.describe 'Projects tree', :js, feature_category: :web_ide do visit project_tree_path(project, '33f3729a45c02fc67d00adb1b8bca394b0e761d9') wait_for_requests - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end end end context 'ref switcher', :js do - it 'switches ref to branch' do + it 'switches ref to branch', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391780' do ref_selector = '.ref-selector' - ref_name = 'feature' + ref_name = 'fix' visit project_tree_path(project, 'master') - find(ref_selector).click - wait_for_requests + click_button 'master' + send_keys ref_name - page.within(ref_selector) do - fill_in 'Search by Git revision', with: ref_name - wait_for_requests - find('li', text: ref_name, match: :prefer_exact).click - end + select_listbox_item ref_name expect(find(ref_selector)).to have_text(ref_name) end diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb index 352fa73bd05..e2b56e8ced6 100644 --- a/spec/features/projects/user_views_empty_project_spec.rb +++ b/spec/features/projects/user_views_empty_project_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'User views an empty project', feature_category: :projects do + include Spec::Support::Helpers::Features::InviteMembersModalHelper + let_it_be(:project) { create(:project, :empty_repo) } let_it_be(:user) { create(:user) } @@ -29,7 +31,9 @@ RSpec.describe 'User views an empty project', feature_category: :projects do click_button 'Invite members' - expect(page).to have_content("You're inviting members to the") + page.within invite_modal_selector do + expect(page).to have_content("You're inviting members to the #{project.name} project") + end end end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 84702b3a6bb..73ee250a8b8 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -343,8 +343,8 @@ RSpec.describe 'Project', feature_category: :projects do visit project_path(project) wait_for_requests - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end end @@ -371,8 +371,8 @@ RSpec.describe 'Project', feature_category: :projects do visit project_path(project) wait_for_requests - expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge' - expect(page).to have_selector '.gpg-status-box.invalid' + expect(page).not_to have_selector '.gl-badge.js-loading-signature-badge' + expect(page).to have_selector '.gl-badge.badge-muted' end end end diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index e7c2452af93..b2ddf427c0d 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -64,10 +64,10 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do context 'when a project_type runner is activated on the project' do let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) } - it 'user sees the specific runner' do + it 'user sees the project runner' do visit project_runners_path(project) - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do expect(page).to have_content(project_runner.display_name) end @@ -76,30 +76,30 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do expect(page).to have_content(project_runner.platform) end - it 'user can pause and resume the specific runner' do + it 'user can pause and resume the project runner' do visit project_runners_path(project) - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do expect(page).to have_link('Pause') end click_on 'Pause' - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do expect(page).to have_link('Resume') end click_on 'Resume' - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do expect(page).to have_link('Pause') end end - it 'user removes an activated specific runner if this is last project for that runners' do + it 'user removes an activated project runner if this is last project for that runners' do visit project_runners_path(project) - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do click_on 'Remove runner' end @@ -109,7 +109,7 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do it 'user edits the runner to be protected' do visit project_runners_path(project) - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do first('[data-testid="edit-runner-link"]').click end @@ -129,7 +129,7 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do it 'user edits runner not to run untagged jobs' do visit project_runners_path(project) - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do first('[data-testid="edit-runner-link"]').click end @@ -189,7 +189,7 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do end end - context 'when a specific runner exists in another project' do + context 'when a project runner exists in another project' do let(:another_project) { create(:project) } let!(:project_runner) { create(:ci_runner, :project, projects: [another_project]) } @@ -197,20 +197,20 @@ RSpec.describe 'Runners', feature_category: :runner_fleet do another_project.add_maintainer(user) end - it 'user enables and disables a specific runner' do + it 'user enables and disables a project runner' do visit project_runners_path(project) - within '.available-specific-runners' do + within '[data-testid="available_project_runners"]' do click_on 'Enable for this project' end - expect(page.find('.activated-specific-runners')).to have_content(project_runner.display_name) + expect(page.find('[data-testid="assigned_project_runners"]')).to have_content(project_runner.display_name) - within '.activated-specific-runners' do + within '[data-testid="assigned_project_runners"]' do click_on 'Disable for this project' end - expect(page.find('.available-specific-runners')).to have_content(project_runner.display_name) + expect(page.find('[data-testid="available_project_runners"]')).to have_content(project_runner.display_name) end end diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb index dd7095107f4..b7d06a3a962 100644 --- a/spec/features/search/user_searches_for_code_spec.rb +++ b/spec/features/search/user_searches_for_code_spec.rb @@ -4,241 +4,221 @@ require 'spec_helper' RSpec.describe 'User searches for code', :js, :disable_rate_limiter, feature_category: :global_search do using RSpec::Parameterized::TableSyntax + include ListboxHelpers let_it_be(:user) { create(:user) } let_it_be_with_reload(:project) { create(:project, :repository, namespace: user.namespace) } - where(search_page_vertical_nav_enabled: [true, false]) - with_them do - context 'when signed in' do + context 'when signed in' do + before do + project.add_maintainer(user) + sign_in(user) + end + + context 'when on a project page' do before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - project.add_maintainer(user) - sign_in(user) + visit(project_path(project)) end - context 'when on a project page' do - before do - visit(project_path(project)) - end - - it 'finds a file' do - submit_search('application.js') - select_search_scope('Code') + it 'finds a file' do + submit_search('application.js') + select_search_scope('Code') - expect(page).to have_selector('.results', text: 'application.js') - expect(page).to have_selector('.file-content .code') - expect(page).to have_selector("span.line[lang='javascript']") - expect(page).to have_link('application.js', href: %r{master/files/js/application.js}) - expect(page).to have_button('Copy file path') - end + expect(page).to have_selector('.results', text: 'application.js') + expect(page).to have_selector('.file-content .code') + expect(page).to have_selector("span.line[lang='javascript']") + expect(page).to have_link('application.js', href: %r{master/files/js/application.js}) + expect(page).to have_button('Copy file path') end + end - context 'when on a project search page' do - before do - visit(search_path) - find('[data-testid="project-filter"]').click + context 'when on a project search page' do + before do + visit(search_path) + find('[data-testid="project-filter"]').click - wait_for_requests + wait_for_requests - page.within('[data-testid="project-filter"]') do - click_on(project.name) - end + page.within('[data-testid="project-filter"]') do + click_on(project.name) end + end - include_examples 'top right search form' - include_examples 'search timeouts', 'blobs' do - let(:additional_params) { { project_id: project.id } } - end + include_examples 'top right search form' + include_examples 'search timeouts', 'blobs' do + let(:additional_params) { { project_id: project.id } } + end - context 'when searching code' do - let(:expected_result) { 'Update capybara, rspec-rails, poltergeist to recent versions' } + context 'when searching code' do + let(:expected_result) { 'Update capybara, rspec-rails, poltergeist to recent versions' } - before do - fill_in('dashboard_search', with: 'rspec') - find('.gl-search-box-by-click-search-button').click - end + before do + fill_in('dashboard_search', with: 'rspec') + find('.gl-search-box-by-click-search-button').click + end - it 'finds code and links to blob' do - expect(page).to have_selector('.results', text: expected_result) + it 'finds code and links to blob' do + expect(page).to have_selector('.results', text: expected_result) - find("#blob-L3").click - expect(current_url).to match(%r{blob/master/.gitignore#L3}) - end + find("#blob-L3").click + expect(current_url).to match(%r{blob/master/.gitignore#L3}) + end - it 'finds code and links to blame' do - expect(page).to have_selector('.results', text: expected_result) + it 'finds code and links to blame' do + expect(page).to have_selector('.results', text: expected_result) - find("#blame-L3").click - expect(current_url).to match(%r{blame/master/.gitignore#L3}) - end + find("#blame-L3").click + expect(current_url).to match(%r{blame/master/.gitignore#L3}) + end - it_behaves_like 'code highlight' do - subject { page } - end + it_behaves_like 'code highlight' do + subject { page } end + end - it 'search multiple words with refs switching' do - expected_result = 'Use `snake_case` for naming files' - search = 'for naming files' + it 'search multiple words with refs switching' do + expected_result = 'Use `snake_case` for naming files' + search = 'for naming files' + ref_selector = 'v1.0.0' - fill_in('dashboard_search', with: search) - find('.gl-search-box-by-click-search-button').click + fill_in('dashboard_search', with: search) + find('.gl-search-box-by-click-search-button').click - expect(page).to have_selector('.results', text: expected_result) + expect(page).to have_selector('.results', text: expected_result) - find('.ref-selector').click - wait_for_requests + click_button 'master' + wait_for_requests - page.within('.ref-selector') do - find('li', text: 'v1.0.0').click - end + select_listbox_item(ref_selector) - expect(page).to have_selector('.results', text: expected_result) + expect(page).to have_selector('.results', text: expected_result) - expect(find_field('dashboard_search').value).to eq(search) - expect(find("#blob-L1502")[:href]).to match(%r{blob/v1.0.0/files/markdown/ruby-style-guide.md#L1502}) - expect(find("#blame-L1502")[:href]).to match(%r{blame/v1.0.0/files/markdown/ruby-style-guide.md#L1502}) - end + expect(find_field('dashboard_search').value).to eq(search) + expect(find("#blob-L1502")[:href]).to match(%r{blob/v1.0.0/files/markdown/ruby-style-guide.md#L1502}) + expect(find("#blame-L1502")[:href]).to match(%r{blame/v1.0.0/files/markdown/ruby-style-guide.md#L1502}) end + end - context 'when :new_header_search is true' do - context 'search code within refs' do - let(:ref_name) { 'v1.0.0' } + context 'when :new_header_search is true' do + context 'search code within refs' do + let(:ref_name) { 'v1.0.0' } - before do - # This feature is disabled by default in spec_helper.rb. - # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec. - # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348. - stub_feature_flags(new_header_search: true) - visit(project_tree_path(project, ref_name)) + before do + # This feature is disabled by default in spec_helper.rb. + # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec. + # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348. + stub_feature_flags(new_header_search: true) + visit(project_tree_path(project, ref_name)) - submit_search('gitlab-grack') - select_search_scope('Code') - end + submit_search('gitlab-grack') + select_search_scope('Code') + end - it 'shows ref switcher in code result summary' do - expect(find('.ref-selector')).to have_text(ref_name) - end + it 'shows ref switcher in code result summary' do + expect(find('.ref-selector')).to have_text(ref_name) + end - it 'persists branch name across search' do - find('.gl-search-box-by-click-search-button').click - expect(find('.ref-selector')).to have_text(ref_name) - end + it 'persists branch name across search' do + find('.gl-search-box-by-click-search-button').click + expect(find('.ref-selector')).to have_text(ref_name) + end - # this example is use to test the design that the refs is not - # only represent the branch as well as the tags. - it 'ref switcher list all the branches and tags' do - find('.ref-selector').click - wait_for_requests + # this example is use to test the design that the refs is not + # only represent the branch as well as the tags. + it 'ref switcher list all the branches and tags' do + find('.ref-selector').click + wait_for_requests - page.within('.ref-selector') do - expect(page).to have_selector('li', text: 'add-ipython-files') - expect(page).to have_selector('li', text: 'v1.0.0') - end + page.within('.ref-selector') do + expect(page).to have_selector('li', text: 'add-ipython-files') + expect(page).to have_selector('li', text: 'v1.0.0') end + end - it 'search result changes when refs switched' do - ref = 'master' - expect(find('.results')).not_to have_content('path = gitlab-grack') - - find('.ref-selector').click - wait_for_requests + it 'search result changes when refs switched' do + expect(find('.results')).not_to have_content('path = gitlab-grack') - page.within('.ref-selector') do - fill_in _('Search by Git revision'), with: ref - wait_for_requests + find('.ref-selector').click + wait_for_requests - find('li', text: ref).click - end + select_listbox_item('add-ipython-files') - expect(page).to have_selector('.results', text: 'path = gitlab-grack') - end + expect(page).to have_selector('.results', text: 'path = gitlab-grack') end end + end - context 'when :new_header_search is false' do - context 'search code within refs' do - let(:ref_name) { 'v1.0.0' } + context 'when :new_header_search is false' do + context 'search code within refs' do + let(:ref_name) { 'v1.0.0' } - before do - # This feature is disabled by default in spec_helper.rb. - # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec. - # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348. - stub_feature_flags(new_header_search: false) - visit(project_tree_path(project, ref_name)) + before do + # This feature is disabled by default in spec_helper.rb. + # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec. + # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348. + stub_feature_flags(new_header_search: false) + visit(project_tree_path(project, ref_name)) - submit_search('gitlab-grack') - select_search_scope('Code') - end + submit_search('gitlab-grack') + select_search_scope('Code') + end - it 'shows ref switcher in code result summary' do - expect(find('.ref-selector')).to have_text(ref_name) - end + it 'shows ref switcher in code result summary' do + expect(find('.ref-selector')).to have_text(ref_name) + end - it 'persists branch name across search' do - find('.gl-search-box-by-click-search-button').click - expect(find('.ref-selector')).to have_text(ref_name) - end + it 'persists branch name across search' do + find('.gl-search-box-by-click-search-button').click + expect(find('.ref-selector')).to have_text(ref_name) + end - # this example is use to test the design that the refs is not - # only represent the branch as well as the tags. - it 'ref switcher list all the branches and tags' do - find('.ref-selector').click - wait_for_requests + # this example is use to test the design that the refs is not + # only represent the branch as well as the tags. + it 'ref switcher list all the branches and tags' do + find('.ref-selector').click + wait_for_requests - page.within('.ref-selector') do - expect(page).to have_selector('li', text: 'add-ipython-files') - expect(page).to have_selector('li', text: 'v1.0.0') - end + page.within('.ref-selector') do + expect(page).to have_selector('li', text: 'add-ipython-files') + expect(page).to have_selector('li', text: 'v1.0.0') end + end - it 'search result changes when refs switched' do - ref = 'master' - expect(find('.results')).not_to have_content('path = gitlab-grack') - - find('.ref-selector').click - wait_for_requests + it 'search result changes when refs switched' do + expect(find('.results')).not_to have_content('path = gitlab-grack') - page.within('.ref-selector') do - fill_in _('Search by Git revision'), with: ref - wait_for_requests + find('.ref-selector').click + wait_for_requests - find('li', text: ref).click - end + select_listbox_item('add-ipython-files') - expect(page).to have_selector('.results', text: 'path = gitlab-grack') - end + expect(page).to have_selector('.results', text: 'path = gitlab-grack') end end + end - it 'no ref switcher shown in issue result summary' do - issue = create(:issue, title: 'test', project: project) - visit(project_tree_path(project)) + it 'no ref switcher shown in issue result summary' do + issue = create(:issue, title: 'test', project: project) + visit(project_tree_path(project)) - submit_search('test') - select_search_scope('Code') + submit_search('test') + select_search_scope('Code') - expect(page).to have_selector('.ref-selector') + expect(page).to have_selector('.ref-selector') - select_search_scope('Issues') + select_search_scope('Issues') - expect(find(:css, '.results')).to have_link(issue.title) - expect(page).not_to have_selector('.ref-selector') - end + expect(find(:css, '.results')).to have_link(issue.title) + expect(page).not_to have_selector('.ref-selector') end + end - context 'when signed out' do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - end - - context 'when block_anonymous_global_searches is enabled' do - it 'is redirected to login page' do - visit(search_path) + context 'when signed out' do + context 'when block_anonymous_global_searches is enabled' do + it 'is redirected to login page' do + visit(search_path) - expect(page).to have_content('You must be logged in to search across all of GitLab') - end + expect(page).to have_content('You must be logged in to search across all of GitLab') end end end diff --git a/spec/features/search/user_searches_for_comments_spec.rb b/spec/features/search/user_searches_for_comments_spec.rb index d7f6143d173..f7af1797c71 100644 --- a/spec/features/search/user_searches_for_comments_spec.rb +++ b/spec/features/search/user_searches_for_comments_spec.rb @@ -3,51 +3,45 @@ require 'spec_helper' RSpec.describe 'User searches for comments', :js, :disable_rate_limiter, feature_category: :global_search do - using RSpec::Parameterized::TableSyntax - let_it_be(:project) { create(:project, :repository) } let_it_be(:user) { create(:user) } - where(search_page_vertical_nav_enabled: [true, false]) - with_them do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - project.add_reporter(user) - sign_in(user) + before do + project.add_reporter(user) + sign_in(user) - visit(project_path(project)) - end + visit(project_path(project)) + end - include_examples 'search timeouts', 'notes' do - let(:additional_params) { { project_id: project.id } } - end + include_examples 'search timeouts', 'notes' do + let(:additional_params) { { project_id: project.id } } + end - context 'when a comment is in commits' do - context 'when comment belongs to an invalid commit' do - let(:comment) { create(:note_on_commit, author: user, project: project, commit_id: 12345678, note: 'Bug here') } + context 'when a comment is in commits' do + context 'when comment belongs to an invalid commit' do + let(:comment) { create(:note_on_commit, author: user, project: project, commit_id: 12345678, note: 'Bug here') } - it 'finds a commit' do - submit_search(comment.note) - select_search_scope('Comments') + it 'finds a commit' do + submit_search(comment.note) + select_search_scope('Comments') - page.within('.results') do - expect(page).to have_content('Commit deleted') - expect(page).to have_content('12345678') - end + page.within('.results') do + expect(page).to have_content('Commit deleted') + expect(page).to have_content('12345678') end end end + end - context 'when a comment is in a snippet' do - let(:snippet) { create(:project_snippet, :private, project: project, author: user, title: 'Some title') } - let(:comment) { create(:note, noteable: snippet, author: user, note: 'Supercalifragilisticexpialidocious', project: project) } + context 'when a comment is in a snippet' do + let(:snippet) { create(:project_snippet, :private, project: project, author: user, title: 'Some title') } + let(:comment) { create(:note, noteable: snippet, author: user, note: 'Supercalifragilisticexpialidocious', project: project) } - it 'finds a snippet' do - submit_search(comment.note) - select_search_scope('Comments') + it 'finds a snippet' do + submit_search(comment.note) + select_search_scope('Comments') - expect(page).to have_selector('.results', text: snippet.title) - end + expect(page).to have_selector('.results', text: snippet.title) end end end diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb index 1fd62a01c78..724daf9277d 100644 --- a/spec/features/search/user_searches_for_commits_spec.rb +++ b/spec/features/search/user_searches_for_commits_spec.rb @@ -3,61 +3,55 @@ require 'spec_helper' RSpec.describe 'User searches for commits', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - using RSpec::Parameterized::TableSyntax - let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository) } - let(:project) { create(:project, :repository) } let(:sha) { '6d394385cf567f80a8fd85055db1ab4c5295806f' } - where(search_page_vertical_nav_enabled: [true, false]) - with_them do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - project.add_reporter(user) - sign_in(user) + before do + project.add_reporter(user) + sign_in(user) - visit(search_path(project_id: project.id)) - end + visit(search_path(project_id: project.id)) + end - include_examples 'search timeouts', 'commits' do - let(:additional_params) { { project_id: project.id } } - end + include_examples 'search timeouts', 'commits' do + let(:additional_params) { { project_id: project.id } } + end - context 'when searching by SHA' do - it 'finds a commit and redirects to its page' do - submit_search(sha) + context 'when searching by SHA' do + it 'finds a commit and redirects to its page' do + submit_search(sha) - expect(page).to have_current_path(project_commit_path(project, sha)) - end + expect(page).to have_current_path(project_commit_path(project, sha)) + end - it 'finds a commit in uppercase and redirects to its page' do - submit_search(sha.upcase) + it 'finds a commit in uppercase and redirects to its page' do + submit_search(sha.upcase) - expect(page).to have_current_path(project_commit_path(project, sha)) - end + expect(page).to have_current_path(project_commit_path(project, sha)) end + end - context 'when searching by message' do - it 'finds a commit and holds on /search page' do - project.repository.commit_files( - user, - message: 'Message referencing another sha: "deadbeef"', - branch_name: 'master', - actions: [{ action: :create, file_path: 'a/new.file', contents: 'new file' }] - ) + context 'when searching by message' do + it 'finds a commit and holds on /search page' do + project.repository.commit_files( + user, + message: 'Message referencing another sha: "deadbeef"', + branch_name: 'master', + actions: [{ action: :create, file_path: 'a/new.file', contents: 'new file' }] + ) - submit_search('deadbeef') + submit_search('deadbeef') - expect(page).to have_current_path('/search', ignore_query: true) - end + expect(page).to have_current_path('/search', ignore_query: true) + end - it 'finds multiple commits' do - submit_search('See merge request') - select_search_scope('Commits') + it 'finds multiple commits' do + submit_search('See merge request') + select_search_scope('Commits') - expect(page).to have_selector('.commit-row-description', visible: false, count: 9) - end + expect(page).to have_selector('.commit-row-description', visible: false, count: 9) end end end diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb index 6ebbe86d1a9..9451e337db1 100644 --- a/spec/features/search/user_searches_for_issues_spec.rb +++ b/spec/features/search/user_searches_for_issues_spec.rb @@ -3,8 +3,6 @@ require 'spec_helper' RSpec.describe 'User searches for issues', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - using RSpec::Parameterized::TableSyntax - let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, namespace: user.namespace) } @@ -17,133 +15,123 @@ RSpec.describe 'User searches for issues', :js, :clean_gitlab_redis_rate_limitin select_search_scope('Issues') end - where(search_page_vertical_nav_enabled: [true, false]) - - with_them do - context 'when signed in' do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) + context 'when signed in' do + before do + project.add_maintainer(user) + sign_in(user) - project.add_maintainer(user) - sign_in(user) + visit(search_path) + end - visit(search_path) - end + include_examples 'top right search form' + include_examples 'search timeouts', 'issues' - include_examples 'top right search form' - include_examples 'search timeouts', 'issues' + it 'finds an issue' do + search_for_issue(issue1.title) - it 'finds an issue' do - search_for_issue(issue1.title) - - page.within('.results') do - expect(page).to have_link(issue1.title) - expect(page).not_to have_link(issue2.title) - end + page.within('.results') do + expect(page).to have_link(issue1.title) + expect(page).not_to have_link(issue2.title) end + end - it 'hides confidential icon for non-confidential issues' do - search_for_issue(issue1.title) + it 'hides confidential icon for non-confidential issues' do + search_for_issue(issue1.title) - page.within('.results') do - expect(page).not_to have_css('[data-testid="eye-slash-icon"]') - end + page.within('.results') do + expect(page).not_to have_css('[data-testid="eye-slash-icon"]') end + end - it 'shows confidential icon for confidential issues' do - search_for_issue(issue2.title) + it 'shows confidential icon for confidential issues' do + search_for_issue(issue2.title) - page.within('.results') do - expect(page).to have_css('[data-testid="eye-slash-icon"]') - end + page.within('.results') do + expect(page).to have_css('[data-testid="eye-slash-icon"]') end + end - it 'shows correct badge for open issues' do - search_for_issue(issue1.title) + it 'shows correct badge for open issues' do + search_for_issue(issue1.title) - page.within('.results') do - expect(page).to have_css('.badge-success') - expect(page).not_to have_css('.badge-info') - end + page.within('.results') do + expect(page).to have_css('.badge-success') + expect(page).not_to have_css('.badge-info') end + end - it 'shows correct badge for closed issues' do - search_for_issue(issue2.title) + it 'shows correct badge for closed issues' do + search_for_issue(issue2.title) - page.within('.results') do - expect(page).not_to have_css('.badge-success') - expect(page).to have_css('.badge-info') - end + page.within('.results') do + expect(page).not_to have_css('.badge-success') + expect(page).to have_css('.badge-info') end + end - it 'sorts by created date' do - search_for_issue('issue') + it 'sorts by created date' do + search_for_issue('issue') - page.within('.results') do - expect(page.all('.search-result-row').first).to have_link(issue2.title) - expect(page.all('.search-result-row').last).to have_link(issue1.title) - end + page.within('.results') do + expect(page.all('.search-result-row').first).to have_link(issue2.title) + expect(page.all('.search-result-row').last).to have_link(issue1.title) + end - find('[data-testid="sort-highest-icon"]').click + find('[data-testid="sort-highest-icon"]').click - page.within('.results') do - expect(page.all('.search-result-row').first).to have_link(issue1.title) - expect(page.all('.search-result-row').last).to have_link(issue2.title) - end + page.within('.results') do + expect(page.all('.search-result-row').first).to have_link(issue1.title) + expect(page.all('.search-result-row').last).to have_link(issue2.title) end + end - context 'when on a project page' do - it 'finds an issue' do - find('[data-testid="project-filter"]').click + context 'when on a project page' do + it 'finds an issue' do + find('[data-testid="project-filter"]').click - wait_for_requests + wait_for_requests - page.within('[data-testid="project-filter"]') do - click_on(project.name) - end + page.within('[data-testid="project-filter"]') do + click_on(project.name) + end - search_for_issue(issue1.title) + search_for_issue(issue1.title) - page.within('.results') do - expect(page).to have_link(issue1.title) - expect(page).not_to have_link(issue2.title) - end + page.within('.results') do + expect(page).to have_link(issue1.title) + expect(page).not_to have_link(issue2.title) end end end + end - context 'when signed out' do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - end - - context 'when block_anonymous_global_searches is disabled' do - let_it_be(:project) { create(:project, :public) } + context 'when signed out' do + context 'when block_anonymous_global_searches is disabled' do + let_it_be(:project) { create(:project, :public) } - before do - stub_feature_flags(block_anonymous_global_searches: false) + before do + stub_feature_flags(block_anonymous_global_searches: false) - visit(search_path) - end + visit(search_path) + end - include_examples 'top right search form' + include_examples 'top right search form' - it 'finds an issue' do - search_for_issue(issue1.title) + it 'finds an issue' do + search_for_issue(issue1.title) - page.within('.results') do - expect(page).to have_link(issue1.title) - expect(page).not_to have_link(issue2.title) - end + page.within('.results') do + expect(page).to have_link(issue1.title) + expect(page).not_to have_link(issue2.title) end end + end - context 'when block_anonymous_global_searches is enabled' do - it 'is redirected to login page' do - visit(search_path) + context 'when block_anonymous_global_searches is enabled' do + it 'is redirected to login page' do + visit(search_path) - expect(page).to have_content('You must be logged in to search across all of GitLab') - end + expect(page).to have_content('You must be logged in to search across all of GitLab') end end end diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb index 69f62a4c1e2..d7b52d9e07a 100644 --- a/spec/features/search/user_searches_for_merge_requests_spec.rb +++ b/spec/features/search/user_searches_for_merge_requests_spec.rb @@ -3,12 +3,10 @@ require 'spec_helper' RSpec.describe 'User searches for merge requests', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - using RSpec::Parameterized::TableSyntax - - let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } - let!(:merge_request1) { create(:merge_request, title: 'Merge Request Foo', source_project: project, target_project: project, created_at: 1.hour.ago) } - let!(:merge_request2) { create(:merge_request, :simple, title: 'Merge Request Bar', source_project: project, target_project: project) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, namespace: user.namespace) } + let_it_be(:merge_request1) { create(:merge_request, title: 'Merge Request Foo', source_project: project, target_project: project, created_at: 1.hour.ago) } + let_it_be(:merge_request2) { create(:merge_request, :simple, title: 'Merge Request Bar', source_project: project, target_project: project) } def search_for_mr(search) fill_in('dashboard_search', with: search) @@ -16,64 +14,60 @@ RSpec.describe 'User searches for merge requests', :js, :clean_gitlab_redis_rate select_search_scope('Merge requests') end - where(search_page_vertical_nav_enabled: [true, false]) - with_them do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - sign_in(user) + before do + sign_in(user) - visit(search_path) - end + visit(search_path) + end - include_examples 'top right search form' - include_examples 'search timeouts', 'merge_requests' + include_examples 'top right search form' + include_examples 'search timeouts', 'merge_requests' - it 'finds a merge request' do - search_for_mr(merge_request1.title) + it 'finds a merge request' do + search_for_mr(merge_request1.title) - page.within('.results') do - expect(page).to have_link(merge_request1.title) - expect(page).not_to have_link(merge_request2.title) + page.within('.results') do + expect(page).to have_link(merge_request1.title) + expect(page).not_to have_link(merge_request2.title) - # Each result should have MR refs like `gitlab-org/gitlab!1` - page.all('.search-result-row').each do |e| - expect(e.text).to match(/!\d+/) - end + # Each result should have MR refs like `gitlab-org/gitlab!1` + page.all('.search-result-row').each do |e| + expect(e.text).to match(/!\d+/) end end + end - it 'sorts by created date' do - search_for_mr('Merge Request') + it 'sorts by created date' do + search_for_mr('Merge Request') - page.within('.results') do - expect(page.all('.search-result-row').first).to have_link(merge_request2.title) - expect(page.all('.search-result-row').last).to have_link(merge_request1.title) - end + page.within('.results') do + expect(page.all('.search-result-row').first).to have_link(merge_request2.title) + expect(page.all('.search-result-row').last).to have_link(merge_request1.title) + end - find('[data-testid="sort-highest-icon"]').click + find('[data-testid="sort-highest-icon"]').click - page.within('.results') do - expect(page.all('.search-result-row').first).to have_link(merge_request1.title) - expect(page.all('.search-result-row').last).to have_link(merge_request2.title) - end + page.within('.results') do + expect(page.all('.search-result-row').first).to have_link(merge_request1.title) + expect(page.all('.search-result-row').last).to have_link(merge_request2.title) end + end - context 'when on a project page' do - it 'finds a merge request' do - find('[data-testid="project-filter"]').click + context 'when on a project page' do + it 'finds a merge request' do + find('[data-testid="project-filter"]').click - wait_for_requests + wait_for_requests - page.within('[data-testid="project-filter"]') do - click_on(project.name) - end + page.within('[data-testid="project-filter"]') do + click_on(project.name) + end - search_for_mr(merge_request1.title) + search_for_mr(merge_request1.title) - page.within('.results') do - expect(page).to have_link(merge_request1.title) - expect(page).not_to have_link(merge_request2.title) - end + page.within('.results') do + expect(page).to have_link(merge_request1.title) + expect(page).not_to have_link(merge_request2.title) end end end diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb index e87c2176380..238e59be940 100644 --- a/spec/features/search/user_searches_for_milestones_spec.rb +++ b/spec/features/search/user_searches_for_milestones_spec.rb @@ -4,29 +4,42 @@ require 'spec_helper' RSpec.describe 'User searches for milestones', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - using RSpec::Parameterized::TableSyntax - let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, namespace: user.namespace) } + let_it_be(:milestone1) { create(:milestone, title: 'Foo', project: project) } + let_it_be(:milestone2) { create(:milestone, title: 'Bar', project: project) } + + before do + project.add_maintainer(user) + sign_in(user) - let!(:milestone1) { create(:milestone, title: 'Foo', project: project) } - let!(:milestone2) { create(:milestone, title: 'Bar', project: project) } + visit(search_path) + end - where(search_page_vertical_nav_enabled: [true, false]) + include_examples 'top right search form' + include_examples 'search timeouts', 'milestones' - with_them do - before do - project.add_maintainer(user) - sign_in(user) - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) + it 'finds a milestone' do + fill_in('dashboard_search', with: milestone1.title) + find('.gl-search-box-by-click-search-button').click + select_search_scope('Milestones') - visit(search_path) + page.within('.results') do + expect(page).to have_link(milestone1.title) + expect(page).not_to have_link(milestone2.title) end + end - include_examples 'top right search form' - include_examples 'search timeouts', 'milestones' - + context 'when on a project page' do it 'finds a milestone' do + find('[data-testid="project-filter"]').click + + wait_for_requests + + page.within('[data-testid="project-filter"]') do + click_on(project.name) + end + fill_in('dashboard_search', with: milestone1.title) find('.gl-search-box-by-click-search-button').click select_search_scope('Milestones') @@ -36,26 +49,5 @@ feature_category: :global_search do expect(page).not_to have_link(milestone2.title) end end - - context 'when on a project page' do - it 'finds a milestone' do - find('[data-testid="project-filter"]').click - - wait_for_requests - - page.within('[data-testid="project-filter"]') do - click_on(project.name) - end - - fill_in('dashboard_search', with: milestone1.title) - find('.gl-search-box-by-click-search-button').click - select_search_scope('Milestones') - - page.within('.results') do - expect(page).to have_link(milestone1.title) - expect(page).not_to have_link(milestone2.title) - end - end - end end end diff --git a/spec/features/search/user_searches_for_users_spec.rb b/spec/features/search/user_searches_for_users_spec.rb index 4737cef98c7..e0a07c5103d 100644 --- a/spec/features/search/user_searches_for_users_spec.rb +++ b/spec/features/search/user_searches_for_users_spec.rb @@ -7,85 +7,80 @@ RSpec.describe 'User searches for users', :js, :clean_gitlab_redis_rate_limiting let_it_be(:user2) { create(:user, username: 'michael_bluth', name: 'Michael Bluth') } let_it_be(:user3) { create(:user, username: 'gob_2018', name: 'George Oscar Bluth') } - where(search_page_vertical_nav_enabled: [true, false]) - with_them do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - - sign_in(user1) - end + before do + sign_in(user1) + end - include_examples 'search timeouts', 'users' do - before do - visit(search_path) - end + include_examples 'search timeouts', 'users' do + before do + visit(search_path) end + end - context 'when on the dashboard' do - it 'finds the user' do - visit dashboard_projects_path + context 'when on the dashboard' do + it 'finds the user' do + visit dashboard_projects_path - submit_search('gob') - select_search_scope('Users') + submit_search('gob') + select_search_scope('Users') - page.within('.results') do - expect(page).to have_content('Gob Bluth') - expect(page).to have_content('@gob_bluth') - end + page.within('.results') do + expect(page).to have_content('Gob Bluth') + expect(page).to have_content('@gob_bluth') end end + end - context 'when on the project page' do - let_it_be_with_reload(:project) { create(:project) } + context 'when on the project page' do + let_it_be_with_reload(:project) { create(:project) } - before do - project.add_developer(user1) - project.add_developer(user2) - end + before do + project.add_developer(user1) + project.add_developer(user2) + end - it 'finds the user belonging to the project' do - visit project_path(project) + it 'finds the user belonging to the project' do + visit project_path(project) - submit_search('gob') - select_search_scope('Users') + submit_search('gob') + select_search_scope('Users') - page.within('.results') do - expect(page).to have_content('Gob Bluth') - expect(page).to have_content('@gob_bluth') + page.within('.results') do + expect(page).to have_content('Gob Bluth') + expect(page).to have_content('@gob_bluth') - expect(page).not_to have_content('Michael Bluth') - expect(page).not_to have_content('@michael_bluth') + expect(page).not_to have_content('Michael Bluth') + expect(page).not_to have_content('@michael_bluth') - expect(page).not_to have_content('George Oscar Bluth') - expect(page).not_to have_content('@gob_2018') - end + expect(page).not_to have_content('George Oscar Bluth') + expect(page).not_to have_content('@gob_2018') end end + end - context 'when on the group page' do - let(:group) { create(:group) } + context 'when on the group page' do + let(:group) { create(:group) } - before do - group.add_developer(user1) - group.add_developer(user2) - end + before do + group.add_developer(user1) + group.add_developer(user2) + end - it 'finds the user belonging to the group' do - visit group_path(group) + it 'finds the user belonging to the group' do + visit group_path(group) - submit_search('gob') - select_search_scope('Users') + submit_search('gob') + select_search_scope('Users') - page.within('.results') do - expect(page).to have_content('Gob Bluth') - expect(page).to have_content('@gob_bluth') + page.within('.results') do + expect(page).to have_content('Gob Bluth') + expect(page).to have_content('@gob_bluth') - expect(page).not_to have_content('Michael Bluth') - expect(page).not_to have_content('@michael_bluth') + expect(page).not_to have_content('Michael Bluth') + expect(page).not_to have_content('@michael_bluth') - expect(page).not_to have_content('George Oscar Bluth') - expect(page).not_to have_content('@gob_2018') - end + expect(page).not_to have_content('George Oscar Bluth') + expect(page).not_to have_content('@gob_2018') end end end diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb index c7dc3e34bb7..1d8bdc58ce6 100644 --- a/spec/features/search/user_searches_for_wiki_pages_spec.rb +++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb @@ -4,58 +4,53 @@ require 'spec_helper' RSpec.describe 'User searches for wiki pages', :js, :clean_gitlab_redis_rate_limiting, feature_category: :global_search do - using RSpec::Parameterized::TableSyntax - let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) } + let_it_be(:wiki_page) do + create(:wiki_page, wiki: project.wiki, title: 'directory/title', content: 'Some Wiki content') + end - let(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) } - let!(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'directory/title', content: 'Some Wiki content') } - - where(search_page_vertical_nav_enabled: [true, false]) - with_them do - before do - stub_feature_flags(search_page_vertical_nav: search_page_vertical_nav_enabled) - project.add_maintainer(user) - sign_in(user) + before do + project.add_maintainer(user) + sign_in(user) - visit(search_path) - end + visit(search_path) + end - include_examples 'top right search form' - include_examples 'search timeouts', 'wiki_blobs' do - let(:additional_params) { { project_id: project.id } } - end + include_examples 'top right search form' + include_examples 'search timeouts', 'wiki_blobs' do + let(:additional_params) { { project_id: project.id } } + end - shared_examples 'search wiki blobs' do - it 'finds a page' do - find('[data-testid="project-filter"]').click + shared_examples 'search wiki blobs' do + it 'finds a page' do + find('[data-testid="project-filter"]').click - wait_for_requests + wait_for_requests - page.within('[data-testid="project-filter"]') do - click_on(project.name) - end + page.within('[data-testid="project-filter"]') do + click_on(project.name) + end - fill_in('dashboard_search', with: search_term) - find('.gl-search-box-by-click-search-button').click - select_search_scope('Wiki') + fill_in('dashboard_search', with: search_term) + find('.gl-search-box-by-click-search-button').click + select_search_scope('Wiki') - page.within('.results') do - expect(page).to have_link(wiki_page.title, href: project_wiki_path(project, wiki_page.slug)) - end + page.within('.results') do + expect(page).to have_link(wiki_page.title, href: project_wiki_path(project, wiki_page.slug)) end end + end - context 'when searching by content' do - it_behaves_like 'search wiki blobs' do - let(:search_term) { 'content' } - end + context 'when searching by content' do + it_behaves_like 'search wiki blobs' do + let(:search_term) { 'content' } end + end - context 'when searching by title' do - it_behaves_like 'search wiki blobs' do - let(:search_term) { 'title' } - end + context 'when searching by title' do + it_behaves_like 'search wiki blobs' do + let(:search_term) { 'title' } end end end diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb index bc82afc70a3..5d9b451cdf6 100644 --- a/spec/features/signed_commits_spec.rb +++ b/spec/features/signed_commits_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, ref) - expect(page).to have_selector('.gpg-status-box', text: 'Unverified') + expect(page).to have_selector('.gl-badge', text: 'Unverified') # user changes their email which makes the gpg key verified perform_enqueued_jobs do @@ -26,7 +26,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, ref) - expect(page).to have_selector('.gpg-status-box', text: 'Verified') + expect(page).to have_selector('.gl-badge', text: 'Verified') end it 'changes from unverified to verified when the user adds the missing gpg key', :sidekiq_might_not_need_inline do @@ -35,7 +35,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, ref) - expect(page).to have_selector('.gpg-status-box', text: 'Unverified') + expect(page).to have_selector('.gl-badge', text: 'Unverified') # user adds the gpg key which makes the signature valid perform_enqueued_jobs do @@ -44,7 +44,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, ref) - expect(page).to have_selector('.gpg-status-box', text: 'Verified') + expect(page).to have_selector('.gl-badge', text: 'Verified') end context 'shows popover badges', :js do @@ -75,7 +75,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA) wait_for_all_requests - page.find('.gpg-status-box', text: 'Unverified').click + page.find('.gl-badge', text: 'Unverified').click within '.popover' do expect(page).to have_content 'This commit was signed with an unverified signature.' @@ -90,7 +90,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA) wait_for_all_requests - page.find('.gpg-status-box', text: 'Unverified').click + page.find('.gl-badge', text: 'Unverified').click within '.popover' do expect(page).to have_content 'This commit was signed with a verified signature, but the committer email is not associated with the GPG Key.' @@ -104,7 +104,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA) wait_for_all_requests - page.find('.gpg-status-box', text: 'Unverified').click + page.find('.gl-badge', text: 'Unverified').click within '.popover' do expect(page).to have_content "This commit was signed with a different user's verified signature." @@ -118,7 +118,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, GpgHelpers::MULTIPLE_SIGNATURES_SHA) wait_for_all_requests - page.find('.gpg-status-box', text: 'Unverified').click + page.find('.gl-badge', text: 'Unverified').click within '.popover' do expect(page).to have_content "This commit was signed with multiple signatures." @@ -131,7 +131,7 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d visit project_commit_path(project, GpgHelpers::SIGNED_AND_AUTHORED_SHA) wait_for_all_requests - page.find('.gpg-status-box', text: 'Verified').click + page.find('.gl-badge', text: 'Verified').click within '.popover' do expect(page).to have_content 'This commit was signed with a verified signature and the committer email was verified to belong to the same user.' @@ -146,14 +146,14 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d wait_for_all_requests # wait for the signature to get generated - expect(page).to have_selector('.gpg-status-box', text: 'Verified') + expect(page).to have_selector('.gl-badge', text: 'Verified') user_1.destroy! refresh wait_for_all_requests - page.find('.gpg-status-box', text: 'Verified').click + page.find('.gl-badge', text: 'Verified').click within '.popover' do expect(page).to have_content 'This commit was signed with a verified signature and the committer email was verified to belong to the same user.' @@ -170,9 +170,9 @@ RSpec.describe 'GPG signed commits', feature_category: :source_code_management d end it 'displays commit signature' do - expect(page).to have_selector('.gpg-status-box', text: 'Unverified') + expect(page).to have_selector('.gl-badge', text: 'Unverified') - page.find('.gpg-status-box', text: 'Unverified').click + page.find('.gl-badge', text: 'Unverified').click within '.popover' do expect(page).to have_content 'This commit was signed with multiple signatures.' diff --git a/spec/features/snippets/spam_snippets_spec.rb b/spec/features/snippets/spam_snippets_spec.rb index 5d49b36f4fe..0e3f96906de 100644 --- a/spec/features/snippets/spam_snippets_spec.rb +++ b/spec/features/snippets/spam_snippets_spec.rb @@ -13,7 +13,6 @@ RSpec.describe 'snippet editor with spam', skip: "Will be handled in https://git end before do - stub_feature_flags(allow_possible_spam: false) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') Gitlab::CurrentSettings.update!( @@ -74,15 +73,15 @@ RSpec.describe 'snippet editor with spam', skip: "Will be handled in https://git end end - context 'when allow_possible_spam feature flag is false' do - before do - stub_application_setting(recaptcha_enabled: false) - end - + context 'when allow_possible_spam application setting is false' do it_behaves_like 'does not allow creation' end - context 'when allow_possible_spam feature flag is true' do + context 'when allow_possible_spam application setting is true' do + before do + stub_application_setting(allow_possible_spam: true) + end + it_behaves_like 'solve reCAPTCHA' end end @@ -94,7 +93,7 @@ RSpec.describe 'snippet editor with spam', skip: "Will be handled in https://git end end - context 'when allow_possible_spam feature flag is false' do + context 'when allow_possible_spam application setting is false' do before do stub_application_setting(recaptcha_enabled: false) end @@ -102,7 +101,11 @@ RSpec.describe 'snippet editor with spam', skip: "Will be handled in https://git it_behaves_like 'does not allow creation' end - context 'when allow_possible_spam feature flag is true' do + context 'when allow_possible_spam application setting is true' do + before do + stub_application_setting(allow_possible_spam: true) + end + it_behaves_like 'does not allow creation' end end diff --git a/spec/features/snippets_spec.rb b/spec/features/snippets_spec.rb index 2ccdb68e844..dde2f0fcfaa 100644 --- a/spec/features/snippets_spec.rb +++ b/spec/features/snippets_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Snippets', feature_category: :snippets do +RSpec.describe 'Snippets', feature_category: :source_code_management do context 'when the project has snippets' do let(:project) { create(:project, :public) } let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.first_owner, project: project) } diff --git a/spec/features/tags/developer_creates_tag_spec.rb b/spec/features/tags/developer_creates_tag_spec.rb index 111710ba325..6a1db051e87 100644 --- a/spec/features/tags/developer_creates_tag_spec.rb +++ b/spec/features/tags/developer_creates_tag_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'Developer creates tag', :js, feature_category: :source_code_mana page.within(ref_selector) do fill_in _('Search by Git revision'), with: ref_name wait_for_requests - expect(find('.gl-dropdown-contents')).not_to have_content(ref_name) + expect(find('.gl-new-dropdown-inner')).not_to have_content(ref_name) end end @@ -60,9 +60,9 @@ RSpec.describe 'Developer creates tag', :js, feature_category: :source_code_mana page.within ref_row do ref_input = find('[name="ref"]', visible: false) expect(ref_input.value).to eq 'master' - expect(find('.gl-dropdown-button-text')).to have_content 'master' + expect(find('.gl-button-text')).to have_content 'master' find('.ref-selector').click - expect(find('.dropdown-menu')).to have_content 'test' + expect(find('.gl-new-dropdown-inner')).to have_content 'test' end end end diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb index d35726fe125..8a9d2ff42d9 100644 --- a/spec/features/task_lists_spec.rb +++ b/spec/features/task_lists_spec.rb @@ -306,6 +306,12 @@ RSpec.describe 'Task Lists', :js, feature_category: :team_planning do describe 'commented tasks' do let(:commented_tasks_markdown) do <<-EOT.strip_heredoc + <!-- comment text --> + + text + + <!-- - [ ] commented out task --> + <!-- - [ ] a --> @@ -333,6 +339,41 @@ RSpec.describe 'Task Lists', :js, feature_category: :team_planning do expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('li.task-list-item', count: 1) expect(page).to have_selector('ul input[checked]', count: 1) + expect(page).to have_content('1 of 1 checklist item completed') + end + end + + describe 'tasks in code blocks' do + let(:code_tasks_markdown) do + <<-EOT.strip_heredoc + ``` + - [ ] a + ``` + + - [ ] b + EOT + end + + let!(:issue) { create(:issue, description: code_tasks_markdown, author: user, project: project) } + + it 'renders' do + visit_issue(project, issue) + wait_for_requests + + expect(page).to have_selector('ul.task-list', count: 1) + expect(page).to have_selector('li.task-list-item', count: 1) + expect(page).to have_selector('ul input[checked]', count: 0) + + find('.task-list-item-checkbox').click + wait_for_requests + + visit_issue(project, issue) + wait_for_requests + + expect(page).to have_selector('ul.task-list', count: 1) + expect(page).to have_selector('li.task-list-item', count: 1) + expect(page).to have_selector('ul input[checked]', count: 1) + expect(page).to have_content('1 of 1 checklist item completed') end end @@ -370,6 +411,43 @@ RSpec.describe 'Task Lists', :js, feature_category: :team_planning do end end + describe 'summary properly formatted' do + let(:summary_markdown) do + <<-EOT.strip_heredoc + <details open> + <summary>Valid detail/summary with tasklist</summary> + + - [ ] People Ops: do such and such + + </details> + + * [x] Task 1 + EOT + end + + let!(:issue) { create(:issue, description: summary_markdown, author: user, project: project) } + + it 'renders' do + visit_issue(project, issue) + wait_for_requests + + expect(page).to have_selector('ul.task-list', count: 2) + expect(page).to have_selector('li.task-list-item', count: 2) + expect(page).to have_selector('ul input[checked]', count: 1) + + first('.task-list-item-checkbox').click + wait_for_requests + + visit_issue(project, issue) + wait_for_requests + + expect(page).to have_selector('ul.task-list', count: 2) + expect(page).to have_selector('li.task-list-item', count: 2) + expect(page).to have_selector('ul input[checked]', count: 2) + expect(page).to have_content('2 of 2 checklist items completed') + end + end + describe 'markdown starting with new line character' do let(:markdown_starting_with_new_line) do <<-EOT.strip_heredoc diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 23a13994fa4..903211ec250 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -113,11 +113,24 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do end end + it 'hides the token value and reveals when clicking the "reveal values" button', :aggregate_failures do + create(:ci_trigger, owner: user, project: @project, description: trigger_title) + visit project_settings_ci_cd_path(@project) + + expect(page.find('.triggers-list')).to have_content('*' * 47) + + page.find('[data-testid="reveal-hide-values-button"]').click + + expect(page.find('.triggers-list')).to have_content(@project.triggers.first.token) + end + it 'do not show "Edit" or full token for not owned trigger' do # Create trigger with user different from current_user create(:ci_trigger, owner: user2, project: @project, description: trigger_title) visit project_settings_ci_cd_path(@project) + page.find('[data-testid="reveal-hide-values-button"]').click + aggregate_failures 'shows truncated token, no clipboard button and no edit link' do expect(page.find('.triggers-list')).to have_content(@project.triggers.first.token[0..3]) expect(page.find('.triggers-list')).not_to have_selector('[data-testid="clipboard-btn"]') @@ -130,6 +143,8 @@ RSpec.describe 'Triggers', :js, feature_category: :continuous_integration do create(:ci_trigger, owner: user, project: @project, description: trigger_title) visit project_settings_ci_cd_path(@project) + page.find('[data-testid="reveal-hide-values-button"]').click + aggregate_failures 'shows full token, clipboard button and edit link' do expect(page.find('.triggers-list')).to have_content @project.triggers.first.token expect(page.find('.triggers-list')).to have_selector('[data-testid="clipboard-btn"]') diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb index bcab35335cb..23fa6261bd5 100644 --- a/spec/features/unsubscribe_links_spec.rb +++ b/spec/features/unsubscribe_links_spec.rb @@ -10,7 +10,7 @@ RSpec.describe 'Unsubscribe links', :sidekiq_inline, feature_category: :not_owne let_it_be(:recipient) { create(:user) } let(:params) { { title: 'A bug!', description: 'Fix it!', assignee_ids: [recipient.id] } } - let(:issue) { Issues::CreateService.new(project: project, current_user: author, params: params, spam_params: nil).execute[:issue] } + let(:issue) { Issues::CreateService.new(container: project, current_user: author, params: params, spam_params: nil).execute[:issue] } let(:mail) { ActionMailer::Base.deliveries.last } let(:body) { Capybara::Node::Simple.new(mail.default_part_body.to_s) } diff --git a/spec/features/uploads/user_uploads_avatar_to_group_spec.rb b/spec/features/uploads/user_uploads_avatar_to_group_spec.rb index 78cede77fea..02e98905662 100644 --- a/spec/features/uploads/user_uploads_avatar_to_group_spec.rb +++ b/spec/features/uploads/user_uploads_avatar_to_group_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User uploads avatar to group', feature_category: :users do +RSpec.describe 'User uploads avatar to group', feature_category: :user_profile do it 'they see the new avatar' do user = create(:user) group = create(:group) diff --git a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb index fb62b5eadc5..f1023f17d3e 100644 --- a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb +++ b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User uploads avatar to profile', feature_category: :users do +RSpec.describe 'User uploads avatar to profile', feature_category: :user_profile do let!(:user) { create(:user) } let(:avatar_file_path) { Rails.root.join('spec', 'fixtures', 'dk.png') } diff --git a/spec/features/users/add_email_to_existing_account_spec.rb b/spec/features/users/add_email_to_existing_account_spec.rb index 8c4e68c454f..ea39e5c5a49 100644 --- a/spec/features/users/add_email_to_existing_account_spec.rb +++ b/spec/features/users/add_email_to_existing_account_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'AdditionalEmailToExistingAccount', feature_category: :users do +RSpec.describe 'AdditionalEmailToExistingAccount', feature_category: :user_profile do describe 'add secondary email associated with account' do let_it_be(:user) { create(:user) } let_it_be(:email) { create(:email, user: user) } diff --git a/spec/features/users/email_verification_on_login_spec.rb b/spec/features/users/email_verification_on_login_spec.rb index de52f0b517e..481ff52b800 100644 --- a/spec/features/users/email_verification_on_login_spec.rb +++ b/spec/features/users/email_verification_on_login_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting, before do stub_feature_flags(require_email_verification: require_email_verification_enabled) + stub_feature_flags(skip_require_email_verification: false) end shared_examples 'email verification required' do diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb index 489e7d61ff9..ff903358931 100644 --- a/spec/features/users/overview_spec.rb +++ b/spec/features/users/overview_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'Overview tab on a user profile', :js, feature_category: :users do +RSpec.describe 'Overview tab on a user profile', :js, feature_category: :user_profile do let(:user) { create(:user) } let(:contributed_project) { create(:project, :public, :repository) } @@ -18,6 +18,7 @@ RSpec.describe 'Overview tab on a user profile', :js, feature_category: :users d end before do + stub_feature_flags(profile_tabs_vue: false) sign_in user end diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb index a2604cd298a..bc37c9941ce 100644 --- a/spec/features/users/rss_spec.rb +++ b/spec/features/users/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User RSS', feature_category: :users do +RSpec.describe 'User RSS', feature_category: :user_profile do let(:user) { create(:user) } let(:path) { user_path(create(:user)) } diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index 318dd688fa4..88b2d918976 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'User page', feature_category: :users do +RSpec.describe 'User page', feature_category: :user_profile do include ExternalAuthorizationServiceHelpers let_it_be(:user) { create(:user, bio: '<b>Lorem</b> <i>ipsum</i> dolor sit <a href="https://example.com">amet</a>') } @@ -16,10 +16,31 @@ RSpec.describe 'User page', feature_category: :users do end context 'with public profile' do - it 'shows all the tabs' do + context 'with `profile_tabs_vue` feature flag disabled' do + before do + stub_feature_flags(profile_tabs_vue: false) + end + + it 'shows all the tabs' do + subject + + page.within '.nav-links' do + expect(page).to have_link('Overview') + expect(page).to have_link('Activity') + expect(page).to have_link('Groups') + expect(page).to have_link('Contributed projects') + expect(page).to have_link('Personal projects') + expect(page).to have_link('Snippets') + expect(page).to have_link('Followers') + expect(page).to have_link('Following') + end + end + end + + it 'shows all the tabs', :js do subject - page.within '.nav-links' do + page.within '[role="tablist"]' do expect(page).to have_link('Overview') expect(page).to have_link('Activity') expect(page).to have_link('Groups') @@ -189,11 +210,33 @@ RSpec.describe 'User page', feature_category: :users do expect(page).to have_content("This user has a private profile") end - it 'shows own tabs' do + context 'with `profile_tabs_vue` feature flag disabled' do + before do + stub_feature_flags(profile_tabs_vue: false) + end + + it 'shows own tabs' do + sign_in(user) + subject + + page.within '.nav-links' do + expect(page).to have_link('Overview') + expect(page).to have_link('Activity') + expect(page).to have_link('Groups') + expect(page).to have_link('Contributed projects') + expect(page).to have_link('Personal projects') + expect(page).to have_link('Snippets') + expect(page).to have_link('Followers') + expect(page).to have_link('Following') + end + end + end + + it 'shows own tabs', :js do sign_in(user) subject - page.within '.nav-links' do + page.within '[role="tablist"]' do expect(page).to have_link('Overview') expect(page).to have_link('Activity') expect(page).to have_link('Groups') @@ -341,6 +384,7 @@ RSpec.describe 'User page', feature_category: :users do page.within '.navbar-gitlab' do expect(page).to have_link('Sign in') + expect(page).not_to have_link('Register') end end end @@ -352,12 +396,17 @@ RSpec.describe 'User page', feature_category: :users do subject page.within '.navbar-gitlab' do - expect(page).to have_link('Sign in / Register') + expect(page).to have_link(_('Sign in'), exact: true) + expect(page).to have_link(_('Register'), exact: true) end end end context 'most recent activity' do + before do + stub_feature_flags(profile_tabs_vue: false) + end + it 'shows the most recent activity' do subject @@ -388,6 +437,10 @@ RSpec.describe 'User page', feature_category: :users do context 'with a bot user' do let_it_be(:user) { create(:user, user_type: :security_bot) } + before do + stub_feature_flags(profile_tabs_vue: false) + end + describe 'feature flag enabled' do before do stub_feature_flags(security_auto_fix: true) diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb index 1057ae48c7d..11ff318c346 100644 --- a/spec/features/users/signup_spec.rb +++ b/spec/features/users/signup_spec.rb @@ -44,7 +44,7 @@ RSpec.shared_examples 'Signup name validation' do |field, max_length, label| end end -RSpec.describe 'Signup', feature_category: :users do +RSpec.describe 'Signup', feature_category: :user_profile do include TermsHelper let(:new_user) { build_stubbed(:user) } diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb index 20fc2981418..2876351be37 100644 --- a/spec/features/users/snippets_spec.rb +++ b/spec/features/users/snippets_spec.rb @@ -2,10 +2,14 @@ require 'spec_helper' -RSpec.describe 'Snippets tab on a user profile', :js, feature_category: :snippets do +RSpec.describe 'Snippets tab on a user profile', :js, feature_category: :source_code_management do context 'when the user has snippets' do let(:user) { create(:user) } + before do + stub_feature_flags(profile_tabs_vue: false) + end + context 'pagination' do let!(:snippets) { create_list(:snippet, 2, :public, author: user) } diff --git a/spec/features/users/terms_spec.rb b/spec/features/users/terms_spec.rb index 7d2137b81b8..5c61843e558 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', :js, feature_category: :users do +RSpec.describe 'Users > Terms', :js, feature_category: :user_profile do include TermsHelper let!(:term) { create(:term, terms: 'By accepting, you promise to be nice!') } diff --git a/spec/features/users/user_browses_projects_on_user_page_spec.rb b/spec/features/users/user_browses_projects_on_user_page_spec.rb index 841b324fba4..52ca2397582 100644 --- a/spec/features/users/user_browses_projects_on_user_page_spec.rb +++ b/spec/features/users/user_browses_projects_on_user_page_spec.rb @@ -28,6 +28,10 @@ RSpec.describe 'Users > User browses projects on user page', :js, feature_catego end end + before do + stub_feature_flags(profile_tabs_vue: false) + end + it 'hides loading spinner after load', :js do visit user_path(user) click_nav_link('Personal projects') @@ -125,7 +129,7 @@ RSpec.describe 'Users > User browses projects on user page', :js, feature_catego end before do - Issues::CreateService.new(project: contributed_project, current_user: user, params: { title: 'Bug in old browser' }, spam_params: nil).execute + Issues::CreateService.new(container: contributed_project, current_user: user, params: { title: 'Bug in old browser' }, spam_params: nil).execute event = create(:push_event, project: contributed_project, author: user) create(:push_event_payload, event: event, commit_count: 3) end diff --git a/spec/features/users/zuora_csp_spec.rb b/spec/features/users/zuora_csp_spec.rb deleted file mode 100644 index b07c923fa54..00000000000 --- a/spec/features/users/zuora_csp_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Zuora content security policy', feature_category: :purchase do - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:pipeline) { create(:ci_pipeline, project: project) } - - before do - project.add_developer(user) - sign_in(user) - end - - it 'has proper Content Security Policy headers' do - visit pipeline_path(pipeline) - - expect(response_headers['Content-Security-Policy']).to include('https://*.zuora.com') - end -end diff --git a/spec/features/webauthn_spec.rb b/spec/features/webauthn_spec.rb index e2f16f4a017..859793d1353 100644 --- a/spec/features/webauthn_spec.rb +++ b/spec/features/webauthn_spec.rb @@ -10,57 +10,62 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor WebAuthn.configuration.origin = app_id end - it_behaves_like 'hardware device for 2fa', 'WebAuthn' - - describe 'registration' do - let(:user) { create(:user) } - + context 'when the webauth_without_totp feature flag is disabled' do before do - gitlab_sign_in(user) - user.update_attribute(:otp_required_for_login, true) + stub_feature_flags(webauthn_without_totp: false) end - describe 'when 2FA via OTP is enabled' do - it 'allows registering more than one device' do - visit profile_account_path + it_behaves_like 'hardware device for 2fa', 'WebAuthn' + + describe 'registration' do + let(:user) { create(:user) } + + before do + gitlab_sign_in(user) + user.update_attribute(:otp_required_for_login, true) + end + + describe 'when 2FA via OTP is enabled' do + it 'allows registering more than one device' do + visit profile_account_path - # First device + # First device + manage_two_factor_authentication + first_device = register_webauthn_device + expect(page).to have_content('Your WebAuthn device was registered') + + # Second device + second_device = register_webauthn_device(name: 'My other device') + expect(page).to have_content('Your WebAuthn device was registered') + + expect(page).to have_content(first_device.name) + expect(page).to have_content(second_device.name) + expect(WebauthnRegistration.count).to eq(2) + end + end + + it 'allows the same device to be registered for multiple users' do + # First user + visit profile_account_path manage_two_factor_authentication - first_device = register_webauthn_device + webauthn_device = register_webauthn_device expect(page).to have_content('Your WebAuthn device was registered') + gitlab_sign_out - # Second device - second_device = register_webauthn_device(name: 'My other device') + # Second user + user = gitlab_sign_in(:user) + user.update_attribute(:otp_required_for_login, true) + visit profile_account_path + manage_two_factor_authentication + register_webauthn_device(webauthn_device, name: 'My other device') expect(page).to have_content('Your WebAuthn device was registered') - expect(page).to have_content(first_device.name) - expect(page).to have_content(second_device.name) expect(WebauthnRegistration.count).to eq(2) end - end - - it 'allows the same device to be registered for multiple users' do - # First user - visit profile_account_path - manage_two_factor_authentication - webauthn_device = register_webauthn_device - expect(page).to have_content('Your WebAuthn device was registered') - gitlab_sign_out - - # Second user - user = gitlab_sign_in(:user) - user.update_attribute(:otp_required_for_login, true) - visit profile_account_path - manage_two_factor_authentication - register_webauthn_device(webauthn_device, name: 'My other device') - expect(page).to have_content('Your WebAuthn device was registered') - - expect(WebauthnRegistration.count).to eq(2) - end - context 'when there are form errors' do - let(:mock_register_js) do - <<~JS + context 'when there are form errors' do + let(:mock_register_js) do + <<~JS const mockResponse = { type: 'public-key', id: '', @@ -72,135 +77,136 @@ RSpec.describe 'Using WebAuthn Devices for Authentication', :js, feature_categor getClientExtensionResults: () => {}, }; navigator.credentials.create = function(_) {return Promise.resolve(mockResponse);} - JS - end + JS + end - it "doesn't register the device if there are errors" do - visit profile_account_path - manage_two_factor_authentication + it "doesn't register the device if there are errors" do + visit profile_account_path + manage_two_factor_authentication - # Have the "webauthn device" respond with bad data - page.execute_script(mock_register_js) - click_on 'Set up new device' - expect(page).to have_content('Your device was successfully set up') - click_on 'Register device' + # Have the "webauthn device" respond with bad data + page.execute_script(mock_register_js) + click_on 'Set up new device' + expect(page).to have_content('Your device was successfully set up') + click_on 'Register device' - expect(WebauthnRegistration.count).to eq(0) - expect(page).to have_content('The form contains the following error') - expect(page).to have_content('did not send a valid JSON response') - end + expect(WebauthnRegistration.count).to eq(0) + expect(page).to have_content('The form contains the following error') + expect(page).to have_content('did not send a valid JSON response') + end - it 'allows retrying registration' do - visit profile_account_path - manage_two_factor_authentication + it 'allows retrying registration' do + visit profile_account_path + manage_two_factor_authentication - # Failed registration - page.execute_script(mock_register_js) - click_on 'Set up new device' - expect(page).to have_content('Your device was successfully set up') - click_on 'Register device' - expect(page).to have_content('The form contains the following error') + # Failed registration + page.execute_script(mock_register_js) + click_on 'Set up new device' + expect(page).to have_content('Your device was successfully set up') + click_on 'Register device' + expect(page).to have_content('The form contains the following error') - # Successful registration - register_webauthn_device + # Successful registration + register_webauthn_device - expect(page).to have_content('Your WebAuthn device was registered') - expect(WebauthnRegistration.count).to eq(1) + expect(page).to have_content('Your WebAuthn device was registered') + expect(WebauthnRegistration.count).to eq(1) + end end end - end - describe 'authentication' do - let(:otp_required_for_login) { true } - let(:user) { create(:user, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } - let!(:webauthn_device) do - add_webauthn_device(app_id, user) - end + describe 'authentication' do + let(:otp_required_for_login) { true } + let(:user) { create(:user, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } + let!(:webauthn_device) do + add_webauthn_device(app_id, user) + end - describe 'when 2FA via OTP is disabled' do - let(:otp_required_for_login) { false } + describe 'when 2FA via OTP is disabled' do + let(:otp_required_for_login) { false } - it 'allows logging in with the WebAuthn device' do - gitlab_sign_in(user) + it 'allows logging in with the WebAuthn device' do + gitlab_sign_in(user) - webauthn_device.respond_to_webauthn_authentication + webauthn_device.respond_to_webauthn_authentication - expect(page).to have_css('.sign-out-link', visible: false) + expect(page).to have_css('.sign-out-link', visible: false) + end end - end - describe 'when 2FA via OTP is enabled' do - it 'allows logging in with the WebAuthn device' do - gitlab_sign_in(user) + describe 'when 2FA via OTP is enabled' do + it 'allows logging in with the WebAuthn device' do + gitlab_sign_in(user) - webauthn_device.respond_to_webauthn_authentication + webauthn_device.respond_to_webauthn_authentication - expect(page).to have_css('.sign-out-link', visible: false) + expect(page).to have_css('.sign-out-link', visible: false) + end end - end - describe 'when a given WebAuthn device has already been registered by another user' do - describe 'but not the current user' do - let(:other_user) { create(:user, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } + describe 'when a given WebAuthn device has already been registered by another user' do + describe 'but not the current user' do + let(:other_user) { create(:user, webauthn_xid: WebAuthn.generate_user_id, otp_required_for_login: otp_required_for_login) } - it 'does not allow logging in with that particular device' do - # Register other user with a different WebAuthn device - other_device = add_webauthn_device(app_id, other_user) + it 'does not allow logging in with that particular device' do + # Register other user with a different WebAuthn device + other_device = add_webauthn_device(app_id, other_user) - # Try authenticating user with the old WebAuthn device - gitlab_sign_in(user) - other_device.respond_to_webauthn_authentication - expect(page).to have_content('Authentication via WebAuthn device failed') + # Try authenticating user with the old WebAuthn device + gitlab_sign_in(user) + other_device.respond_to_webauthn_authentication + expect(page).to have_content('Authentication via WebAuthn device failed') + end end - end - - describe "and also the current user" do - # TODO Uncomment once WebAuthn::FakeClient supports passing credential options - # (especially allow_credentials, as this is needed to specify which credential the - # fake client should use. Currently, the first credential is always used). - # There is an issue open for this: https://github.com/cedarcode/webauthn-ruby/issues/259 - it "allows logging in with that particular device" do - pending("support for passing credential options in FakeClient") - # Register current user with the same WebAuthn device - current_user = gitlab_sign_in(:user) - visit profile_account_path - manage_two_factor_authentication - register_webauthn_device(webauthn_device) - gitlab_sign_out - # Try authenticating user with the same WebAuthn device - gitlab_sign_in(current_user) - webauthn_device.respond_to_webauthn_authentication - - expect(page).to have_css('.sign-out-link', visible: false) + describe "and also the current user" do + # TODO Uncomment once WebAuthn::FakeClient supports passing credential options + # (especially allow_credentials, as this is needed to specify which credential the + # fake client should use. Currently, the first credential is always used). + # There is an issue open for this: https://github.com/cedarcode/webauthn-ruby/issues/259 + it "allows logging in with that particular device" do + pending("support for passing credential options in FakeClient") + # Register current user with the same WebAuthn device + current_user = gitlab_sign_in(:user) + visit profile_account_path + manage_two_factor_authentication + register_webauthn_device(webauthn_device) + gitlab_sign_out + + # Try authenticating user with the same WebAuthn device + gitlab_sign_in(current_user) + webauthn_device.respond_to_webauthn_authentication + + expect(page).to have_css('.sign-out-link', visible: false) + end end end - end - describe 'when a given WebAuthn device has not been registered' do - it 'does not allow logging in with that particular device' do - unregistered_device = FakeWebauthnDevice.new(page, 'My device') - gitlab_sign_in(user) - unregistered_device.respond_to_webauthn_authentication + describe 'when a given WebAuthn device has not been registered' do + it 'does not allow logging in with that particular device' do + unregistered_device = FakeWebauthnDevice.new(page, 'My device') + gitlab_sign_in(user) + unregistered_device.respond_to_webauthn_authentication - expect(page).to have_content('Authentication via WebAuthn device failed') + expect(page).to have_content('Authentication via WebAuthn device failed') + end end - end - describe 'when more than one device has been registered by the same user' do - it 'allows logging in with either device' do - first_device = add_webauthn_device(app_id, user) - second_device = add_webauthn_device(app_id, user) + describe 'when more than one device has been registered by the same user' do + it 'allows logging in with either device' do + first_device = add_webauthn_device(app_id, user) + second_device = add_webauthn_device(app_id, user) - # Authenticate as both devices - [first_device, second_device].each do |device| - gitlab_sign_in(user) - # register_webauthn_device(device) - device.respond_to_webauthn_authentication + # Authenticate as both devices + [first_device, second_device].each do |device| + gitlab_sign_in(user) + # register_webauthn_device(device) + device.respond_to_webauthn_authentication - expect(page).to have_css('.sign-out-link', visible: false) + expect(page).to have_css('.sign-out-link', visible: false) - gitlab_sign_out + gitlab_sign_out + end end end end diff --git a/spec/features/work_items/work_item_children_spec.rb b/spec/features/work_items/work_item_children_spec.rb index 4403ca60d11..f41fb86d13c 100644 --- a/spec/features/work_items/work_item_children_spec.rb +++ b/spec/features/work_items/work_item_children_spec.rb @@ -31,15 +31,15 @@ RSpec.describe 'Work item children', :js, feature_category: :team_planning do it 'toggles widget body', :aggregate_failures do page.within('[data-testid="work-item-links"]') do - expect(page).to have_selector('[data-testid="links-body"]') + expect(page).to have_selector('[data-testid="widget-body"]') - click_button 'Collapse tasks' + click_button 'Collapse' - expect(page).not_to have_selector('[data-testid="links-body"]') + expect(page).not_to have_selector('[data-testid="widget-body"]') - click_button 'Expand tasks' + click_button 'Expand' - expect(page).to have_selector('[data-testid="links-body"]') + expect(page).to have_selector('[data-testid="widget-body"]') end end diff --git a/spec/features/work_items/work_item_spec.rb b/spec/features/work_items/work_item_spec.rb index 577ec060020..3c71a27ff82 100644 --- a/spec/features/work_items/work_item_spec.rb +++ b/spec/features/work_items/work_item_spec.rb @@ -5,56 +5,33 @@ require 'spec_helper' RSpec.describe 'Work item', :js, feature_category: :team_planning do let_it_be(:project) { create(:project, :public) } let_it_be(:user) { create(:user) } - let_it_be(:other_user) { create(:user) } let_it_be(:work_item) { create(:work_item, project: project) } context 'for signed in user' do before do project.add_developer(user) - project.add_developer(other_user) sign_in(user) visit project_work_items_path(project, work_items_path: work_item.id) end - context 'in work item description' do - it 'shows GFM autocomplete', :aggregate_failures do - click_button "Edit description" - - find('[aria-label="Description"]').send_keys("@#{user.username}") - - wait_for_requests - - page.within('.atwho-container') do - expect(page).to have_text(user.name) - end - end - - it 'shows conflict message when description changes', :aggregate_failures do - click_button "Edit description" - scroll_to(find('[aria-label="Description"]')) - - # without this for some reason the test fails when running locally - sleep 1 - - ::WorkItems::UpdateService.new( - project: work_item.project, - current_user: other_user, - params: { description: "oh no!" } - ).execute(work_item) - - work_item.reload - - find('[aria-label="Description"]').send_keys("oh yeah!") + it_behaves_like 'work items status' + it_behaves_like 'work items assignees' + it_behaves_like 'work items labels' + it_behaves_like 'work items comments' + it_behaves_like 'work items description' + end - warning = 'Someone edited the description at the same time you did.' - expect(page.find('[data-testid="work-item-description-conflicts"]')).to have_text(warning) + context 'for signed in owner' do + before do + project.add_owner(user) - click_button "Save and overwrite" + sign_in(user) - expect(page.find('[data-testid="work-item-description"]')).to have_text("oh yeah!") - end + visit project_work_items_path(project, work_items_path: work_item.id) end + + it_behaves_like 'work items invite members' end end |